mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
style: Implement CSS revert keyword.
The only fishy bit is the animation stuff. In particular, there are two places where we just mint the revert behavior: * When serializing web-animations keyframes (the custom properties stuff in declaration_block.rs). That codepath is already not sound and I wanted to get rid of it in bug 1501530, but what do I know. * When getting an animation value from a property declaration. At that point we no longer have the CSS rules that apply to the element to compute the right revert value handy. It'd also use the wrong style anyway, I think, given the way StyleBuilder::for_animation works. We _could_ probably get them out of somewhere, but it seems like a whole lot of code reinventing the wheel which is probably not useful, and that Blink and WebKit just cannot implement either since they don't have a rule tree, so it just doesn't seem worth the churn. The custom properties code looks a bit different in order to minimize hash lookups in the common case. FWIW, `revert` for custom properties doesn't seem very useful either, but oh well. Differential Revision: https://phabricator.services.mozilla.com/D21877
This commit is contained in:
parent
80ed070639
commit
6fd17ccb35
9 changed files with 119 additions and 20 deletions
|
@ -17,6 +17,7 @@ use crate::properties::CASCADE_PROPERTY;
|
|||
use crate::rule_cache::{RuleCache, RuleCacheConditions};
|
||||
use crate::rule_tree::{CascadeLevel, StrongRuleNode};
|
||||
use crate::selector_parser::PseudoElement;
|
||||
use crate::stylesheets::{Origin, PerOrigin};
|
||||
use servo_arc::Arc;
|
||||
use crate::shared_lock::StylesheetGuards;
|
||||
use smallbitvec::SmallBitVec;
|
||||
|
@ -251,7 +252,7 @@ where
|
|||
for (declaration, cascade_level) in iter_declarations() {
|
||||
declarations.push((declaration, cascade_level));
|
||||
if let PropertyDeclaration::Custom(ref declaration) = *declaration {
|
||||
builder.cascade(&declaration.name, &declaration.value);
|
||||
builder.cascade(declaration, cascade_level.origin());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,14 +340,8 @@ fn should_ignore_declaration_when_ignoring_document_colors(
|
|||
return false;
|
||||
}
|
||||
|
||||
let is_ua_or_user_rule = matches!(
|
||||
cascade_level,
|
||||
CascadeLevel::UANormal |
|
||||
CascadeLevel::UserNormal |
|
||||
CascadeLevel::UserImportant |
|
||||
CascadeLevel::UAImportant
|
||||
);
|
||||
|
||||
let is_ua_or_user_rule =
|
||||
matches!(cascade_level.origin(), Origin::User | Origin::UserAgent);
|
||||
if is_ua_or_user_rule {
|
||||
return false;
|
||||
}
|
||||
|
@ -388,6 +383,7 @@ struct Cascade<'a, 'b: 'a> {
|
|||
context: &'a mut computed::Context<'b>,
|
||||
cascade_mode: CascadeMode<'a>,
|
||||
seen: LonghandIdSet,
|
||||
reverted: PerOrigin<LonghandIdSet>,
|
||||
saved_font_size: Option<PropertyDeclaration>,
|
||||
saved_font_family: Option<PropertyDeclaration>,
|
||||
}
|
||||
|
@ -398,6 +394,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
context,
|
||||
cascade_mode,
|
||||
seen: LonghandIdSet::default(),
|
||||
reverted: Default::default(),
|
||||
saved_font_size: None,
|
||||
saved_font_family: None,
|
||||
}
|
||||
|
@ -488,6 +485,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
|
||||
for (declaration, cascade_level) in declarations {
|
||||
let declaration_id = declaration.id();
|
||||
let origin = cascade_level.origin();
|
||||
let longhand_id = match declaration_id {
|
||||
PropertyDeclarationId::Longhand(id) => id,
|
||||
PropertyDeclarationId::Custom(..) => continue,
|
||||
|
@ -513,6 +511,10 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
continue;
|
||||
}
|
||||
|
||||
if self.reverted.borrow_for_origin(&origin).contains(physical_longhand_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only a few properties are allowed to depend on the visited state
|
||||
// of links. When cascading visited styles, we can save time by
|
||||
// only processing these properties.
|
||||
|
@ -540,6 +542,15 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
if declaration.is_revert() {
|
||||
for origin in origin.following_including() {
|
||||
self.reverted
|
||||
.borrow_mut_for_origin(&origin)
|
||||
.insert(physical_longhand_id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
self.seen.insert(physical_longhand_id);
|
||||
|
||||
// FIXME(emilio): We should avoid generating code for logical
|
||||
|
|
|
@ -849,7 +849,7 @@ impl PropertyDeclarationBlock {
|
|||
|
||||
for declaration in self.normal_declaration_iter() {
|
||||
if let PropertyDeclaration::Custom(ref declaration) = *declaration {
|
||||
builder.cascade(&declaration.name, &declaration.value);
|
||||
builder.cascade(declaration, Origin::Author);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -349,6 +349,7 @@
|
|||
context.builder.inherit_${property.ident}();
|
||||
% endif
|
||||
}
|
||||
CSSWideKeyword::Revert => unreachable!("Should never get here"),
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -452,14 +452,23 @@ impl AnimationValue {
|
|||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
LonghandId::${prop.camel_case} => {
|
||||
// FIXME(emilio, bug 1533327): I think
|
||||
// CSSWideKeyword::Revert handling is not fine here, but
|
||||
// what to do instead?
|
||||
//
|
||||
// Seems we'd need the computed value as if it was
|
||||
// revert, somehow. Treating it as `unset` seems fine
|
||||
// for now...
|
||||
let style_struct = match declaration.keyword {
|
||||
% if not prop.style_struct.inherited:
|
||||
CSSWideKeyword::Revert |
|
||||
CSSWideKeyword::Unset |
|
||||
% endif
|
||||
CSSWideKeyword::Initial => {
|
||||
initial.get_${prop.style_struct.name_lower}()
|
||||
},
|
||||
% if prop.style_struct.inherited:
|
||||
CSSWideKeyword::Revert |
|
||||
CSSWideKeyword::Unset |
|
||||
% endif
|
||||
CSSWideKeyword::Inherit => {
|
||||
|
|
|
@ -900,6 +900,8 @@ pub enum CSSWideKeyword {
|
|||
Inherit,
|
||||
/// The `unset` keyword.
|
||||
Unset,
|
||||
/// The `revert` keyword.
|
||||
Revert,
|
||||
}
|
||||
|
||||
impl CSSWideKeyword {
|
||||
|
@ -908,6 +910,7 @@ impl CSSWideKeyword {
|
|||
CSSWideKeyword::Initial => "initial",
|
||||
CSSWideKeyword::Inherit => "inherit",
|
||||
CSSWideKeyword::Unset => "unset",
|
||||
CSSWideKeyword::Revert => "revert",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -921,6 +924,7 @@ impl CSSWideKeyword {
|
|||
"initial" => CSSWideKeyword::Initial,
|
||||
"inherit" => CSSWideKeyword::Inherit,
|
||||
"unset" => CSSWideKeyword::Unset,
|
||||
"revert" => CSSWideKeyword::Revert,
|
||||
_ => return Err(()),
|
||||
}
|
||||
};
|
||||
|
@ -2103,6 +2107,7 @@ impl PropertyDeclaration {
|
|||
}
|
||||
|
||||
/// Returns a CSS-wide keyword if the declaration's value is one.
|
||||
#[inline]
|
||||
pub fn get_css_wide_keyword(&self) -> Option<CSSWideKeyword> {
|
||||
match *self {
|
||||
PropertyDeclaration::CSSWideKeyword(ref declaration) => {
|
||||
|
@ -2112,6 +2117,12 @@ impl PropertyDeclaration {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether this declaration is the `revert` keyword.
|
||||
#[inline]
|
||||
pub fn is_revert(&self) -> bool {
|
||||
self.get_css_wide_keyword().map_or(false, |kw| kw == CSSWideKeyword::Revert)
|
||||
}
|
||||
|
||||
/// Returns whether or not the property is set by a system font
|
||||
pub fn get_system(&self) -> Option<SystemFont> {
|
||||
match *self {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue