mirror of
https://github.com/servo/servo.git
synced 2025-06-18 21:34:30 +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::bloom::BloomFilter;
|
||||||
use selectors::matching::StyleRelations;
|
use selectors::matching::StyleRelations;
|
||||||
use sharing::{StyleSharingCandidate, StyleSharingTarget};
|
use sharing::{StyleSharingCandidate, StyleSharingTarget};
|
||||||
use sink::ForgetfulSink;
|
|
||||||
use stylearc::Arc;
|
use stylearc::Arc;
|
||||||
|
|
||||||
/// Determines, based on the results of selector matching, whether it's worth to
|
/// 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::*;
|
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 |
|
AFFECTED_BY_STYLE_ATTRIBUTE)
|
||||||
AFFECTED_BY_PRESENTATIONAL_HINTS)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether, given two elements, they have pointer-equal computed values.
|
/// 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
|
/// 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
|
/// hints, both because implementing the code that compares that the hints are
|
||||||
/// equal is somewhat annoying, and also because it'd be expensive enough.
|
/// 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,
|
where E: TElement,
|
||||||
{
|
{
|
||||||
let mut hints = ForgetfulSink::new();
|
target.pres_hints() == candidate.pres_hints()
|
||||||
element.synthesize_presentational_hints_for_legacy_attributes(&mut hints);
|
|
||||||
!hints.is_empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether a given element has the same class attribute than a given candidate.
|
/// 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 properties::ComputedValues;
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
||||||
use sink::ForgetfulSink;
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use stylist::Stylist;
|
use stylist::{ApplicableDeclarationBlock, Stylist};
|
||||||
|
|
||||||
mod checks;
|
mod checks;
|
||||||
|
|
||||||
|
@ -45,6 +44,9 @@ pub struct CachedStyleSharingData {
|
||||||
/// a similar fashion as what Boris is doing for the ID attribute.
|
/// a similar fashion as what Boris is doing for the ID attribute.
|
||||||
class_list: Option<SmallVec<[Atom; 5]>>,
|
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
|
/// The cached result of matching this entry against the revalidation
|
||||||
/// selectors.
|
/// selectors.
|
||||||
revalidation_match_results: Option<BitVec>,
|
revalidation_match_results: Option<BitVec>,
|
||||||
|
@ -56,6 +58,7 @@ impl CachedStyleSharingData {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
class_list: None,
|
class_list: None,
|
||||||
|
pres_hints: None,
|
||||||
revalidation_match_results: None,
|
revalidation_match_results: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,10 +67,24 @@ impl CachedStyleSharingData {
|
||||||
pub fn take(&mut self) -> Self {
|
pub fn take(&mut self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
class_list: self.class_list.take(),
|
class_list: self.class_list.take(),
|
||||||
|
pres_hints: self.pres_hints.take(),
|
||||||
revalidation_match_results: self.revalidation_match_results.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.
|
/// Get or compute the class-list associated with this element.
|
||||||
pub fn class_list<E>(&mut self, element: E) -> &[Atom]
|
pub fn class_list<E>(&mut self, element: E) -> &[Atom]
|
||||||
where E: TElement,
|
where E: TElement,
|
||||||
|
@ -121,6 +138,11 @@ impl<E: TElement> StyleSharingCandidate<E> {
|
||||||
self.cache.class_list(*self.element)
|
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.
|
/// Get the classlist of this candidate.
|
||||||
fn revalidation_match_results(
|
fn revalidation_match_results(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -167,6 +189,11 @@ impl<E: TElement> StyleSharingTarget<E> {
|
||||||
self.cache.class_list(self.element)
|
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(
|
fn revalidation_match_results(
|
||||||
&mut self,
|
&mut self,
|
||||||
stylist: &Stylist,
|
stylist: &Stylist,
|
||||||
|
@ -307,7 +334,9 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
element: &E,
|
element: &E,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
relations: StyleRelations,
|
relations: StyleRelations,
|
||||||
cache: CachedStyleSharingData) {
|
mut cache: CachedStyleSharingData) {
|
||||||
|
use selectors::matching::AFFECTED_BY_PRESENTATIONAL_HINTS;
|
||||||
|
|
||||||
let parent = match element.parent_element() {
|
let parent = match element.parent_element() {
|
||||||
Some(element) => element,
|
Some(element) => element,
|
||||||
None => {
|
None => {
|
||||||
|
@ -328,14 +357,6 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
return;
|
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();
|
let box_style = style.get_box();
|
||||||
if box_style.specifies_transitions() {
|
if box_style.specifies_transitions() {
|
||||||
debug!("Failing to insert to the cache: transitions");
|
debug!("Failing to insert to the cache: transitions");
|
||||||
|
@ -347,6 +368,13 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
return;
|
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);
|
debug!("Inserting into cache: {:?} with parent {:?}", element, parent);
|
||||||
|
|
||||||
self.cache.insert(StyleSharingCandidate {
|
self.cache.insert(StyleSharingCandidate {
|
||||||
|
@ -532,7 +560,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
miss!(Class)
|
miss!(Class)
|
||||||
}
|
}
|
||||||
|
|
||||||
if checks::has_presentational_hints(target.element) {
|
if !checks::have_same_presentational_hints(target, candidate) {
|
||||||
miss!(PresHints)
|
miss!(PresHints)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue