style: Add a style flag for the root element style.

This is needed to make the root element not a containing block in presence of
filters or what not.

Differential Revision: https://phabricator.services.mozilla.com/D61167
This commit is contained in:
Emilio Cobos Álvarez 2020-01-31 14:51:06 +00:00
parent f426b644ca
commit 16fd7cad0c
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
13 changed files with 37 additions and 46 deletions

View file

@ -120,6 +120,8 @@ pub mod attr;
pub mod author_styles;
pub mod bezier;
pub mod bloom;
#[path="properties/computed_value_flags.rs"]
pub mod computed_value_flags;
pub mod context;
pub mod counter_style;
pub mod custom_properties;

View file

@ -7,6 +7,7 @@
#![allow(unsafe_code)]
#![deny(missing_docs)]
use crate::computed_value_flags::ComputedValueFlags;
use crate::context::{ElementCascadeInputs, QuirksMode, SelectorFlagsMap};
use crate::context::{SharedStyleContext, StyleContext};
use crate::data::ElementData;
@ -705,7 +706,7 @@ pub trait MatchMethods: TElement {
let new_primary_style = data.styles.primary.as_ref().unwrap();
let mut cascade_requirement = ChildCascadeRequirement::CanSkipCascade;
if self.is_root() && !self.is_in_native_anonymous_subtree() {
if new_primary_style.flags.contains(ComputedValueFlags::IS_ROOT_ELEMENT_STYLE) {
let device = context.shared.stylist.device();
let new_font_size = new_primary_style.get_font().clone_font_size();

View file

@ -263,8 +263,11 @@ where
builder.build()
};
let is_root_element =
pseudo.is_none() && element.map_or(false, |e| e.is_root());
let mut context = computed::Context {
is_root_element: pseudo.is_none() && element.map_or(false, |e| e.is_root()),
// We'd really like to own the rules here to avoid refcount traffic, but
// animation's usage of `apply_declarations` make this tricky. See bug
// 1375525.
@ -275,6 +278,7 @@ where
pseudo,
Some(rules.clone()),
custom_properties,
is_root_element,
),
cached_system_font: None,
in_media_query: false,

View file

@ -11,6 +11,7 @@ bitflags! {
/// anonymous boxes, see StyleBuilder::for_inheritance and its callsites.
/// If we ever want to add some flags that shouldn't inherit for them,
/// we might want to add a function to handle this.
#[repr(C)]
pub struct ComputedValueFlags: u16 {
/// Whether the style or any of the ancestors has a text-decoration-line
/// property that should get propagated to descendants.
@ -63,6 +64,9 @@ bitflags! {
///
/// Only used in Servo.
const CAN_BE_FRAGMENTED = 1 << 10;
/// Whether this style is the style of the document element.
const IS_ROOT_ELEMENT_STYLE = 1 << 11;
}
}
@ -97,22 +101,3 @@ impl ComputedValueFlags {
self & Self::maybe_inherited_flags()
}
}
/// Asserts that the relevant servo and Gecko representations match.
#[cfg(feature = "gecko")]
#[inline]
pub fn assert_match() {
use crate::gecko_bindings::structs;
macro_rules! assert_bit {
($rust:ident, $cpp:ident) => {
debug_assert_eq!(ComputedValueFlags::$rust.bits, structs::$cpp);
}
}
assert_bit!(HAS_TEXT_DECORATION_LINES, ComputedStyleBit_HasTextDecorationLines);
assert_bit!(IS_IN_PSEUDO_ELEMENT_SUBTREE, ComputedStyleBit_HasPseudoElementData);
assert_bit!(SHOULD_SUPPRESS_LINEBREAK, ComputedStyleBit_SuppressLineBreak);
assert_bit!(IS_TEXT_COMBINED, ComputedStyleBit_IsTextCombined);
assert_bit!(IS_RELEVANT_LINK_VISITED, ComputedStyleBit_RelevantLinkVisited);
assert_bit!(DEPENDS_ON_FONT_METRICS, ComputedStyleBit_DependsOnFontMetrics);
}

View file

@ -12,6 +12,7 @@
use crate::Atom;
use app_units::Au;
use crate::computed_value_flags::*;
use crate::custom_properties::CustomPropertiesMap;
use crate::gecko_bindings::bindings;
% for style_struct in data.style_structs:
@ -39,7 +40,6 @@ use crate::gecko_bindings::structs::mozilla::PseudoStyleType;
use crate::gecko::values::round_border_to_device_pixels;
use crate::logical_geometry::WritingMode;
use crate::media_queries::Device;
use crate::properties::computed_value_flags::*;
use crate::properties::longhands;
use crate::rule_tree::StrongRuleNode;
use crate::selector_parser::PseudoElement;

View file

@ -28,6 +28,7 @@ use crate::context::QuirksMode;
#[cfg(feature = "servo")] use crate::computed_values;
use crate::logical_geometry::WritingMode;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use crate::computed_value_flags::*;
use crate::media_queries::Device;
use crate::parser::ParserContext;
use crate::properties::longhands::system_font::SystemFont;
@ -45,7 +46,6 @@ use crate::values::computed::NonNegativeLength;
use crate::values::serialize_atom_name;
use crate::rule_tree::StrongRuleNode;
use crate::Zero;
use self::computed_value_flags::*;
use crate::str::{CssString, CssStringBorrow, CssStringWriter};
use std::cell::Cell;
@ -58,8 +58,6 @@ pub use self::cascade::*;
import os.path
%>
#[path="${repr(os.path.join(os.path.dirname(__file__), 'computed_value_flags.rs'))[1:-1]}"]
pub mod computed_value_flags;
#[path="${repr(os.path.join(os.path.dirname(__file__), 'declaration_block.rs'))[1:-1]}"]
pub mod declaration_block;
#[path="${repr(os.path.join(os.path.dirname(__file__), 'cascade.rs'))[1:-1]}"]
@ -3436,6 +3434,9 @@ pub struct StyleBuilder<'a> {
/// `StyleAdjuster` did any work.
modified_reset: bool,
/// Whether this is the style for the root element.
pub is_root_element: bool,
/// The writing mode flags.
///
/// TODO(emilio): Make private.
@ -3462,6 +3463,7 @@ impl<'a> StyleBuilder<'a> {
pseudo: Option<<&'a PseudoElement>,
rules: Option<StrongRuleNode>,
custom_properties: Option<Arc<crate::custom_properties::CustomPropertiesMap>>,
is_root_element: bool,
) -> Self {
debug_assert_eq!(parent_style.is_some(), parent_style_ignoring_first_line.is_some());
#[cfg(feature = "gecko")]
@ -3483,6 +3485,7 @@ impl<'a> StyleBuilder<'a> {
pseudo,
rules,
modified_reset: false,
is_root_element,
custom_properties,
writing_mode: inherited_style.writing_mode,
flags: Cell::new(flags),
@ -3521,6 +3524,7 @@ impl<'a> StyleBuilder<'a> {
reset_style,
pseudo: None,
modified_reset: false,
is_root_element: false,
rules: None,
custom_properties: style_to_derive_from.custom_properties().cloned(),
writing_mode: style_to_derive_from.writing_mode,
@ -3648,6 +3652,7 @@ impl<'a> StyleBuilder<'a> {
pseudo,
/* rules = */ None,
parent.and_then(|p| p.custom_properties().cloned()),
/* is_root_element = */ false,
);
ret.visited_style = visited_style;
ret
@ -3830,9 +3835,9 @@ pub use self::lazy_static_module::INITIAL_SERVO_VALUES;
#[allow(missing_docs)]
mod lazy_static_module {
use crate::logical_geometry::WritingMode;
use create::computed_value_flags::ComputedValueFlags;
use servo_arc::Arc;
use super::{ComputedValues, ComputedValuesInner, longhands, style_structs};
use super::computed_value_flags::ComputedValueFlags;
lazy_static! {
/// The initial values for all style structs as defined by the specification.

View file

@ -5,8 +5,8 @@
//! A struct to encapsulate all the style fixups and flags propagations
//! a computed style needs in order for it to adhere to the CSS spec.
use crate::computed_value_flags::ComputedValueFlags;
use crate::dom::TElement;
use crate::properties::computed_value_flags::ComputedValueFlags;
use crate::properties::longhands::display::computed_value::T as Display;
use crate::properties::longhands::float::computed_value::T as Float;
use crate::properties::longhands::overflow_x::computed_value::T as Overflow;
@ -189,8 +189,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
};
}
let is_root = self.style.pseudo.is_none() && element.map_or(false, |e| e.is_root());
blockify_if!(is_root);
blockify_if!(self.style.is_root_element);
if !self.skip_item_display_fixup(element) {
let parent_display = layout_parent_style.get_box().clone_display();
blockify_if!(parent_display.is_item_container());
@ -213,7 +212,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
let display = self.style.get_box().clone_display();
let blockified_display = display.equivalent_block_display(is_root);
let blockified_display = display.equivalent_block_display(self.style.is_root_element);
if display != blockified_display {
self.style
.mutate_box()
@ -222,7 +221,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
/// Compute a few common flags for both text and element's style.
pub fn set_bits(&mut self) {
fn set_bits(&mut self) {
let display = self.style.get_box().clone_display();
if !display.is_contents() &&
@ -241,6 +240,10 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
.add_flags(ComputedValueFlags::IS_IN_PSEUDO_ELEMENT_SUBTREE);
}
if self.style.is_root_element {
self.style.add_flags(ComputedValueFlags::IS_ROOT_ELEMENT_STYLE);
}
#[cfg(feature = "servo-layout-2013")]
{
if self.style.get_parent_column().is_multicol() {
@ -257,6 +260,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
/// Note that this, for Gecko, comes through Servo_ComputedValues_Inherit.
#[cfg(feature = "gecko")]
pub fn adjust_for_text(&mut self) {
debug_assert!(!self.style.is_root_element);
self.adjust_for_text_combine_upright();
self.adjust_for_text_in_ruby();
self.set_bits();

View file

@ -110,7 +110,7 @@ fn eager_pseudo_is_definitely_not_generated(
pseudo: &PseudoElement,
style: &ComputedValues,
) -> bool {
use crate::properties::computed_value_flags::ComputedValueFlags;
use crate::computed_value_flags::ComputedValueFlags;
if !pseudo.is_before_or_after() {
return false;

View file

@ -733,7 +733,6 @@ impl MaybeNew for ViewportConstraints {
let mut conditions = RuleCacheConditions::default();
let context = Context {
is_root_element: false,
// Note: DEVICE-ADAPT § 5. states that relative length values are
// resolved against initial values
builder: StyleBuilder::for_inheritance(device, None, None),

View file

@ -775,7 +775,7 @@ fn note_children<E, D, F>(
child_hint |= RestyleHint::RECASCADE_SELF | RestyleHint::RECASCADE_DESCENDANTS;
},
ChildCascadeRequirement::MustCascadeChildrenIfInheritResetStyle => {
use crate::properties::computed_value_flags::ComputedValueFlags;
use crate::computed_value_flags::ComputedValueFlags;
if child_data
.styles
.primary()

View file

@ -126,9 +126,6 @@ pub mod url;
/// A `Context` is all the data a specified value could ever need to compute
/// itself and be transformed to a computed value.
pub struct Context<'a> {
/// Whether the current element is the root element.
pub is_root_element: bool,
/// Values accessed through this need to be in the properties "computed
/// early": color, text-decoration, font-size, display, position, float,
/// border-*-style, outline-style, font-family, writing-mode...
@ -187,7 +184,6 @@ impl<'a> Context<'a> {
let provider = get_metrics_provider_for_product();
let context = Context {
is_root_element: false,
builder: StyleBuilder::for_inheritance(device, None, None),
font_metrics_provider: &provider,
cached_system_font: None,
@ -201,11 +197,6 @@ impl<'a> Context<'a> {
f(&context)
}
/// Whether the current element is the root element.
pub fn is_root_element(&self) -> bool {
self.is_root_element
}
/// The current device.
pub fn device(&self) -> &Device {
self.builder.device

View file

@ -7,9 +7,9 @@
//! [length]: https://drafts.csswg.org/css-values/#lengths
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
use crate::computed_value_flags::ComputedValueFlags;
use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
use crate::parser::{Parse, ParserContext};
use crate::properties::computed_value_flags::ComputedValueFlags;
use crate::values::computed::{self, CSSPixelLength, Context};
use crate::values::generics::length as generics;
use crate::values::generics::length::{
@ -206,7 +206,7 @@ impl FontRelativeLength {
// element, the rem units refer to the property's initial
// value.
//
let reference_size = if context.is_root_element || context.in_media_query {
let reference_size = if context.builder.is_root_element || context.in_media_query {
reference_font_size
} else {
computed::Length::new(context.device().root_font_size().to_f32_px())

View file

@ -596,7 +596,7 @@ impl ToComputedValue for TextAlign {
// In that case, the default behavior here will set it to left,
// but we want to set it to right -- instead set it to the default (`start`),
// which will do the right thing in this case (but not the general case)
if _context.is_root_element {
if _context.builder.is_root_element {
return TextAlignKeyword::Start;
}
let parent = _context