diff options
-rw-r--r-- | src/components/script/dom/element.rs | 12 | ||||
-rw-r--r-- | src/components/style/selector_matching.rs | 29 | ||||
-rw-r--r-- | src/components/style/selectors.rs | 10 | ||||
-rw-r--r-- | src/components/util/tree.rs | 1 |
4 files changed, 50 insertions, 2 deletions
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 24644e514af..1901278b40d 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -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 { diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index a3fddb8c13d..7e93387f83b 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -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 { diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs index 1589625f61a..9fee4f8fbc9 100644 --- a/src/components/style/selectors.rs +++ b/src/components/style/selectors.rs @@ -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), diff --git a/src/components/util/tree.rs b/src/components/util/tree.rs index f2a80342655..4a156cfa6ca 100644 --- a/src/components/util/tree.rs +++ b/src/components/util/tree.rs @@ -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>; } |