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;
}
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 {

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())
},
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),
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]
fn matches_first_child<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike>(
element: &T) -> bool {

View file

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

View file

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