aboutsummaryrefslogtreecommitdiffstats
path: root/components/style/traversal.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/style/traversal.rs')
-rw-r--r--components/style/traversal.rs117
1 files changed, 63 insertions, 54 deletions
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 47d33dd7269..a438211495a 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -8,7 +8,7 @@
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
-use data::{ElementData, ElementStyles, StoredRestyleHint};
+use data::{ElementData, ElementStyles, RestyleKind, StoredRestyleHint};
use dom::{NodeInfo, TElement, TNode};
use matching::{MatchMethods, StyleSharingResult};
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
@@ -453,9 +453,6 @@ pub fn recalc_style_at<E, D>(traversal: &D,
// Computes style, returning true if the inherited styles changed for this
// element.
-//
-// FIXME(bholley): This should differentiate between matching and cascading,
-// since we have separate bits for each now.
fn compute_style<E, D>(_traversal: &D,
traversal_data: &mut PerLevelTraversalData,
context: &mut StyleContext<E>,
@@ -466,63 +463,75 @@ fn compute_style<E, D>(_traversal: &D,
{
context.thread_local.statistics.elements_styled += 1;
let shared_context = context.shared;
- // Ensure the bloom filter is up to date.
- let dom_depth = context.thread_local.bloom_filter
- .insert_parents_recovering(element, traversal_data.current_dom_depth);
- // Update the dom depth with the up-to-date dom depth.
- //
- // Note that this is always the same than the pre-existing depth, but it can
- // change from unknown to known at this step.
- traversal_data.current_dom_depth = Some(dom_depth);
-
- context.thread_local.bloom_filter.assert_complete(element);
-
- // Check to see whether we can share a style with someone.
- let sharing_result = if element.parent_element().is_none() {
- StyleSharingResult::CannotShare
- } else {
- unsafe { element.share_style_if_possible(&mut context.thread_local.style_sharing_candidate_cache,
- shared_context, &mut data) }
- };
+ // TODO(emilio): Make cascade_input less expensive to compute in the cases
+ // we don't need to run selector matching.
+ let cascade_input = match data.restyle_kind() {
+ RestyleKind::MatchAndCascade => {
+ // Check to see whether we can share a style with someone.
+ let sharing_result = unsafe {
+ element.share_style_if_possible(&mut context.thread_local.style_sharing_candidate_cache,
+ shared_context,
+ &mut data)
+ };
- // Otherwise, match and cascade selectors.
- match sharing_result {
- StyleSharingResult::CannotShare => {
- let match_results;
- let shareable_element = {
- // Perform the CSS selector matching.
- context.thread_local.statistics.elements_matched += 1;
- let filter = context.thread_local.bloom_filter.filter();
- match_results = element.match_element(context, Some(filter));
- if match_results.primary_is_shareable() {
- Some(element)
- } else {
+ match sharing_result {
+ StyleSharingResult::StyleWasShared(index) => {
+ context.thread_local.statistics.styles_shared += 1;
+ context.thread_local.style_sharing_candidate_cache.touch(index);
None
}
- };
- let relations = match_results.relations;
-
- // Perform the CSS cascade.
- unsafe {
- let shareable = match_results.primary_is_shareable();
- element.cascade_node(context, &mut data,
- element.parent_element(),
- match_results.primary,
- match_results.per_pseudo,
- shareable);
- }
+ StyleSharingResult::CannotShare => {
+ // Ensure the bloom filter is up to date.
+ let dom_depth =
+ context.thread_local.bloom_filter
+ .insert_parents_recovering(element,
+ traversal_data.current_dom_depth);
+
+ // Update the dom depth with the up-to-date dom depth.
+ //
+ // Note that this is always the same than the pre-existing depth,
+ // but it can change from unknown to known at this step.
+ traversal_data.current_dom_depth = Some(dom_depth);
- // Add ourselves to the LRU cache.
- if let Some(element) = shareable_element {
- context.thread_local
- .style_sharing_candidate_cache
- .insert_if_possible(&element, &data.styles().primary.values, relations);
+ context.thread_local.bloom_filter.assert_complete(element);
+
+ // Perform the CSS selector matching.
+ context.thread_local.statistics.elements_matched += 1;
+
+ let filter = context.thread_local.bloom_filter.filter();
+ Some(element.match_element(context, Some(filter)))
+ }
}
}
- StyleSharingResult::StyleWasShared(index) => {
- context.thread_local.statistics.styles_shared += 1;
- context.thread_local.style_sharing_candidate_cache.touch(index);
+ RestyleKind::CascadeWithReplacements(hint) => {
+ Some(element.cascade_with_replacements(hint, context, &mut data))
+ }
+ RestyleKind::CascadeOnly => {
+ // TODO(emilio): Stop doing this work, and teach cascade_node about
+ // the current style instead.
+ Some(element.match_results_from_current_style(&*data))
+ }
+ };
+
+ if let Some(match_results) = cascade_input {
+ // Perform the CSS cascade.
+ let shareable = match_results.primary_is_shareable();
+ unsafe {
+ element.cascade_node(context, &mut data,
+ element.parent_element(),
+ match_results.primary,
+ match_results.per_pseudo,
+ shareable);
+ }
+
+ if shareable {
+ // Add ourselves to the LRU cache.
+ context.thread_local
+ .style_sharing_candidate_cache
+ .insert_if_possible(&element,
+ &data.styles().primary.values,
+ match_results.relations);
}
}