Compare style attributes rather than rejecting them from the cache.

MozReview-Commit-ID: Jmu7Pie2mBP
This commit is contained in:
Bobby Holley 2017-05-30 17:38:59 -07:00
parent f40c45fe1a
commit 47404cfc4e
4 changed files with 29 additions and 21 deletions

View file

@ -23,14 +23,11 @@ bitflags! {
pub flags StyleRelations: usize { pub flags StyleRelations: usize {
/// Whether this element is affected by an ID selector. /// Whether this element is affected by an ID selector.
const AFFECTED_BY_ID_SELECTOR = 1 << 0, 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 /// Whether this element is affected by presentational hints. This is
/// computed externally (that is, in Servo). /// 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. /// Whether this element has pseudo-element styles. Computed externally.
const AFFECTED_BY_PSEUDO_ELEMENTS = 1 << 3, const AFFECTED_BY_PSEUDO_ELEMENTS = 1 << 2,
} }
} }

View file

@ -21,8 +21,7 @@ use stylearc::Arc;
pub fn relations_are_shareable(relations: &StyleRelations) -> bool { pub fn relations_are_shareable(relations: &StyleRelations) -> bool {
use selectors::matching::*; use selectors::matching::*;
!relations.intersects(AFFECTED_BY_ID_SELECTOR | !relations.intersects(AFFECTED_BY_ID_SELECTOR |
AFFECTED_BY_PSEUDO_ELEMENTS | AFFECTED_BY_PSEUDO_ELEMENTS)
AFFECTED_BY_STYLE_ATTRIBUTE)
} }
/// Whether, given two elements, they have pointer-equal computed values. /// Whether, given two elements, they have pointer-equal computed values.
@ -44,11 +43,21 @@ pub fn same_computed_values<E>(first: Option<E>, second: Option<E>) -> bool
eq eq
} }
/// Whether a given element has presentational hints. /// Whether two elements have the same same style attribute (by pointer identity).
/// pub fn have_same_style_attribute<E>(
/// We consider not worth to share style with an element that has presentational target: &mut StyleSharingTarget<E>,
/// hints, both because implementing the code that compares that the hints are candidate: &mut StyleSharingCandidate<E>
/// equal is somewhat annoying, and also because it'd be expensive enough. ) -> 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<E>( pub fn have_same_presentational_hints<E>(
target: &mut StyleSharingTarget<E>, target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E> candidate: &mut StyleSharingCandidate<E>

View file

@ -126,6 +126,15 @@ pub struct StyleSharingCandidate<E: TElement> {
validation_data: ValidationData, validation_data: ValidationData,
} }
impl<E: TElement> Deref for StyleSharingCandidate<E> {
type Target = E;
fn deref(&self) -> &Self::Target {
&self.element
}
}
impl<E: TElement> StyleSharingCandidate<E> { impl<E: TElement> StyleSharingCandidate<E> {
/// Get the classlist of this candidate. /// Get the classlist of this candidate.
fn class_list(&mut self) -> &[Atom] { fn class_list(&mut self) -> &[Atom] {
@ -409,12 +418,6 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
return StyleSharingResult::CannotShare; 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() { if target.get_id().is_some() {
debug!("{:?} Cannot share style: element has id", target.element); debug!("{:?} Cannot share style: element has id", target.element);
return StyleSharingResult::CannotShare return StyleSharingResult::CannotShare
@ -542,7 +545,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
miss!(IdAttr) miss!(IdAttr)
} }
if target.style_attribute().is_some() { if !checks::have_same_style_attribute(target, candidate) {
miss!(StyleAttr) miss!(StyleAttr)
} }

View file

@ -26,8 +26,8 @@ use selector_map::{SelectorMap, SelectorMapEntry};
use selector_parser::{SelectorImpl, PseudoElement}; use selector_parser::{SelectorImpl, PseudoElement};
use selectors::attr::NamespaceConstraint; use selectors::attr::NamespaceConstraint;
use selectors::bloom::BloomFilter; 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::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode};
use selectors::matching::AFFECTED_BY_PRESENTATIONAL_HINTS;
use selectors::parser::{Combinator, Component, Selector, SelectorInner, SelectorIter, SelectorMethods}; use selectors::parser::{Combinator, Component, Selector, SelectorInner, SelectorIter, SelectorMethods};
use selectors::visitor::SelectorVisitor; use selectors::visitor::SelectorVisitor;
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
@ -1007,7 +1007,6 @@ impl Stylist {
// Step 4: Normal style attributes. // Step 4: Normal style attributes.
if let Some(sa) = style_attribute { if let Some(sa) = style_attribute {
context.relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
Push::push( Push::push(
applicable_declarations, applicable_declarations,
ApplicableDeclarationBlock::from_declarations(sa.clone(), ApplicableDeclarationBlock::from_declarations(sa.clone(),