style: Simplify the implementation of HasAuthorSpecifiedRules.

This patch computes the author-specified properties during the CSS cascade, and
removes the complex rule-tree-based implementation that tries to do the cascade
again.

This changes behavior in two ways, one of them which is not observable to
content, I believe:

 * revert now re-enables the native styling. This was brought up in
   https://github.com/w3c/csswg-drafts/issues/4777 and I think it is a bug-fix.

   This is observable to content, and I'm adding a test for it.

 * We don't look at inherited styles from our ancestors when `inherit` is
   specified in a non-author stylesheet. This was introduced for bug 452969 but
   we don't seem to inherit background anymore for file controls or such. It
   seems back then file controls used to have a text-field.

   I audited forms.css and ua.css and we don't explicitly inherit
   padding / border / background-color into any nested form control.

We keep the distinction between border/background and padding, because the later
has some callers. I think we should try to align with Chromium in the long run
and remove the padding bit.

We need to give an appearance to the range-thumb and such so that we can assert
that we don't call HasAuthorSpecifiedRules on non-themed stuff. I used a new
internal value for that.

Differential Revision: https://phabricator.services.mozilla.com/D67722
This commit is contained in:
Emilio Cobos Álvarez 2020-03-26 16:48:01 +00:00
parent 7d438cd816
commit 414edb5a4a
5 changed files with 122 additions and 243 deletions

View file

@ -13,7 +13,7 @@ use crate::media_queries::Device;
use crate::properties::{ComputedValues, StyleBuilder};
use crate::properties::{LonghandId, LonghandIdSet, CSSWideKeyword};
use crate::properties::{PropertyDeclaration, PropertyDeclarationId, DeclarationImportanceIterator};
use crate::properties::CASCADE_PROPERTY;
use crate::properties::{CASCADE_PROPERTY, ComputedValueFlags};
use crate::rule_cache::{RuleCache, RuleCacheConditions};
use crate::rule_tree::StrongRuleNode;
use crate::selector_parser::PseudoElement;
@ -411,6 +411,7 @@ struct Cascade<'a, 'b: 'a> {
context: &'a mut computed::Context<'b>,
cascade_mode: CascadeMode<'a>,
seen: LonghandIdSet,
author_specified: LonghandIdSet,
reverted: PerOrigin<LonghandIdSet>,
}
@ -420,6 +421,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
context,
cascade_mode,
seen: LonghandIdSet::default(),
author_specified: LonghandIdSet::default(),
reverted: Default::default(),
}
}
@ -557,6 +559,9 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
}
self.seen.insert(physical_longhand_id);
if origin == Origin::Author {
self.author_specified.insert(physical_longhand_id);
}
let unset = css_wide_keyword.map_or(false, |css_wide_keyword| {
match css_wide_keyword {
@ -679,6 +684,14 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
if let Some(svg) = builder.get_svg_if_mutated() {
svg.fill_arrays();
}
}
if self.author_specified.contains_any(LonghandIdSet::border_background_properties()) {
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND);
}
if self.author_specified.contains_any(LonghandIdSet::padding_properties()) {
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_PADDING);
}
#[cfg(feature = "servo")]
@ -699,12 +712,26 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
None => return false,
};
let cached_style = match cache.find(guards, &self.context.builder) {
let builder = &mut self.context.builder;
let cached_style = match cache.find(guards, &builder) {
Some(style) => style,
None => return false,
};
self.context.builder.copy_reset_from(cached_style);
builder.copy_reset_from(cached_style);
// We're using the same reset style as another element, and we'll skip
// applying the relevant properties. So we need to do the relevant
// bookkeeping here to keep these two bits correct.
//
// Note that all the properties involved are non-inherited, so we don't
// need to do anything else other than just copying the bits over.
let reset_props_bits =
ComputedValueFlags::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND |
ComputedValueFlags::HAS_AUTHOR_SPECIFIED_PADDING;
builder.add_flags(cached_style.flags & reset_props_bits);
true
}