diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 521bcb3b815..07050d8c91b 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -23,14 +23,11 @@ bitflags! { pub flags StyleRelations: usize { /// Whether this element is affected by an ID selector. const AFFECTED_BY_ID_SELECTOR = 1 << 0, - /// Whether this element has a style attribute. Computed - /// externally. - const AFFECTED_BY_STYLE_ATTRIBUTE = 1 << 1, /// Whether this element is affected by presentational hints. This is /// computed externally (that is, in Servo). - const AFFECTED_BY_PRESENTATIONAL_HINTS = 1 << 2, + const AFFECTED_BY_PRESENTATIONAL_HINTS = 1 << 1, /// Whether this element has pseudo-element styles. Computed externally. - const AFFECTED_BY_PSEUDO_ELEMENTS = 1 << 3, + const AFFECTED_BY_PSEUDO_ELEMENTS = 1 << 2, } } diff --git a/components/style/sharing/checks.rs b/components/style/sharing/checks.rs index d773afc2bd4..40b5140809f 100644 --- a/components/style/sharing/checks.rs +++ b/components/style/sharing/checks.rs @@ -21,8 +21,7 @@ use stylearc::Arc; pub fn relations_are_shareable(relations: &StyleRelations) -> bool { use selectors::matching::*; !relations.intersects(AFFECTED_BY_ID_SELECTOR | - AFFECTED_BY_PSEUDO_ELEMENTS | - AFFECTED_BY_STYLE_ATTRIBUTE) + AFFECTED_BY_PSEUDO_ELEMENTS) } /// Whether, given two elements, they have pointer-equal computed values. @@ -44,11 +43,21 @@ pub fn same_computed_values(first: Option, second: Option) -> bool eq } -/// Whether a given element has presentational hints. -/// -/// We consider not worth to share style with an element that has presentational -/// hints, both because implementing the code that compares that the hints are -/// equal is somewhat annoying, and also because it'd be expensive enough. +/// Whether two elements have the same same style attribute (by pointer identity). +pub fn have_same_style_attribute( + target: &mut StyleSharingTarget, + candidate: &mut StyleSharingCandidate +) -> bool + where E: TElement, +{ + match (target.style_attribute(), candidate.style_attribute()) { + (None, None) => true, + (Some(_), None) | (None, Some(_)) => false, + (Some(a), Some(b)) => Arc::ptr_eq(a, b) + } +} + +/// Whether two elements have the same same presentational attributes. pub fn have_same_presentational_hints( target: &mut StyleSharingTarget, candidate: &mut StyleSharingCandidate diff --git a/components/style/sharing/mod.rs b/components/style/sharing/mod.rs index 0975e0cf4e1..4140d44a187 100644 --- a/components/style/sharing/mod.rs +++ b/components/style/sharing/mod.rs @@ -126,6 +126,15 @@ pub struct StyleSharingCandidate { validation_data: ValidationData, } +impl Deref for StyleSharingCandidate { + type Target = E; + + fn deref(&self) -> &Self::Target { + &self.element + } +} + + impl StyleSharingCandidate { /// Get the classlist of this candidate. fn class_list(&mut self) -> &[Atom] { @@ -409,12 +418,6 @@ impl StyleSharingCandidateCache { return StyleSharingResult::CannotShare; } - if target.style_attribute().is_some() { - debug!("{:?} Cannot share style: element has style attribute", - target.element); - return StyleSharingResult::CannotShare - } - if target.get_id().is_some() { debug!("{:?} Cannot share style: element has id", target.element); return StyleSharingResult::CannotShare @@ -542,7 +545,7 @@ impl StyleSharingCandidateCache { miss!(IdAttr) } - if target.style_attribute().is_some() { + if !checks::have_same_style_attribute(target, candidate) { miss!(StyleAttr) } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 48f369bd35b..e14ed0e27c5 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -26,8 +26,8 @@ use selector_map::{SelectorMap, SelectorMapEntry}; use selector_parser::{SelectorImpl, PseudoElement}; use selectors::attr::NamespaceConstraint; use selectors::bloom::BloomFilter; -use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS}; use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode}; +use selectors::matching::AFFECTED_BY_PRESENTATIONAL_HINTS; use selectors::parser::{Combinator, Component, Selector, SelectorInner, SelectorIter, SelectorMethods}; use selectors::visitor::SelectorVisitor; use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; @@ -1007,7 +1007,6 @@ impl Stylist { // Step 4: Normal style attributes. if let Some(sa) = style_attribute { - context.relations |= AFFECTED_BY_STYLE_ATTRIBUTE; Push::push( applicable_declarations, ApplicableDeclarationBlock::from_declarations(sa.clone(),