mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Add an AllLinksVisitedAndUnvisited for invalidation.
Otherwise, tests like the following fail, given we always match as unvisited, and we'd never mark the link as needing invalidation. <!doctype html> <style> a { color: red !important; } .foo :visited { color: green !important; } </style> <div> <a href="https://google.es">visit me</a> <button onclick="this.parentNode.className = 'foo'">Then click me</button> </div> Bug: 1368240 MozReview-Commit-ID: LDv6S28c4ju
This commit is contained in:
parent
fdf9093466
commit
4434509088
6 changed files with 42 additions and 2 deletions
|
@ -48,6 +48,12 @@ pub enum MatchingMode {
|
|||
pub enum VisitedHandlingMode {
|
||||
/// All links are matched as if they are unvisted.
|
||||
AllLinksUnvisited,
|
||||
/// All links are matched as if they are visited and unvisited (both :link
|
||||
/// and :visited match).
|
||||
///
|
||||
/// This is intended to be used from invalidation code, to be conservative
|
||||
/// about whether we need to restyle a link.
|
||||
AllLinksVisitedAndUnvisited,
|
||||
/// A element's "relevant link" is the element being matched if it is a link
|
||||
/// or the nearest ancestor link. The relevant link is matched as though it
|
||||
/// is visited, and all other links are matched as if they are unvisited.
|
||||
|
|
|
@ -253,6 +253,10 @@ impl RelevantLinkStatus {
|
|||
return false
|
||||
}
|
||||
|
||||
if context.visited_handling == VisitedHandlingMode::AllLinksVisitedAndUnvisited {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Non-relevant links are always unvisited.
|
||||
if *self != RelevantLinkStatus::Found {
|
||||
return false
|
||||
|
@ -274,6 +278,10 @@ impl RelevantLinkStatus {
|
|||
return false
|
||||
}
|
||||
|
||||
if context.visited_handling == VisitedHandlingMode::AllLinksVisitedAndUnvisited {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Non-relevant links are always unvisited.
|
||||
if *self != RelevantLinkStatus::Found {
|
||||
return true
|
||||
|
|
|
@ -268,6 +268,10 @@ impl EagerPseudoStyles {
|
|||
rules: StrongRuleNode)
|
||||
-> bool {
|
||||
match visited_handling {
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited => {
|
||||
unreachable!("We should never try to selector match with \
|
||||
AllLinksVisitedAndUnvisited");
|
||||
},
|
||||
VisitedHandlingMode::AllLinksUnvisited => {
|
||||
self.add_unvisited_rules(&pseudo, rules)
|
||||
},
|
||||
|
@ -286,6 +290,10 @@ impl EagerPseudoStyles {
|
|||
visited_handling: VisitedHandlingMode)
|
||||
-> bool {
|
||||
match visited_handling {
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited => {
|
||||
unreachable!("We should never try to selector match with \
|
||||
AllLinksVisitedAndUnvisited");
|
||||
},
|
||||
VisitedHandlingMode::AllLinksUnvisited => {
|
||||
self.remove_unvisited_rules(&pseudo)
|
||||
},
|
||||
|
|
|
@ -1258,6 +1258,10 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> {
|
|||
// Unvisited vs. visited styles are computed up-front based on the
|
||||
// visited mode (not the element's actual state).
|
||||
let declarations = match visited_handling {
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited => {
|
||||
unreachable!("We should never try to selector match with \
|
||||
AllLinksVisitedAndUnvisited");
|
||||
},
|
||||
VisitedHandlingMode::AllLinksUnvisited => unsafe {
|
||||
Gecko_GetUnvisitedLinkAttrDeclarationBlock(self.0)
|
||||
},
|
||||
|
|
|
@ -420,8 +420,14 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
|
|||
debug!("TreeStyleInvalidator::process_invalidation({:?}, {:?})",
|
||||
self.element, invalidation);
|
||||
|
||||
let mut context = MatchingContext::new(MatchingMode::Normal, None,
|
||||
self.shared_context.quirks_mode);
|
||||
let mut context =
|
||||
MatchingContext::new_for_visited(
|
||||
MatchingMode::Normal,
|
||||
None,
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited,
|
||||
self.shared_context.quirks_mode,
|
||||
);
|
||||
|
||||
let matching_result = matches_compound_selector(
|
||||
&invalidation.selector,
|
||||
invalidation.offset,
|
||||
|
|
|
@ -991,6 +991,10 @@ pub trait MatchMethods : TElement {
|
|||
&context.shared.guards);
|
||||
|
||||
let rules_changed = match visited_handling {
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited => {
|
||||
unreachable!("We should never try to selector match with \
|
||||
AllLinksVisitedAndUnvisited");
|
||||
},
|
||||
VisitedHandlingMode::AllLinksUnvisited => {
|
||||
data.set_primary_rules(rules)
|
||||
},
|
||||
|
@ -1070,6 +1074,10 @@ pub trait MatchMethods : TElement {
|
|||
);
|
||||
|
||||
let rules_changed = match visited_handling {
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited => {
|
||||
unreachable!("We should never try to selector match with \
|
||||
AllLinksVisitedAndUnvisited");
|
||||
},
|
||||
VisitedHandlingMode::AllLinksUnvisited => {
|
||||
data.set_primary_rules(primary_rule_node)
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue