diff --git a/components/style/sharing/checks.rs b/components/style/sharing/checks.rs index 5cc5869e509..4ac537e0009 100644 --- a/components/style/sharing/checks.rs +++ b/components/style/sharing/checks.rs @@ -8,6 +8,7 @@ use context::{CurrentElementInfo, SelectorFlagsMap, SharedStyleContext}; use dom::TElement; +use element_state::*; use matching::MatchMethods; use selectors::bloom::BloomFilter; use selectors::matching::{ElementSelectorFlags, StyleRelations}; @@ -80,6 +81,20 @@ pub fn have_same_class(element: E, element_class_attributes == *candidate.class_attributes.as_ref().unwrap() } +/// Compare element and candidate state, but ignore visitedness. Styles don't +/// actually changed based on visitedness (since both possibilities are computed +/// up front), so it's safe to share styles if visitedness differs. +pub fn have_same_state_ignoring_visitedness(element: E, + candidate: &StyleSharingCandidate) + -> bool + where E: TElement, +{ + let state_mask = !IN_VISITED_OR_UNVISITED_STATE; + let state = element.get_state() & state_mask; + let candidate_state = candidate.element.get_state() & state_mask; + state == candidate_state +} + /// Whether a given element and a candidate match the same set of "revalidation" /// selectors. /// diff --git a/components/style/sharing/mod.rs b/components/style/sharing/mod.rs index 744571ca863..67fde2e047b 100644 --- a/components/style/sharing/mod.rs +++ b/components/style/sharing/mod.rs @@ -349,7 +349,7 @@ impl StyleSharingCandidateCache { miss!(UserAndAuthorRules) } - if element.get_state() != candidate.element.get_state() { + if !checks::have_same_state_ignoring_visitedness(element, candidate) { miss!(State) }