mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #17722 - upsuper:ruby-fixup, r=heycam,bz
Implement style adjustments for ruby This is the Servo side changes of [bug 1378287](https://bugzilla.mozilla.org/show_bug.cgi?id=1378287) and [bug 1364274](https://bugzilla.mozilla.org/show_bug.cgi?id=1364274). <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17722) <!-- Reviewable:end -->
This commit is contained in:
commit
18c5ba108d
10 changed files with 206 additions and 56 deletions
|
@ -2663,7 +2663,6 @@ extern "C" {
|
||||||
pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
||||||
ServoComputedValuesBorrowedOrNull,
|
ServoComputedValuesBorrowedOrNull,
|
||||||
pseudo_tag: *mut nsIAtom,
|
pseudo_tag: *mut nsIAtom,
|
||||||
skip_display_fixup: bool,
|
|
||||||
set:
|
set:
|
||||||
RawServoStyleSetBorrowed)
|
RawServoStyleSetBorrowed)
|
||||||
-> ServoComputedValuesStrong;
|
-> ServoComputedValuesStrong;
|
||||||
|
@ -2680,6 +2679,11 @@ extern "C" {
|
||||||
ServoComputedValuesBorrowed)
|
ServoComputedValuesBorrowed)
|
||||||
-> ServoComputedValuesStrong;
|
-> ServoComputedValuesStrong;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_ComputedValues_GetStyleBits(values:
|
||||||
|
ServoComputedValuesBorrowed)
|
||||||
|
-> u64;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_ComputedValues_GetStyleRuleList(values:
|
pub fn Servo_ComputedValues_GetStyleRuleList(values:
|
||||||
ServoComputedValuesBorrowed,
|
ServoComputedValuesBorrowed,
|
||||||
|
|
|
@ -55,7 +55,7 @@ class CSSPseudoElementsAtomSource:
|
||||||
|
|
||||||
|
|
||||||
class CSSAnonBoxesAtomSource:
|
class CSSAnonBoxesAtomSource:
|
||||||
PATTERN = re.compile('^(?:CSS_ANON_BOX|CSS_NON_INHERITING_ANON_BOX)\((.+),\s*"(.*)"(\,|\))')
|
PATTERN = re.compile('^(?:CSS_ANON_BOX|CSS_NON_INHERITING_ANON_BOX)\((.+),\s*"(.*)"\)')
|
||||||
FILE = "include/nsCSSAnonBoxList.h"
|
FILE = "include/nsCSSAnonBoxList.h"
|
||||||
CLASS = "nsCSSAnonBoxes"
|
CLASS = "nsCSSAnonBoxes"
|
||||||
TYPE = "nsICSSAnonBoxPseudo"
|
TYPE = "nsICSSAnonBoxPseudo"
|
||||||
|
|
|
@ -301,7 +301,6 @@ trait PrivateMatchMethods: TElement {
|
||||||
new_values: &Arc<ComputedValues>,
|
new_values: &Arc<ComputedValues>,
|
||||||
pseudo: Option<&PseudoElement>)
|
pseudo: Option<&PseudoElement>)
|
||||||
-> ChildCascadeRequirement {
|
-> ChildCascadeRequirement {
|
||||||
use properties::computed_value_flags::*;
|
|
||||||
// Don't accumulate damage if we're in a restyle for reconstruction.
|
// Don't accumulate damage if we're in a restyle for reconstruction.
|
||||||
if shared_context.traversal_flags.for_reconstruct() {
|
if shared_context.traversal_flags.for_reconstruct() {
|
||||||
return ChildCascadeRequirement::MustCascadeChildren;
|
return ChildCascadeRequirement::MustCascadeChildren;
|
||||||
|
@ -327,10 +326,8 @@ trait PrivateMatchMethods: TElement {
|
||||||
match difference.change {
|
match difference.change {
|
||||||
StyleChange::Unchanged => {
|
StyleChange::Unchanged => {
|
||||||
// We need to cascade the children in order to ensure the
|
// We need to cascade the children in order to ensure the
|
||||||
// correct propagation of text-decoration-line, which is a reset
|
// correct propagation of computed value flags.
|
||||||
// property.
|
if old_values.flags != new_values.flags {
|
||||||
if old_values.flags.contains(HAS_TEXT_DECORATION_LINE) !=
|
|
||||||
new_values.flags.contains(HAS_TEXT_DECORATION_LINE) {
|
|
||||||
return ChildCascadeRequirement::MustCascadeChildren;
|
return ChildCascadeRequirement::MustCascadeChildren;
|
||||||
}
|
}
|
||||||
ChildCascadeRequirement::CanSkipCascade
|
ChildCascadeRequirement::CanSkipCascade
|
||||||
|
|
|
@ -4,42 +4,29 @@
|
||||||
|
|
||||||
//! Misc information about a given computed style.
|
//! Misc information about a given computed style.
|
||||||
|
|
||||||
use properties::{ComputedValues, StyleBuilder};
|
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Misc information about a given computed style.
|
/// Misc information about a given computed style.
|
||||||
|
///
|
||||||
|
/// All flags are currently inherited for text, pseudo elements, and
|
||||||
|
/// 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.
|
||||||
pub flags ComputedValueFlags: u8 {
|
pub flags ComputedValueFlags: u8 {
|
||||||
/// Whether the style or any of the ancestors has a text-decoration
|
/// Whether the style or any of the ancestors has a text-decoration-line
|
||||||
/// property that should get propagated to descendants.
|
/// property that should get propagated to descendants.
|
||||||
///
|
///
|
||||||
/// text-decoration is a reset property, but gets propagated in the
|
/// text-decoration-line is a reset property, but gets propagated in the
|
||||||
/// frame/box tree.
|
/// frame/box tree.
|
||||||
const HAS_TEXT_DECORATION_LINE = 1 << 0,
|
const HAS_TEXT_DECORATION_LINES = 1 << 0,
|
||||||
}
|
|
||||||
}
|
/// Whether line break inside should be suppressed.
|
||||||
|
///
|
||||||
impl ComputedValueFlags {
|
/// If this flag is set, the line should not be broken inside,
|
||||||
/// Get the computed value flags for the initial style.
|
/// which means inlines act as if nowrap is set, <br> element is
|
||||||
pub fn initial() -> Self {
|
/// suppressed, and blocks are inlinized.
|
||||||
Self::empty()
|
///
|
||||||
}
|
/// This bit is propagated to all children of line participants.
|
||||||
|
/// It is currently used by ruby to make its content unbreakable.
|
||||||
/// Compute the flags for this style, given the parent style.
|
const SHOULD_SUPPRESS_LINEBREAK = 1 << 1,
|
||||||
pub fn compute(
|
|
||||||
this_style: &StyleBuilder,
|
|
||||||
parent_style: &ComputedValues,
|
|
||||||
) -> Self {
|
|
||||||
let mut ret = Self::empty();
|
|
||||||
|
|
||||||
// FIXME(emilio): This feels like it wants to look at the
|
|
||||||
// layout_parent_style, but the way it works in Gecko means it's not
|
|
||||||
// needed (we'd recascade a bit more when it changes, but that's fine),
|
|
||||||
// and this way it simplifies the code for text styles and similar.
|
|
||||||
if parent_style.flags.contains(HAS_TEXT_DECORATION_LINE) ||
|
|
||||||
!this_style.get_text().clone_text_decoration_line().is_empty() {
|
|
||||||
ret.insert(HAS_TEXT_DECORATION_LINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl ComputedValues {
|
||||||
custom_properties: None,
|
custom_properties: None,
|
||||||
writing_mode: WritingMode::empty(), // FIXME(bz): This seems dubious
|
writing_mode: WritingMode::empty(), // FIXME(bz): This seems dubious
|
||||||
font_computation_data: FontComputationData::default_values(),
|
font_computation_data: FontComputationData::default_values(),
|
||||||
flags: ComputedValueFlags::initial(),
|
flags: ComputedValueFlags::empty(),
|
||||||
rules: None,
|
rules: None,
|
||||||
visited_style: None,
|
visited_style: None,
|
||||||
% for style_struct in data.style_structs:
|
% for style_struct in data.style_structs:
|
||||||
|
|
|
@ -53,6 +53,34 @@
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether an element with this display type is a line
|
||||||
|
/// participant, which means it may lay its children on the same
|
||||||
|
/// line as itself.
|
||||||
|
pub fn is_line_participant(&self) -> bool {
|
||||||
|
matches!(*self,
|
||||||
|
T::inline
|
||||||
|
% if product == "gecko":
|
||||||
|
| T::contents
|
||||||
|
| T::ruby
|
||||||
|
| T::ruby_base_container
|
||||||
|
% endif
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether this "display" value is one of the types for
|
||||||
|
/// ruby.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn is_ruby_type(&self) -> bool {
|
||||||
|
matches!(*self, T::ruby | T::ruby_base | T::ruby_text |
|
||||||
|
T::ruby_base_container | T::ruby_text_container)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether this "display" value is a ruby level container.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn is_ruby_level_container(&self) -> bool {
|
||||||
|
matches!(*self, T::ruby_base_container | T::ruby_text_container)
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert this display into an equivalent block display.
|
/// Convert this display into an equivalent block display.
|
||||||
///
|
///
|
||||||
/// Also used for style adjustments.
|
/// Also used for style adjustments.
|
||||||
|
@ -82,6 +110,25 @@
|
||||||
// Everything else becomes block.
|
// Everything else becomes block.
|
||||||
_ => T::block,
|
_ => T::block,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert this display into an inline-outside display.
|
||||||
|
///
|
||||||
|
/// Ideally it should implement spec: https://drafts.csswg.org/css-display/#inlinify
|
||||||
|
/// but the spec isn't stable enough, so we copy what Gecko does for now.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn inlinify(&self) -> Self {
|
||||||
|
match *self {
|
||||||
|
T::block | T::flow_root => T::inline_block,
|
||||||
|
T::table => T::inline_table,
|
||||||
|
T::flex => T::inline_flex,
|
||||||
|
T::grid => T::inline_grid,
|
||||||
|
T::_moz_box => T::_moz_inline_box,
|
||||||
|
T::_moz_stack => T::_moz_inline_stack,
|
||||||
|
T::_webkit_box => T::_webkit_inline_box,
|
||||||
|
other => other,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@
|
||||||
${helpers.single_keyword("unicode-bidi",
|
${helpers.single_keyword("unicode-bidi",
|
||||||
"normal embed isolate bidi-override isolate-override plaintext",
|
"normal embed isolate bidi-override isolate-override plaintext",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
|
need_clone="True",
|
||||||
spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi")}
|
spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi")}
|
||||||
|
|
||||||
<%helpers:longhand name="text-decoration-line"
|
<%helpers:longhand name="text-decoration-line"
|
||||||
|
|
|
@ -2384,8 +2384,6 @@ impl<'a, T: 'a> Deref for StyleStructRef<'a, T> {
|
||||||
/// actually cloning them, until we either build the style, or mutate the
|
/// actually cloning them, until we either build the style, or mutate the
|
||||||
/// inherited value.
|
/// inherited value.
|
||||||
pub struct StyleBuilder<'a> {
|
pub struct StyleBuilder<'a> {
|
||||||
/// The style we're inheriting from.
|
|
||||||
inherited_style: &'a ComputedValues,
|
|
||||||
/// The rule node representing the ordered list of rules matched for this
|
/// The rule node representing the ordered list of rules matched for this
|
||||||
/// node.
|
/// node.
|
||||||
rules: Option<StrongRuleNode>,
|
rules: Option<StrongRuleNode>,
|
||||||
|
@ -2396,6 +2394,8 @@ pub struct StyleBuilder<'a> {
|
||||||
pub writing_mode: WritingMode,
|
pub writing_mode: WritingMode,
|
||||||
/// The keyword behind the current font-size property, if any.
|
/// The keyword behind the current font-size property, if any.
|
||||||
pub font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
pub font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||||
|
/// Flags for the computed value.
|
||||||
|
pub flags: ComputedValueFlags,
|
||||||
/// The element's style if visited, only computed if there's a relevant link
|
/// The element's style if visited, only computed if there's a relevant link
|
||||||
/// for this element. A element's "relevant link" is the element being
|
/// for this element. A element's "relevant link" is the element being
|
||||||
/// matched if it is a link or the nearest ancestor link.
|
/// matched if it is a link or the nearest ancestor link.
|
||||||
|
@ -2414,14 +2414,15 @@ impl<'a> StyleBuilder<'a> {
|
||||||
custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
|
custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||||
|
flags: ComputedValueFlags,
|
||||||
visited_style: Option<Arc<ComputedValues>>,
|
visited_style: Option<Arc<ComputedValues>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
StyleBuilder {
|
StyleBuilder {
|
||||||
inherited_style,
|
|
||||||
rules,
|
rules,
|
||||||
custom_properties,
|
custom_properties,
|
||||||
writing_mode,
|
writing_mode,
|
||||||
font_size_keyword,
|
font_size_keyword,
|
||||||
|
flags,
|
||||||
visited_style,
|
visited_style,
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
% if style_struct.inherited:
|
% if style_struct.inherited:
|
||||||
|
@ -2452,6 +2453,7 @@ impl<'a> StyleBuilder<'a> {
|
||||||
parent.custom_properties(),
|
parent.custom_properties(),
|
||||||
parent.writing_mode,
|
parent.writing_mode,
|
||||||
parent.font_computation_data.font_size_keyword,
|
parent.font_computation_data.font_size_keyword,
|
||||||
|
parent.flags,
|
||||||
parent.clone_visited_style()
|
parent.clone_visited_style()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2484,6 +2486,12 @@ impl<'a> StyleBuilder<'a> {
|
||||||
-> Option<<&mut style_structs::${style_struct.name}> {
|
-> Option<<&mut style_structs::${style_struct.name}> {
|
||||||
self.${style_struct.ident}.get_if_mutated()
|
self.${style_struct.ident}.get_if_mutated()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset the current `${style_struct.name}` style to its default value.
|
||||||
|
pub fn reset_${style_struct.name_lower}(&mut self, default: &'a ComputedValues) {
|
||||||
|
self.${style_struct.ident} =
|
||||||
|
StyleStructRef::Borrowed(default.${style_struct.name_lower}_arc());
|
||||||
|
}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
/// Returns whether this computed style represents a floated object.
|
/// Returns whether this computed style represents a floated object.
|
||||||
|
@ -2515,11 +2523,10 @@ impl<'a> StyleBuilder<'a> {
|
||||||
|
|
||||||
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
|
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
|
||||||
pub fn build(self) -> ComputedValues {
|
pub fn build(self) -> ComputedValues {
|
||||||
let flags = ComputedValueFlags::compute(&self, &self.inherited_style);
|
|
||||||
ComputedValues::new(self.custom_properties,
|
ComputedValues::new(self.custom_properties,
|
||||||
self.writing_mode,
|
self.writing_mode,
|
||||||
self.font_size_keyword,
|
self.font_size_keyword,
|
||||||
flags,
|
self.flags,
|
||||||
self.rules,
|
self.rules,
|
||||||
self.visited_style,
|
self.visited_style,
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
|
@ -2564,7 +2571,7 @@ mod lazy_static_module {
|
||||||
% endfor
|
% endfor
|
||||||
custom_properties: None,
|
custom_properties: None,
|
||||||
writing_mode: WritingMode::empty(),
|
writing_mode: WritingMode::empty(),
|
||||||
flags: ComputedValueFlags::initial(),
|
flags: ComputedValueFlags::empty(),
|
||||||
font_computation_data: FontComputationData::default_values(),
|
font_computation_data: FontComputationData::default_values(),
|
||||||
rules: None,
|
rules: None,
|
||||||
visited_style: None,
|
visited_style: None,
|
||||||
|
@ -2596,8 +2603,8 @@ bitflags! {
|
||||||
/// present, non-inherited styles are reset to their initial values.
|
/// present, non-inherited styles are reset to their initial values.
|
||||||
const INHERIT_ALL = 0x01,
|
const INHERIT_ALL = 0x01,
|
||||||
|
|
||||||
/// Whether to skip any root element and flex/grid item display style
|
/// Whether to skip any display style fixup for root element, flex/grid
|
||||||
/// fixup.
|
/// item, and ruby descendants.
|
||||||
const SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP = 0x02,
|
const SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP = 0x02,
|
||||||
|
|
||||||
/// Whether to only cascade properties that are visited dependent.
|
/// Whether to only cascade properties that are visited dependent.
|
||||||
|
@ -2747,6 +2754,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
||||||
custom_properties,
|
custom_properties,
|
||||||
WritingMode::empty(),
|
WritingMode::empty(),
|
||||||
inherited_style.font_computation_data.font_size_keyword,
|
inherited_style.font_computation_data.font_size_keyword,
|
||||||
|
ComputedValueFlags::empty(),
|
||||||
visited_style,
|
visited_style,
|
||||||
),
|
),
|
||||||
font_metrics_provider: font_metrics_provider,
|
font_metrics_provider: font_metrics_provider,
|
||||||
|
@ -2983,7 +2991,8 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
||||||
|
|
||||||
{
|
{
|
||||||
StyleAdjuster::new(&mut style)
|
StyleAdjuster::new(&mut style)
|
||||||
.adjust(context.layout_parent_style, flags);
|
.adjust(context.layout_parent_style,
|
||||||
|
context.device.default_computed_values(), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! A struct to encapsulate all the style fixups a computed style needs in order
|
//! A struct to encapsulate all the style fixups and flags propagations
|
||||||
//! for it to adhere to the CSS spec.
|
//! a computed style needs in order for it to adhere to the CSS spec.
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use properties::{self, CascadeFlags, ComputedValues};
|
use properties::{self, CascadeFlags, ComputedValues};
|
||||||
|
@ -12,6 +12,8 @@ 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;
|
||||||
use properties::longhands::position::computed_value::T as position;
|
use properties::longhands::position::computed_value::T as position;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use properties::longhands::unicode_bidi::computed_value::T as unicode_bidi;
|
||||||
|
|
||||||
|
|
||||||
/// An unsized struct that implements all the adjustment methods.
|
/// An unsized struct that implements all the adjustment methods.
|
||||||
|
@ -312,6 +314,92 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
self.style.mutate_inheritedtext().set_text_align(text_align::start);
|
self.style.mutate_inheritedtext().set_text_align(text_align::start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the HAS_TEXT_DECORATION_LINES flag based on parent style.
|
||||||
|
fn adjust_for_text_decoration_lines(&mut self, layout_parent_style: &ComputedValues) {
|
||||||
|
use properties::computed_value_flags::HAS_TEXT_DECORATION_LINES;
|
||||||
|
if layout_parent_style.flags.contains(HAS_TEXT_DECORATION_LINES) ||
|
||||||
|
!self.style.get_text().clone_text_decoration_line().is_empty() {
|
||||||
|
self.style.flags.insert(HAS_TEXT_DECORATION_LINES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn should_suppress_linebreak(&self, layout_parent_style: &ComputedValues) -> bool {
|
||||||
|
use properties::computed_value_flags::SHOULD_SUPPRESS_LINEBREAK;
|
||||||
|
// Line break suppression should only be propagated to in-flow children.
|
||||||
|
if self.style.floated() || self.style.out_of_flow_positioned() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let parent_display = layout_parent_style.get_box().clone_display();
|
||||||
|
if layout_parent_style.flags.contains(SHOULD_SUPPRESS_LINEBREAK) {
|
||||||
|
// Line break suppression is propagated to any children of
|
||||||
|
// line participants.
|
||||||
|
if parent_display.is_line_participant() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match self.style.get_box().clone_display() {
|
||||||
|
// Ruby base and text are always non-breakable.
|
||||||
|
display::ruby_base | display::ruby_text => true,
|
||||||
|
// Ruby base container and text container are breakable.
|
||||||
|
// Note that, when certain HTML tags, e.g. form controls, have ruby
|
||||||
|
// level container display type, they could also escape from the
|
||||||
|
// line break suppression flag while they shouldn't. However, it is
|
||||||
|
// generally fine since they themselves are non-breakable.
|
||||||
|
display::ruby_base_container | display::ruby_text_container => false,
|
||||||
|
// Anything else is non-breakable if and only if its layout parent
|
||||||
|
// has a ruby display type, because any of the ruby boxes can be
|
||||||
|
// anonymous.
|
||||||
|
_ => parent_display.is_ruby_type(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Do ruby-related style adjustments, which include:
|
||||||
|
/// * propagate the line break suppression flag,
|
||||||
|
/// * inlinify block descendants,
|
||||||
|
/// * suppress border and padding for ruby level containers,
|
||||||
|
/// * correct unicode-bidi.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn adjust_for_ruby(&mut self,
|
||||||
|
layout_parent_style: &ComputedValues,
|
||||||
|
default_computed_values: &'b ComputedValues,
|
||||||
|
flags: CascadeFlags) {
|
||||||
|
use properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
||||||
|
use properties::computed_value_flags::SHOULD_SUPPRESS_LINEBREAK;
|
||||||
|
let self_display = self.style.get_box().clone_display();
|
||||||
|
// Check whether line break should be suppressed for this element.
|
||||||
|
if self.should_suppress_linebreak(layout_parent_style) {
|
||||||
|
self.style.flags.insert(SHOULD_SUPPRESS_LINEBREAK);
|
||||||
|
// Inlinify the display type if allowed.
|
||||||
|
if !flags.contains(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP) {
|
||||||
|
let inline_display = self_display.inlinify();
|
||||||
|
if self_display != inline_display {
|
||||||
|
self.style.mutate_box().set_display(inline_display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Suppress border and padding for ruby level containers.
|
||||||
|
// This is actually not part of the spec. It is currently unspecified
|
||||||
|
// how border and padding should be handled for ruby level container,
|
||||||
|
// and suppressing them here make it easier for layout to handle.
|
||||||
|
if self_display.is_ruby_level_container() {
|
||||||
|
self.style.reset_border(default_computed_values);
|
||||||
|
self.style.reset_padding(default_computed_values);
|
||||||
|
}
|
||||||
|
// Force bidi isolation on all internal ruby boxes and ruby container
|
||||||
|
// per spec https://drafts.csswg.org/css-ruby-1/#bidi
|
||||||
|
if self_display.is_ruby_type() {
|
||||||
|
let new_value = match self.style.get_text().clone_unicode_bidi() {
|
||||||
|
unicode_bidi::normal | unicode_bidi::embed => Some(unicode_bidi::isolate),
|
||||||
|
unicode_bidi::bidi_override => Some(unicode_bidi::isolate_override),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(new_value) = new_value {
|
||||||
|
self.style.mutate_text().set_unicode_bidi(new_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Adjusts the style to account for various fixups that don't fit naturally
|
/// Adjusts the style to account for various fixups that don't fit naturally
|
||||||
/// into the cascade.
|
/// into the cascade.
|
||||||
///
|
///
|
||||||
|
@ -319,6 +407,7 @@ 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,
|
||||||
|
_default_computed_values: &'b ComputedValues,
|
||||||
flags: CascadeFlags) {
|
flags: CascadeFlags) {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
|
@ -341,5 +430,11 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
self.adjust_for_border_width();
|
self.adjust_for_border_width();
|
||||||
self.adjust_for_outline();
|
self.adjust_for_outline();
|
||||||
self.adjust_for_writing_mode(layout_parent_style);
|
self.adjust_for_writing_mode(layout_parent_style);
|
||||||
|
self.adjust_for_text_decoration_lines(layout_parent_style);
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
{
|
||||||
|
self.adjust_for_ruby(layout_parent_style,
|
||||||
|
_default_computed_values, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ use style::invalidation::element::restyle_hints::{self, RestyleHint};
|
||||||
use style::media_queries::{MediaList, parse_media_query_list};
|
use style::media_queries::{MediaList, parse_media_query_list};
|
||||||
use style::parallel;
|
use style::parallel;
|
||||||
use style::parser::ParserContext;
|
use style::parser::ParserContext;
|
||||||
use style::properties::{CascadeFlags, ComputedValues, Importance, SourcePropertyDeclaration};
|
use style::properties::{ComputedValues, Importance, SourcePropertyDeclaration};
|
||||||
use style::properties::{LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, StyleBuilder};
|
use style::properties::{LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, StyleBuilder};
|
||||||
use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
||||||
use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue};
|
use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue};
|
||||||
|
@ -1502,7 +1502,6 @@ pub extern "C" fn Servo_DocumentRule_GetConditionText(rule: RawServoDocumentRule
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
||||||
pseudo_tag: *mut nsIAtom,
|
pseudo_tag: *mut nsIAtom,
|
||||||
skip_display_fixup: bool,
|
|
||||||
raw_data: RawServoStyleSetBorrowed)
|
raw_data: RawServoStyleSetBorrowed)
|
||||||
-> ServoComputedValuesStrong {
|
-> ServoComputedValuesStrong {
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
@ -1515,10 +1514,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
||||||
|
|
||||||
|
|
||||||
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
|
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
|
||||||
let mut cascade_flags = CascadeFlags::empty();
|
let cascade_flags = SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
||||||
if skip_display_fixup {
|
|
||||||
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
|
|
||||||
}
|
|
||||||
let metrics = get_metrics_provider_for_product();
|
let metrics = get_metrics_provider_for_product();
|
||||||
data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
|
data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
|
||||||
cascade_flags, &metrics)
|
cascade_flags, &metrics)
|
||||||
|
@ -1723,6 +1719,20 @@ pub extern "C" fn Servo_ComputedValues_GetVisitedStyle(values: ServoComputedValu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ServoComputedValuesBorrowed) -> u64 {
|
||||||
|
use style::properties::computed_value_flags::*;
|
||||||
|
let flags = ComputedValues::as_arc(&values).flags;
|
||||||
|
let mut result = 0;
|
||||||
|
if flags.contains(HAS_TEXT_DECORATION_LINES) {
|
||||||
|
result |= structs::NS_STYLE_HAS_TEXT_DECORATION_LINES as u64;
|
||||||
|
}
|
||||||
|
if flags.contains(SHOULD_SUPPRESS_LINEBREAK) {
|
||||||
|
result |= structs::NS_STYLE_SUPPRESS_LINEBREAK as u64;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(values: ServoComputedValuesBorrowed)
|
pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(values: ServoComputedValuesBorrowed)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue