mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Add support for resolving default computed styles.
This commit is contained in:
parent
1f323f8848
commit
cc44f05f44
9 changed files with 2784 additions and 2437 deletions
|
@ -13,7 +13,7 @@ use element_state::ElementState;
|
|||
use error_reporting::RustLogReporter;
|
||||
use font_metrics::FontMetricsProvider;
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::nsIAtom;
|
||||
use gecko_bindings::structs::{nsIAtom, StyleRuleInclusion};
|
||||
use keyframes::KeyframesAnimation;
|
||||
use media_queries::Device;
|
||||
use properties::{self, CascadeFlags, ComputedValues};
|
||||
|
@ -205,6 +205,27 @@ impl<'a> ExtraStyleData<'a> {
|
|||
fn clear(&mut self) {}
|
||||
}
|
||||
|
||||
/// What cascade levels to include when styling elements.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum RuleInclusion {
|
||||
/// Include rules for style sheets at all cascade levels. This is the
|
||||
/// normal rule inclusion mode.
|
||||
All,
|
||||
/// Only include rules from UA and user level sheets. Used to implement
|
||||
/// `getDefaultComputedStyle`.
|
||||
DefaultOnly,
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl From<StyleRuleInclusion> for RuleInclusion {
|
||||
fn from(value: StyleRuleInclusion) -> Self {
|
||||
match value {
|
||||
StyleRuleInclusion::All => RuleInclusion::All,
|
||||
StyleRuleInclusion::DefaultOnly => RuleInclusion::DefaultOnly,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stylist {
|
||||
/// Construct a new `Stylist`, using given `Device` and `QuirksMode`.
|
||||
/// If more members are added here, think about whether they should
|
||||
|
@ -625,13 +646,14 @@ impl Stylist {
|
|||
guards: &StylesheetGuards,
|
||||
element: &E,
|
||||
pseudo: &PseudoElement,
|
||||
rule_inclusion: RuleInclusion,
|
||||
parent_style: &ComputedValues,
|
||||
font_metrics: &FontMetricsProvider)
|
||||
-> Option<ComputedStyle>
|
||||
where E: TElement,
|
||||
{
|
||||
let rule_node =
|
||||
match self.lazy_pseudo_rules(guards, element, pseudo) {
|
||||
match self.lazy_pseudo_rules(guards, element, pseudo, rule_inclusion) {
|
||||
Some(rule_node) => rule_node,
|
||||
None => return None
|
||||
};
|
||||
|
@ -664,7 +686,8 @@ impl Stylist {
|
|||
pub fn lazy_pseudo_rules<E>(&self,
|
||||
guards: &StylesheetGuards,
|
||||
element: &E,
|
||||
pseudo: &PseudoElement)
|
||||
pseudo: &PseudoElement,
|
||||
rule_inclusion: RuleInclusion)
|
||||
-> Option<StrongRuleNode>
|
||||
where E: TElement
|
||||
{
|
||||
|
@ -683,6 +706,12 @@ impl Stylist {
|
|||
unreachable!("internal pseudo generated slow selector flags?");
|
||||
}
|
||||
|
||||
// No need to bother setting the selector flags when we're computing
|
||||
// default styles.
|
||||
if rule_inclusion == RuleInclusion::DefaultOnly {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gecko calls this from sequential mode, so we can directly apply
|
||||
// the flags.
|
||||
debug_assert!(thread_state::get() == thread_state::LAYOUT);
|
||||
|
@ -707,6 +736,7 @@ impl Stylist {
|
|||
None,
|
||||
None,
|
||||
AnimationRules(None, None),
|
||||
rule_inclusion,
|
||||
&mut declarations,
|
||||
&mut matching_context,
|
||||
&mut set_selector_flags);
|
||||
|
@ -836,6 +866,7 @@ impl Stylist {
|
|||
style_attribute: Option<&Arc<Locked<PropertyDeclarationBlock>>>,
|
||||
smil_override: Option<&Arc<Locked<PropertyDeclarationBlock>>>,
|
||||
animation_rules: AnimationRules,
|
||||
rule_inclusion: RuleInclusion,
|
||||
applicable_declarations: &mut V,
|
||||
context: &mut MatchingContext,
|
||||
flags_setter: &mut F)
|
||||
|
@ -871,6 +902,8 @@ impl Stylist {
|
|||
debug!("Determining if style is shareable: pseudo: {}",
|
||||
pseudo_element.is_some());
|
||||
|
||||
let only_default_rules = rule_inclusion == RuleInclusion::DefaultOnly;
|
||||
|
||||
// Step 1: Normal user-agent rules.
|
||||
map.user_agent.get_all_matching_rules(element,
|
||||
&rule_hash_target,
|
||||
|
@ -880,7 +913,7 @@ impl Stylist {
|
|||
CascadeLevel::UANormal);
|
||||
debug!("UA normal: {:?}", context.relations);
|
||||
|
||||
if pseudo_element.is_none() {
|
||||
if pseudo_element.is_none() && !only_default_rules {
|
||||
// Step 2: Presentational hints.
|
||||
let length_before_preshints = applicable_declarations.len();
|
||||
element.synthesize_presentational_hints_for_legacy_attributes(applicable_declarations);
|
||||
|
@ -905,7 +938,7 @@ impl Stylist {
|
|||
//
|
||||
// Which may be more what you would probably expect.
|
||||
if rule_hash_target.matches_user_and_author_rules() {
|
||||
// Step 3: User and author normal rules.
|
||||
// Step 3a: User normal rules.
|
||||
map.user.get_all_matching_rules(element,
|
||||
&rule_hash_target,
|
||||
applicable_declarations,
|
||||
|
@ -913,6 +946,12 @@ impl Stylist {
|
|||
flags_setter,
|
||||
CascadeLevel::UserNormal);
|
||||
debug!("user normal: {:?}", context.relations);
|
||||
} else {
|
||||
debug!("skipping user rules");
|
||||
}
|
||||
|
||||
if rule_hash_target.matches_user_and_author_rules() && !only_default_rules {
|
||||
// Step 3b: Author normal rules.
|
||||
map.author.get_all_matching_rules(element,
|
||||
&rule_hash_target,
|
||||
applicable_declarations,
|
||||
|
@ -961,15 +1000,20 @@ impl Stylist {
|
|||
// rule tree insertion.
|
||||
//
|
||||
|
||||
// Step 11: Transitions.
|
||||
// The transitions sheet (CSS transitions that are tied to CSS markup)
|
||||
if let Some(anim) = animation_rules.1 {
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
ApplicableDeclarationBlock::from_declarations(anim.clone(),
|
||||
CascadeLevel::Transitions));
|
||||
if !only_default_rules {
|
||||
// Step 11: Transitions.
|
||||
// The transitions sheet (CSS transitions that are tied to CSS markup)
|
||||
if let Some(anim) = animation_rules.1 {
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
ApplicableDeclarationBlock::from_declarations(anim.clone(),
|
||||
CascadeLevel::Transitions));
|
||||
}
|
||||
debug!("transition: {:?}", context.relations);
|
||||
} else {
|
||||
debug!("skipping transition rules");
|
||||
}
|
||||
debug!("transition: {:?}", context.relations);
|
||||
|
||||
debug!("push_applicable_declarations: shareable: {:?}", context.relations);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue