Add :any-link (Level 4), :link and :visited selectors.

All links are considered "unvisited" for now.
This commit is contained in:
Simon Sapin 2013-11-07 15:05:15 +00:00
parent 651b2f072b
commit 74dfc3b66a
4 changed files with 50 additions and 2 deletions

View file

@ -130,6 +130,18 @@ impl ElementLike for Element {
return value; return value;
} }
fn get_link<'a>(&'a self) -> Option<&'a str> {
// FIXME: This is HTML only.
match self.node.type_id {
// http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#selector-link
ElementNodeTypeId(HTMLAnchorElementTypeId) |
ElementNodeTypeId(HTMLAreaElementTypeId) |
ElementNodeTypeId(HTMLLinkElementTypeId)
=> self.get_attr("href"),
_ => None,
}
}
} }
impl<'self> Element { impl<'self> Element {

View file

@ -241,6 +241,28 @@ fn matches_simple_selector<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: Ele
attr_value.ends_with(value.as_slice()) attr_value.ends_with(value.as_slice())
}, },
AnyLink => {
do element.with_imm_element_like |element: &E| {
element.get_link().is_some()
}
}
Link => {
do element.with_imm_element_like |element: &E| {
match element.get_link() {
Some(url) => !url_is_visited(url),
None => false,
}
}
}
Visited => {
do element.with_imm_element_like |element: &E| {
match element.get_link() {
Some(url) => url_is_visited(url),
None => false,
}
}
}
FirstChild => matches_first_child(element), FirstChild => matches_first_child(element),
Negation(ref negated) => { Negation(ref negated) => {
@ -249,6 +271,13 @@ fn matches_simple_selector<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: Ele
} }
} }
fn url_is_visited(_url: &str) -> bool {
// FIXME: implement this.
// This function will probably need to take a "session"
// or something containing browsing history as an additional parameter.
false
}
#[inline] #[inline]
fn matches_first_child<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>( fn matches_first_child<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
element: &T) -> bool { element: &T) -> bool {

View file

@ -58,12 +58,15 @@ pub enum SimpleSelector {
AttrSuffixMatch(AttrSelector, ~str), // [foo$=bar] AttrSuffixMatch(AttrSelector, ~str), // [foo$=bar]
// Pseudo-classes // Pseudo-classes
Negation(~[SimpleSelector]),
AnyLink,
Link,
Visited,
FirstChild, FirstChild,
// Empty, // Empty,
// Root, // Root,
// Lang(~str), // Lang(~str),
// NthChild(i32, i32), // NthChild(i32, i32),
Negation(~[SimpleSelector]),
// ... // ...
} }
@ -181,7 +184,7 @@ fn compute_specificity(mut selector: &CompoundSelector,
&ClassSelector(*) &ClassSelector(*)
| &AttrExists(*) | &AttrEqual(*) | &AttrIncludes(*) | &AttrDashMatch(*) | &AttrExists(*) | &AttrEqual(*) | &AttrIncludes(*) | &AttrDashMatch(*)
| &AttrPrefixMatch(*) | &AttrSubstringMatch(*) | &AttrSuffixMatch(*) | &AttrPrefixMatch(*) | &AttrSubstringMatch(*) | &AttrSuffixMatch(*)
| &FirstChild | &AnyLink | &Link | &Visited | &FirstChild
// | &Empty | &Root | &Lang(*) | &NthChild(*) // | &Empty | &Root | &Lang(*) | &NthChild(*)
=> specificity.class_like_selectors += 1, => specificity.class_like_selectors += 1,
&NamespaceSelector(*) => (), &NamespaceSelector(*) => (),
@ -420,6 +423,9 @@ fn parse_attribute_selector(content: ~[ComponentValue], namespaces: &NamespaceMa
fn parse_simple_pseudo_class(name: &str) -> Option<SimpleSelector> { fn parse_simple_pseudo_class(name: &str) -> Option<SimpleSelector> {
match name.to_ascii_lower().as_slice() { match name.to_ascii_lower().as_slice() {
"any-link" => Some(AnyLink),
"link" => Some(Link),
"visited" => Some(Visited),
"first-child" => Some(FirstChild), "first-child" => Some(FirstChild),
// "root" => Some(Root), // "root" => Some(Root),
// "empty" => Some(Empty), // "empty" => Some(Empty),

View file

@ -349,4 +349,5 @@ pub trait TreeNode<Ref: TreeNodeRef<Self>> {
pub trait ElementLike { pub trait ElementLike {
fn get_local_name<'a>(&'a self) -> &'a str; fn get_local_name<'a>(&'a self) -> &'a str;
fn get_attr<'a>(&'a self, name: &str) -> Option<&'a str>; fn get_attr<'a>(&'a self, name: &str) -> Option<&'a str>;
fn get_link<'a>(&'a self) -> Option<&'a str>;
} }