mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
auto merge of #1661 : SimonSapin/servo/attr-selectors, r=jdm
… instead of None meaning "any namespace" (where it could be the null namespace.)
This commit is contained in:
commit
7d740f8f8b
3 changed files with 29 additions and 18 deletions
|
@ -27,7 +27,8 @@ use servo_util::namespace;
|
||||||
use servo_util::namespace::Namespace;
|
use servo_util::namespace::Namespace;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cell::{Ref, RefMut};
|
use std::cell::{Ref, RefMut};
|
||||||
use style::{PropertyDeclarationBlock, TElement, TNode, AttrSelector};
|
use style::{PropertyDeclarationBlock, TElement, TNode,
|
||||||
|
AttrSelector, SpecificNamespace, AnyNamespace};
|
||||||
|
|
||||||
use layout::util::LayoutDataWrapper;
|
use layout::util::LayoutDataWrapper;
|
||||||
|
|
||||||
|
@ -239,14 +240,14 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
|
||||||
attr.name.as_slice()
|
attr.name.as_slice()
|
||||||
};
|
};
|
||||||
match attr.namespace {
|
match attr.namespace {
|
||||||
Some(ref ns) => {
|
SpecificNamespace(ref ns) => {
|
||||||
match element.get_attr(ns, name) {
|
match element.get_attr(ns, name) {
|
||||||
Some(value) => test(value),
|
Some(value) => test(value),
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// FIXME: support `*|attr`, attribute selectors in any namespace
|
// FIXME: https://github.com/mozilla/servo/issues/1558
|
||||||
None => return false,
|
AnyNamespace => return false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,8 +93,13 @@ pub enum SimpleSelector {
|
||||||
pub struct AttrSelector {
|
pub struct AttrSelector {
|
||||||
name: ~str,
|
name: ~str,
|
||||||
lower_name: ~str,
|
lower_name: ~str,
|
||||||
/// None means "any namespace", `*|attr`
|
namespace: NamespaceConstraint,
|
||||||
namespace: Option<Namespace>,
|
}
|
||||||
|
|
||||||
|
#[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) => {
|
QualifiedName(namespace, local_name) => {
|
||||||
let mut simple_selectors = ~[];
|
let mut simple_selectors = ~[];
|
||||||
match namespace {
|
match namespace {
|
||||||
Some(ns) => simple_selectors.push(NamespaceSelector(ns)),
|
SpecificNamespace(ns) => simple_selectors.push(NamespaceSelector(ns)),
|
||||||
None => (),
|
AnyNamespace => (),
|
||||||
}
|
}
|
||||||
match local_name {
|
match local_name {
|
||||||
Some(name) => simple_selectors.push(LocalNameSelector(name)),
|
Some(name) => simple_selectors.push(LocalNameSelector(name)),
|
||||||
|
@ -363,7 +368,7 @@ enum QualifiedNameParseResult {
|
||||||
InvalidQualifiedName,
|
InvalidQualifiedName,
|
||||||
NotAQualifiedName,
|
NotAQualifiedName,
|
||||||
// Namespace URL, local name. None means '*'
|
// Namespace URL, local name. None means '*'
|
||||||
QualifiedName(Option<Namespace>, Option<~str>)
|
QualifiedName(NamespaceConstraint, Option<~str>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &NamespaceMap)
|
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]
|
#[inline]
|
||||||
fn default_namespace(namespaces: &NamespaceMap, local_name: Option<~str>)
|
fn default_namespace(namespaces: &NamespaceMap, local_name: Option<~str>)
|
||||||
-> QualifiedNameParseResult {
|
-> 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]
|
#[inline]
|
||||||
fn explicit_namespace(iter: &mut Iter, in_attr_selector: bool, namespace: Option<Namespace>)
|
fn explicit_namespace(iter: &mut Iter, in_attr_selector: bool, namespace: NamespaceConstraint)
|
||||||
-> QualifiedNameParseResult {
|
-> QualifiedNameParseResult {
|
||||||
assert!(iter.next() == Some(Delim('|')),
|
assert!(iter.next() == Some(Delim('|')),
|
||||||
"Implementation error, this should not happen.");
|
"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
|
None => return InvalidQualifiedName, // Undeclared namespace prefix
|
||||||
Some(ref ns) => (*ns).clone(),
|
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)),
|
_ => default_namespace(namespaces, Some(value)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(&Delim('*')) => {
|
Some(&Delim('*')) => {
|
||||||
iter.next(); // Consume '*'
|
iter.next(); // Consume '*'
|
||||||
match iter.peek() {
|
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) }
|
if !in_attr_selector { default_namespace(namespaces, None) }
|
||||||
else { InvalidQualifiedName }
|
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,
|
_ => NotAQualifiedName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -643,7 +653,7 @@ mod tests {
|
||||||
simple_selectors: ~[AttrExists(AttrSelector {
|
simple_selectors: ~[AttrExists(AttrSelector {
|
||||||
name: ~"Foo",
|
name: ~"Foo",
|
||||||
lower_name: ~"foo",
|
lower_name: ~"foo",
|
||||||
namespace: Some(namespace::Null),
|
namespace: SpecificNamespace(namespace::Null),
|
||||||
})],
|
})],
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
|
@ -657,7 +667,7 @@ mod tests {
|
||||||
simple_selectors: ~[AttrExists(AttrSelector {
|
simple_selectors: ~[AttrExists(AttrSelector {
|
||||||
name: ~"Foo",
|
name: ~"Foo",
|
||||||
lower_name: ~"foo",
|
lower_name: ~"foo",
|
||||||
namespace: Some(namespace::Null),
|
namespace: SpecificNamespace(namespace::Null),
|
||||||
})],
|
})],
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub use properties::{cascade, PropertyDeclaration, ComputedValues, computed_valu
|
||||||
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
|
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
|
||||||
pub use errors::with_errors_silenced;
|
pub use errors::with_errors_silenced;
|
||||||
pub use node::{TElement, TNode};
|
pub use node::{TElement, TNode};
|
||||||
pub use selectors::{PseudoElement, Before, After, AttrSelector};
|
pub use selectors::{PseudoElement, Before, After, AttrSelector, SpecificNamespace, AnyNamespace};
|
||||||
|
|
||||||
mod stylesheets;
|
mod stylesheets;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue