mirror of
https://github.com/servo/servo.git
synced 2025-06-22 16:18:59 +01:00
style: Adjust display:contents to display:inline for NAC (including ::before/::after).
This commit is contained in:
parent
04935de3ea
commit
36e4d0a511
3 changed files with 56 additions and 24 deletions
|
@ -17,7 +17,7 @@ use invalidation::element::restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_T
|
||||||
use invalidation::element::restyle_hints::{RESTYLE_SMIL, RESTYLE_STYLE_ATTRIBUTE};
|
use invalidation::element::restyle_hints::{RESTYLE_SMIL, RESTYLE_STYLE_ATTRIBUTE};
|
||||||
use invalidation::element::restyle_hints::RestyleHint;
|
use invalidation::element::restyle_hints::RestyleHint;
|
||||||
use log::LogLevel::Trace;
|
use log::LogLevel::Trace;
|
||||||
use properties::{ALLOW_SET_ROOT_FONT_SIZE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP};
|
use properties::{ALLOW_SET_ROOT_FONT_SIZE, PROHIBIT_DISPLAY_CONTENTS, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP};
|
||||||
use properties::{AnimationRules, CascadeFlags, ComputedValues};
|
use properties::{AnimationRules, CascadeFlags, ComputedValues};
|
||||||
use properties::{VISITED_DEPENDENT_ONLY, cascade};
|
use properties::{VISITED_DEPENDENT_ONLY, cascade};
|
||||||
use properties::longhands::display::computed_value as display;
|
use properties::longhands::display::computed_value as display;
|
||||||
|
@ -29,15 +29,23 @@ use sharing::StyleSharingBehavior;
|
||||||
use stylearc::Arc;
|
use stylearc::Arc;
|
||||||
use stylist::RuleInclusion;
|
use stylist::RuleInclusion;
|
||||||
|
|
||||||
/// The way a style should be inherited.
|
/// Whether we are cascading for an eager pseudo-element or something else.
|
||||||
enum InheritMode {
|
///
|
||||||
|
/// Controls where we inherit styles from, and whether display:contents is
|
||||||
|
/// prohibited.
|
||||||
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
enum CascadeTarget {
|
||||||
/// Inherit from the parent element, as normal CSS dictates, _or_ from the
|
/// Inherit from the parent element, as normal CSS dictates, _or_ from the
|
||||||
/// closest non-Native Anonymous element in case this is Native Anonymous
|
/// closest non-Native Anonymous element in case this is Native Anonymous
|
||||||
/// Content.
|
/// Content. display:contents is allowed.
|
||||||
Normal,
|
Normal,
|
||||||
/// Inherit from the primary style, this is used while computing eager
|
/// Inherit from the primary style, this is used while computing eager
|
||||||
/// pseudos, like ::before and ::after when we're traversing the parent.
|
/// pseudos, like ::before and ::after when we're traversing the parent.
|
||||||
FromPrimaryStyle,
|
/// Also prohibits display:contents from having an effect.
|
||||||
|
///
|
||||||
|
/// TODO(emilio) display:contents really should apply to ::before/::after.
|
||||||
|
/// https://github.com/w3c/csswg-drafts/issues/1345
|
||||||
|
EagerPseudo,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the result of comparing an element's old and new style.
|
/// Represents the result of comparing an element's old and new style.
|
||||||
|
@ -251,7 +259,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
font_metrics_provider: &FontMetricsProvider,
|
font_metrics_provider: &FontMetricsProvider,
|
||||||
rule_node: &StrongRuleNode,
|
rule_node: &StrongRuleNode,
|
||||||
primary_style: &ComputedStyle,
|
primary_style: &ComputedStyle,
|
||||||
inherit_mode: InheritMode,
|
cascade_target: CascadeTarget,
|
||||||
cascade_visited: CascadeVisitedMode,
|
cascade_visited: CascadeVisitedMode,
|
||||||
visited_values_to_insert: Option<Arc<ComputedValues>>)
|
visited_values_to_insert: Option<Arc<ComputedValues>>)
|
||||||
-> Arc<ComputedValues> {
|
-> Arc<ComputedValues> {
|
||||||
|
@ -263,15 +271,17 @@ trait PrivateMatchMethods: TElement {
|
||||||
if cascade_visited.visited_dependent_only() {
|
if cascade_visited.visited_dependent_only() {
|
||||||
cascade_flags.insert(VISITED_DEPENDENT_ONLY);
|
cascade_flags.insert(VISITED_DEPENDENT_ONLY);
|
||||||
}
|
}
|
||||||
if !self.is_native_anonymous() {
|
if self.is_native_anonymous() || cascade_target == CascadeTarget::EagerPseudo {
|
||||||
|
cascade_flags.insert(PROHIBIT_DISPLAY_CONTENTS);
|
||||||
|
} else {
|
||||||
cascade_flags.insert(ALLOW_SET_ROOT_FONT_SIZE);
|
cascade_flags.insert(ALLOW_SET_ROOT_FONT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the inherited values.
|
// Grab the inherited values.
|
||||||
let parent_el;
|
let parent_el;
|
||||||
let parent_data;
|
let parent_data;
|
||||||
let style_to_inherit_from = match inherit_mode {
|
let style_to_inherit_from = match cascade_target {
|
||||||
InheritMode::Normal => {
|
CascadeTarget::Normal => {
|
||||||
parent_el = self.inheritance_parent();
|
parent_el = self.inheritance_parent();
|
||||||
parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
|
parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
|
||||||
let parent_style = parent_data.as_ref().map(|d| {
|
let parent_style = parent_data.as_ref().map(|d| {
|
||||||
|
@ -287,7 +297,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
});
|
});
|
||||||
parent_style.map(|s| cascade_visited.values(s))
|
parent_style.map(|s| cascade_visited.values(s))
|
||||||
}
|
}
|
||||||
InheritMode::FromPrimaryStyle => {
|
CascadeTarget::EagerPseudo => {
|
||||||
parent_el = Some(self.clone());
|
parent_el = Some(self.clone());
|
||||||
Some(cascade_visited.values(primary_style))
|
Some(cascade_visited.values(primary_style))
|
||||||
}
|
}
|
||||||
|
@ -390,17 +400,17 @@ trait PrivateMatchMethods: TElement {
|
||||||
// Grab the rule node.
|
// Grab the rule node.
|
||||||
let style = eager_pseudo_style.unwrap_or(primary_style);
|
let style = eager_pseudo_style.unwrap_or(primary_style);
|
||||||
let rule_node = cascade_visited.rules(style);
|
let rule_node = cascade_visited.rules(style);
|
||||||
let inherit_mode = if eager_pseudo_style.is_some() {
|
let cascade_target = if eager_pseudo_style.is_some() {
|
||||||
InheritMode::FromPrimaryStyle
|
CascadeTarget::EagerPseudo
|
||||||
} else {
|
} else {
|
||||||
InheritMode::Normal
|
CascadeTarget::Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
self.cascade_with_rules(context.shared,
|
self.cascade_with_rules(context.shared,
|
||||||
&context.thread_local.font_metrics_provider,
|
&context.thread_local.font_metrics_provider,
|
||||||
rule_node,
|
rule_node,
|
||||||
primary_style,
|
primary_style,
|
||||||
inherit_mode,
|
cascade_target,
|
||||||
cascade_visited,
|
cascade_visited,
|
||||||
visited_values_to_insert)
|
visited_values_to_insert)
|
||||||
}
|
}
|
||||||
|
@ -536,7 +546,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
&context.thread_local.font_metrics_provider,
|
&context.thread_local.font_metrics_provider,
|
||||||
&without_transition_rules,
|
&without_transition_rules,
|
||||||
primary_style,
|
primary_style,
|
||||||
InheritMode::Normal,
|
CascadeTarget::Normal,
|
||||||
CascadeVisitedMode::Unvisited,
|
CascadeVisitedMode::Unvisited,
|
||||||
None))
|
None))
|
||||||
}
|
}
|
||||||
|
@ -1480,7 +1490,7 @@ pub trait MatchMethods : TElement {
|
||||||
font_metrics_provider,
|
font_metrics_provider,
|
||||||
&without_animation_rules,
|
&without_animation_rules,
|
||||||
primary_style,
|
primary_style,
|
||||||
InheritMode::Normal,
|
CascadeTarget::Normal,
|
||||||
CascadeVisitedMode::Unvisited,
|
CascadeVisitedMode::Unvisited,
|
||||||
None)
|
None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2479,6 +2479,10 @@ bitflags! {
|
||||||
/// ::backdrop and all NAC will resolve rem units against
|
/// ::backdrop and all NAC will resolve rem units against
|
||||||
/// the toplevel root element now.
|
/// the toplevel root element now.
|
||||||
const ALLOW_SET_ROOT_FONT_SIZE = 0x08,
|
const ALLOW_SET_ROOT_FONT_SIZE = 0x08,
|
||||||
|
/// Whether to convert display:contents into display:inline. This
|
||||||
|
/// is used by Gecko to prevent display:contents on generated
|
||||||
|
/// content.
|
||||||
|
const PROHIBIT_DISPLAY_CONTENTS = 0x10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2851,8 +2855,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
||||||
|
|
||||||
{
|
{
|
||||||
StyleAdjuster::new(&mut style, is_root_element)
|
StyleAdjuster::new(&mut style, is_root_element)
|
||||||
.adjust(context.layout_parent_style,
|
.adjust(context.layout_parent_style, flags);
|
||||||
flags.contains(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
//! for it to adhere to the CSS spec.
|
//! for it to adhere to the CSS spec.
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use properties::{self, ComputedValues, StyleBuilder};
|
use properties::{self, CascadeFlags, ComputedValues};
|
||||||
|
use properties::{SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, StyleBuilder};
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use properties::PROHIBIT_DISPLAY_CONTENTS;
|
||||||
use properties::longhands::display::computed_value::T as display;
|
use properties::longhands::display::computed_value::T as display;
|
||||||
use properties::longhands::float::computed_value::T as float;
|
use properties::longhands::float::computed_value::T as float;
|
||||||
use properties::longhands::overflow_x::computed_value::T as overflow;
|
use properties::longhands::overflow_x::computed_value::T as overflow;
|
||||||
|
@ -54,7 +57,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
/// https://drafts.csswg.org/css2/visuren.html#dis-pos-flo
|
/// https://drafts.csswg.org/css2/visuren.html#dis-pos-flo
|
||||||
fn blockify_if_necessary(&mut self,
|
fn blockify_if_necessary(&mut self,
|
||||||
layout_parent_style: &ComputedValues,
|
layout_parent_style: &ComputedValues,
|
||||||
skip_root_and_element_display_fixup: bool) {
|
flags: CascadeFlags) {
|
||||||
let mut blockify = false;
|
let mut blockify = false;
|
||||||
macro_rules! blockify_if {
|
macro_rules! blockify_if {
|
||||||
($if_what:expr) => {
|
($if_what:expr) => {
|
||||||
|
@ -64,7 +67,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skip_root_and_element_display_fixup {
|
if !flags.contains(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP) {
|
||||||
blockify_if!(self.is_root_element);
|
blockify_if!(self.is_root_element);
|
||||||
blockify_if!(layout_parent_style.get_box().clone_display().is_item_container());
|
blockify_if!(layout_parent_style.get_box().clone_display().is_item_container());
|
||||||
}
|
}
|
||||||
|
@ -275,6 +278,19 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Native anonymous content converts display:contents into display:inline.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn adjust_for_prohibited_display_contents(&mut self, flags: CascadeFlags) {
|
||||||
|
// TODO: We should probably convert display:contents into display:none
|
||||||
|
// in some cases too: https://drafts.csswg.org/css-display/#unbox
|
||||||
|
if !flags.contains(PROHIBIT_DISPLAY_CONTENTS) ||
|
||||||
|
self.style.get_box().clone_display() != display::contents {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.style.mutate_box().set_display(display::inline);
|
||||||
|
}
|
||||||
|
|
||||||
/// -moz-center, -moz-left and -moz-right are used for HTML's alignment.
|
/// -moz-center, -moz-left and -moz-right are used for HTML's alignment.
|
||||||
///
|
///
|
||||||
/// This is covering the <div align="right"><table>...</table></div> case.
|
/// This is covering the <div align="right"><table>...</table></div> case.
|
||||||
|
@ -305,10 +321,13 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
/// `nsStyleContext::ApplyStyleFixups`.
|
/// `nsStyleContext::ApplyStyleFixups`.
|
||||||
pub fn adjust(&mut self,
|
pub fn adjust(&mut self,
|
||||||
layout_parent_style: &ComputedValues,
|
layout_parent_style: &ComputedValues,
|
||||||
skip_root_and_element_display_fixup: bool) {
|
flags: CascadeFlags) {
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
{
|
||||||
|
self.adjust_for_prohibited_display_contents(flags);
|
||||||
|
}
|
||||||
self.adjust_for_top_layer();
|
self.adjust_for_top_layer();
|
||||||
self.blockify_if_necessary(layout_parent_style,
|
self.blockify_if_necessary(layout_parent_style, flags);
|
||||||
skip_root_and_element_display_fixup);
|
|
||||||
self.adjust_for_position();
|
self.adjust_for_position();
|
||||||
self.adjust_for_overflow();
|
self.adjust_for_overflow();
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue