mirror of
https://github.com/servo/servo.git
synced 2025-06-18 13:24:29 +00:00
style: Allow sharing style for elements with presentational hints.
This commit is contained in:
parent
03952a0c27
commit
10bd5636dc
2 changed files with 46 additions and 19 deletions
|
@ -12,7 +12,6 @@ use element_state::*;
|
|||
use selectors::bloom::BloomFilter;
|
||||
use selectors::matching::StyleRelations;
|
||||
use sharing::{StyleSharingCandidate, StyleSharingTarget};
|
||||
use sink::ForgetfulSink;
|
||||
use stylearc::Arc;
|
||||
|
||||
/// Determines, based on the results of selector matching, whether it's worth to
|
||||
|
@ -23,8 +22,7 @@ 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_PRESENTATIONAL_HINTS)
|
||||
AFFECTED_BY_STYLE_ATTRIBUTE)
|
||||
}
|
||||
|
||||
/// Whether, given two elements, they have pointer-equal computed values.
|
||||
|
@ -51,12 +49,13 @@ pub fn same_computed_values<E>(first: Option<E>, second: Option<E>) -> bool
|
|||
/// 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.
|
||||
pub fn has_presentational_hints<E>(element: E) -> bool
|
||||
pub fn have_same_presentational_hints<E>(
|
||||
target: &mut StyleSharingTarget<E>,
|
||||
candidate: &mut StyleSharingCandidate<E>
|
||||
) -> bool
|
||||
where E: TElement,
|
||||
{
|
||||
let mut hints = ForgetfulSink::new();
|
||||
element.synthesize_presentational_hints_for_legacy_attributes(&mut hints);
|
||||
!hints.is_empty()
|
||||
target.pres_hints() == candidate.pres_hints()
|
||||
}
|
||||
|
||||
/// Whether a given element has the same class attribute than a given candidate.
|
||||
|
|
|
@ -15,10 +15,9 @@ use matching::{ChildCascadeRequirement, MatchMethods};
|
|||
use properties::ComputedValues;
|
||||
use selectors::bloom::BloomFilter;
|
||||
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
||||
use sink::ForgetfulSink;
|
||||
use smallvec::SmallVec;
|
||||
use std::ops::Deref;
|
||||
use stylist::Stylist;
|
||||
use stylist::{ApplicableDeclarationBlock, Stylist};
|
||||
|
||||
mod checks;
|
||||
|
||||
|
@ -45,6 +44,9 @@ pub struct CachedStyleSharingData {
|
|||
/// a similar fashion as what Boris is doing for the ID attribute.
|
||||
class_list: Option<SmallVec<[Atom; 5]>>,
|
||||
|
||||
/// The list of presentational attributes of the element.
|
||||
pres_hints: Option<SmallVec<[ApplicableDeclarationBlock; 5]>>,
|
||||
|
||||
/// The cached result of matching this entry against the revalidation
|
||||
/// selectors.
|
||||
revalidation_match_results: Option<BitVec>,
|
||||
|
@ -56,6 +58,7 @@ impl CachedStyleSharingData {
|
|||
pub fn new() -> Self {
|
||||
Self {
|
||||
class_list: None,
|
||||
pres_hints: None,
|
||||
revalidation_match_results: None,
|
||||
}
|
||||
}
|
||||
|
@ -64,10 +67,24 @@ impl CachedStyleSharingData {
|
|||
pub fn take(&mut self) -> Self {
|
||||
Self {
|
||||
class_list: self.class_list.take(),
|
||||
pres_hints: self.pres_hints.take(),
|
||||
revalidation_match_results: self.revalidation_match_results.take(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get or compute the list of presentational attributes associated with
|
||||
/// this element.
|
||||
pub fn pres_hints<E>(&mut self, element: E) -> &[ApplicableDeclarationBlock]
|
||||
where E: TElement,
|
||||
{
|
||||
if self.pres_hints.is_none() {
|
||||
let mut pres_hints = SmallVec::new();
|
||||
element.synthesize_presentational_hints_for_legacy_attributes(&mut pres_hints);
|
||||
self.pres_hints = Some(pres_hints);
|
||||
}
|
||||
&*self.pres_hints.as_ref().unwrap()
|
||||
}
|
||||
|
||||
/// Get or compute the class-list associated with this element.
|
||||
pub fn class_list<E>(&mut self, element: E) -> &[Atom]
|
||||
where E: TElement,
|
||||
|
@ -121,6 +138,11 @@ impl<E: TElement> StyleSharingCandidate<E> {
|
|||
self.cache.class_list(*self.element)
|
||||
}
|
||||
|
||||
/// Get the pres hints of this candidate.
|
||||
fn pres_hints(&mut self) -> &[ApplicableDeclarationBlock] {
|
||||
self.cache.pres_hints(*self.element)
|
||||
}
|
||||
|
||||
/// Get the classlist of this candidate.
|
||||
fn revalidation_match_results(
|
||||
&mut self,
|
||||
|
@ -167,6 +189,11 @@ impl<E: TElement> StyleSharingTarget<E> {
|
|||
self.cache.class_list(self.element)
|
||||
}
|
||||
|
||||
/// Get the pres hints of this candidate.
|
||||
fn pres_hints(&mut self) -> &[ApplicableDeclarationBlock] {
|
||||
self.cache.pres_hints(self.element)
|
||||
}
|
||||
|
||||
fn revalidation_match_results(
|
||||
&mut self,
|
||||
stylist: &Stylist,
|
||||
|
@ -307,7 +334,9 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
element: &E,
|
||||
style: &ComputedValues,
|
||||
relations: StyleRelations,
|
||||
cache: CachedStyleSharingData) {
|
||||
mut cache: CachedStyleSharingData) {
|
||||
use selectors::matching::AFFECTED_BY_PRESENTATIONAL_HINTS;
|
||||
|
||||
let parent = match element.parent_element() {
|
||||
Some(element) => element,
|
||||
None => {
|
||||
|
@ -328,14 +357,6 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Make sure we noted any presentational hints in the StyleRelations.
|
||||
if cfg!(debug_assertions) {
|
||||
let mut hints = ForgetfulSink::new();
|
||||
element.synthesize_presentational_hints_for_legacy_attributes(&mut hints);
|
||||
debug_assert!(hints.is_empty(),
|
||||
"Style relations should not be shareable!");
|
||||
}
|
||||
|
||||
let box_style = style.get_box();
|
||||
if box_style.specifies_transitions() {
|
||||
debug!("Failing to insert to the cache: transitions");
|
||||
|
@ -347,6 +368,13 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Take advantage of the information we've learned during
|
||||
// selector-matching.
|
||||
if !relations.intersects(AFFECTED_BY_PRESENTATIONAL_HINTS) {
|
||||
debug_assert!(cache.pres_hints.as_ref().map_or(true, |v| v.is_empty()));
|
||||
cache.pres_hints = Some(SmallVec::new());
|
||||
}
|
||||
|
||||
debug!("Inserting into cache: {:?} with parent {:?}", element, parent);
|
||||
|
||||
self.cache.insert(StyleSharingCandidate {
|
||||
|
@ -532,7 +560,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
miss!(Class)
|
||||
}
|
||||
|
||||
if checks::has_presentational_hints(target.element) {
|
||||
if !checks::have_same_presentational_hints(target, candidate) {
|
||||
miss!(PresHints)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue