mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Auto merge of #23727 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See each individual commit for details. <!-- 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/23727) <!-- Reviewable:end -->
This commit is contained in:
commit
3e88f63693
52 changed files with 654 additions and 1396 deletions
|
@ -182,7 +182,7 @@ impl<T> Arc<T> {
|
|||
// FIXME(emilio): Would be so amazing to have
|
||||
// std::intrinsics::type_name() around, so that we could also report
|
||||
// a real size.
|
||||
NS_LogCtor(ptr as *const _, b"ServoArc\0".as_ptr() as *const _, 8);
|
||||
NS_LogCtor(ptr as *mut _, b"ServoArc\0".as_ptr() as *const _, 8);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -314,11 +314,7 @@ impl<T: ?Sized> Arc<T> {
|
|||
fn record_drop(&self) {
|
||||
#[cfg(feature = "gecko_refcount_logging")]
|
||||
unsafe {
|
||||
NS_LogDtor(
|
||||
self.ptr() as *const _,
|
||||
b"ServoArc\0".as_ptr() as *const _,
|
||||
8,
|
||||
);
|
||||
NS_LogDtor(self.ptr() as *mut _, b"ServoArc\0".as_ptr() as *const _, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,12 +351,12 @@ impl<T: ?Sized> Arc<T> {
|
|||
#[cfg(feature = "gecko_refcount_logging")]
|
||||
extern "C" {
|
||||
fn NS_LogCtor(
|
||||
aPtr: *const std::os::raw::c_void,
|
||||
aPtr: *mut std::os::raw::c_void,
|
||||
aTypeName: *const std::os::raw::c_char,
|
||||
aSize: u32,
|
||||
);
|
||||
fn NS_LogDtor(
|
||||
aPtr: *const std::os::raw::c_void,
|
||||
aPtr: *mut std::os::raw::c_void,
|
||||
aTypeName: *const std::os::raw::c_char,
|
||||
aSize: u32,
|
||||
);
|
||||
|
@ -762,7 +758,7 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> {
|
|||
if !is_static {
|
||||
// FIXME(emilio): Would be so amazing to have
|
||||
// std::intrinsics::type_name() around.
|
||||
NS_LogCtor(ptr as *const _, b"ServoArc\0".as_ptr() as *const _, 8)
|
||||
NS_LogCtor(ptr as *mut _, b"ServoArc\0".as_ptr() as *const _, 8)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -416,13 +416,13 @@ macro_rules! is_descriptor_enabled {
|
|||
("font-display") => {
|
||||
unsafe {
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
mozilla::StaticPrefs_sVarCache_layout_css_font_display_enabled
|
||||
mozilla::StaticPrefs::sVarCache_layout_css_font_display_enabled
|
||||
}
|
||||
};
|
||||
("font-variation-settings") => {
|
||||
unsafe {
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
mozilla::StaticPrefs_sVarCache_layout_css_font_variations_enabled != 0
|
||||
mozilla::StaticPrefs::sVarCache_layout_css_font_variations_enabled != 0
|
||||
}
|
||||
};
|
||||
($name:tt) => {
|
||||
|
|
|
@ -10,57 +10,15 @@
|
|||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||
use crate::gecko_bindings::bindings;
|
||||
use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue, Matrix4x4Components};
|
||||
use crate::gecko_bindings::structs::{self, Matrix4x4Components};
|
||||
use crate::gecko_bindings::structs::{nsStyleImage, nsresult};
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
||||
use crate::stylesheets::RulesMutateError;
|
||||
use crate::values::computed::transform::Matrix3D;
|
||||
use crate::values::computed::url::ComputedImageUrl;
|
||||
use crate::values::computed::{Angle, Gradient, Image};
|
||||
use crate::values::computed::{Integer, LengthPercentage};
|
||||
use crate::values::computed::{Length, Percentage, TextAlign};
|
||||
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
||||
use crate::values::computed::{Gradient, Image, TextAlign};
|
||||
use crate::values::generics::image::GenericImage;
|
||||
use crate::values::generics::rect::Rect;
|
||||
use crate::Zero;
|
||||
use app_units::Au;
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
|
||||
impl From<LengthPercentage> for nsStyleCoord_CalcValue {
|
||||
fn from(other: LengthPercentage) -> nsStyleCoord_CalcValue {
|
||||
debug_assert!(
|
||||
other.was_calc || !other.has_percentage || other.unclamped_length() == Length::zero()
|
||||
);
|
||||
nsStyleCoord_CalcValue {
|
||||
mLength: other.unclamped_length().to_i32_au(),
|
||||
mPercent: other.percentage(),
|
||||
mHasPercent: other.has_percentage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nsStyleCoord_CalcValue> for LengthPercentage {
|
||||
fn from(other: nsStyleCoord_CalcValue) -> LengthPercentage {
|
||||
let percentage = if other.mHasPercent {
|
||||
Some(Percentage(other.mPercent))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Self::with_clamping_mode(
|
||||
Au(other.mLength).into(),
|
||||
percentage,
|
||||
AllowedNumericType::All,
|
||||
/* was_calc = */ true,
|
||||
)
|
||||
}
|
||||
}
|
||||
impl From<Angle> for CoordDataValue {
|
||||
fn from(reference: Angle) -> Self {
|
||||
CoordDataValue::Degree(reference.degrees())
|
||||
}
|
||||
}
|
||||
|
||||
impl nsStyleImage {
|
||||
/// Set a given Servo `Image` value into this `nsStyleImage`.
|
||||
|
@ -77,18 +35,12 @@ impl nsStyleImage {
|
|||
|
||||
// Set CropRect
|
||||
let ref mut rect = *self.mCropRect.mPtr;
|
||||
image_rect
|
||||
.top
|
||||
.to_gecko_style_coord(&mut rect.data_at_mut(0));
|
||||
image_rect
|
||||
.right
|
||||
.to_gecko_style_coord(&mut rect.data_at_mut(1));
|
||||
image_rect
|
||||
.bottom
|
||||
.to_gecko_style_coord(&mut rect.data_at_mut(2));
|
||||
image_rect
|
||||
.left
|
||||
.to_gecko_style_coord(&mut rect.data_at_mut(3));
|
||||
*rect = Rect(
|
||||
image_rect.top,
|
||||
image_rect.right,
|
||||
image_rect.bottom,
|
||||
image_rect.left,
|
||||
);
|
||||
}
|
||||
},
|
||||
GenericImage::Element(ref element) => unsafe {
|
||||
|
@ -106,7 +58,7 @@ impl nsStyleImage {
|
|||
/// Converts into Image.
|
||||
pub unsafe fn into_image(self: &nsStyleImage) -> Option<Image> {
|
||||
use crate::gecko_bindings::structs::nsStyleImageType;
|
||||
use crate::values::computed::{MozImageRect, NumberOrPercentage};
|
||||
use crate::values::computed::MozImageRect;
|
||||
|
||||
match self.mType {
|
||||
nsStyleImageType::eStyleImageType_Null => None,
|
||||
|
@ -115,30 +67,14 @@ impl nsStyleImage {
|
|||
if self.mCropRect.mPtr.is_null() {
|
||||
Some(GenericImage::Url(url))
|
||||
} else {
|
||||
let ref rect = *self.mCropRect.mPtr;
|
||||
match (
|
||||
NumberOrPercentage::from_gecko_style_coord(&rect.data_at(0)),
|
||||
NumberOrPercentage::from_gecko_style_coord(&rect.data_at(1)),
|
||||
NumberOrPercentage::from_gecko_style_coord(&rect.data_at(2)),
|
||||
NumberOrPercentage::from_gecko_style_coord(&rect.data_at(3)),
|
||||
) {
|
||||
(Some(top), Some(right), Some(bottom), Some(left)) => {
|
||||
Some(GenericImage::Rect(Box::new(MozImageRect {
|
||||
url,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
left,
|
||||
})))
|
||||
},
|
||||
_ => {
|
||||
debug_assert!(
|
||||
false,
|
||||
"mCropRect could not convert to NumberOrPercentage"
|
||||
);
|
||||
None
|
||||
},
|
||||
}
|
||||
let rect = &*self.mCropRect.mPtr;
|
||||
Some(GenericImage::Rect(Box::new(MozImageRect {
|
||||
url,
|
||||
top: rect.0,
|
||||
right: rect.1,
|
||||
bottom: rect.2,
|
||||
left: rect.3,
|
||||
})))
|
||||
}
|
||||
},
|
||||
nsStyleImageType::eStyleImageType_Gradient => {
|
||||
|
@ -331,98 +267,6 @@ impl From<RulesMutateError> for nsresult {
|
|||
}
|
||||
}
|
||||
|
||||
impl TrackSize<LengthPercentage> {
|
||||
/// Return TrackSize from given two nsStyleCoord
|
||||
pub fn from_gecko_style_coords<T: CoordData>(gecko_min: &T, gecko_max: &T) -> Self {
|
||||
use crate::gecko_bindings::structs::root::nsStyleUnit;
|
||||
use crate::values::generics::grid::TrackBreadth;
|
||||
|
||||
if gecko_min.unit() == nsStyleUnit::eStyleUnit_None {
|
||||
debug_assert!(
|
||||
gecko_max.unit() == nsStyleUnit::eStyleUnit_Coord ||
|
||||
gecko_max.unit() == nsStyleUnit::eStyleUnit_Percent ||
|
||||
gecko_max.unit() == nsStyleUnit::eStyleUnit_Calc
|
||||
);
|
||||
return TrackSize::FitContent(
|
||||
LengthPercentage::from_gecko_style_coord(gecko_max)
|
||||
.expect("gecko_max could not convert to LengthPercentage"),
|
||||
);
|
||||
}
|
||||
|
||||
let min = TrackBreadth::from_gecko_style_coord(gecko_min)
|
||||
.expect("gecko_min could not convert to TrackBreadth");
|
||||
let max = TrackBreadth::from_gecko_style_coord(gecko_max)
|
||||
.expect("gecko_max could not convert to TrackBreadth");
|
||||
if min == max {
|
||||
TrackSize::Breadth(max)
|
||||
} else {
|
||||
TrackSize::Minmax(min, max)
|
||||
}
|
||||
}
|
||||
|
||||
/// Save TrackSize to given gecko fields.
|
||||
pub fn to_gecko_style_coords<T: CoordDataMut>(&self, gecko_min: &mut T, gecko_max: &mut T) {
|
||||
match *self {
|
||||
TrackSize::FitContent(ref lop) => {
|
||||
// Gecko sets min value to None and max value to the actual value in fit-content
|
||||
// https://searchfox.org/mozilla-central/rev/c05d9d61188d32b8/layout/style/nsRuleNode.cpp#7910
|
||||
gecko_min.set_value(CoordDataValue::None);
|
||||
lop.to_gecko_style_coord(gecko_max);
|
||||
},
|
||||
TrackSize::Breadth(ref breadth) => {
|
||||
// Set the value to both fields if there's one breadth value
|
||||
// https://searchfox.org/mozilla-central/rev/c05d9d61188d32b8/layout/style/nsRuleNode.cpp#7919
|
||||
breadth.to_gecko_style_coord(gecko_min);
|
||||
breadth.to_gecko_style_coord(gecko_max);
|
||||
},
|
||||
TrackSize::Minmax(ref min, ref max) => {
|
||||
min.to_gecko_style_coord(gecko_min);
|
||||
max.to_gecko_style_coord(gecko_max);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TrackListValue<LengthPercentage, Integer> {
|
||||
/// Return TrackSize from given two nsStyleCoord
|
||||
pub fn from_gecko_style_coords<T: CoordData>(gecko_min: &T, gecko_max: &T) -> Self {
|
||||
TrackListValue::TrackSize(TrackSize::from_gecko_style_coords(gecko_min, gecko_max))
|
||||
}
|
||||
|
||||
/// Save TrackSize to given gecko fields.
|
||||
pub fn to_gecko_style_coords<T: CoordDataMut>(&self, gecko_min: &mut T, gecko_max: &mut T) {
|
||||
match *self {
|
||||
TrackListValue::TrackSize(ref size) => size.to_gecko_style_coords(gecko_min, gecko_max),
|
||||
_ => unreachable!("Should only transform from track-size computed values"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Rect<T>
|
||||
where
|
||||
T: GeckoStyleCoordConvertible,
|
||||
{
|
||||
/// Convert this generic Rect to given Gecko fields.
|
||||
pub fn to_gecko_rect(&self, sides: &mut crate::gecko_bindings::structs::nsStyleSides) {
|
||||
self.0.to_gecko_style_coord(&mut sides.data_at_mut(0));
|
||||
self.1.to_gecko_style_coord(&mut sides.data_at_mut(1));
|
||||
self.2.to_gecko_style_coord(&mut sides.data_at_mut(2));
|
||||
self.3.to_gecko_style_coord(&mut sides.data_at_mut(3));
|
||||
}
|
||||
|
||||
/// Convert from given Gecko data to generic Rect.
|
||||
pub fn from_gecko_rect(
|
||||
sides: &crate::gecko_bindings::structs::nsStyleSides,
|
||||
) -> Option<crate::values::generics::rect::Rect<T>> {
|
||||
Some(Rect::new(
|
||||
T::from_gecko_style_coord(&sides.data_at(0)).expect("coord[0] cound not convert"),
|
||||
T::from_gecko_style_coord(&sides.data_at(1)).expect("coord[1] cound not convert"),
|
||||
T::from_gecko_style_coord(&sides.data_at(2)).expect("coord[2] cound not convert"),
|
||||
T::from_gecko_style_coord(&sides.data_at(3)).expect("coord[3] cound not convert"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl TextAlign {
|
||||
/// Obtain a specified value from a Gecko keyword value
|
||||
///
|
||||
|
|
|
@ -271,7 +271,7 @@ impl Device {
|
|||
return true;
|
||||
}
|
||||
let document_color_use =
|
||||
unsafe { structs::StaticPrefs_sVarCache_browser_display_document_color_use };
|
||||
unsafe { structs::StaticPrefs::sVarCache_browser_display_document_color_use };
|
||||
let prefs = self.pref_sheet_prefs();
|
||||
match document_color_use {
|
||||
1 => true,
|
||||
|
|
|
@ -182,12 +182,18 @@ impl PseudoElement {
|
|||
/// Property flag that properties must have to apply to this pseudo-element.
|
||||
#[inline]
|
||||
pub fn property_restriction(&self) -> Option<PropertyFlags> {
|
||||
match *self {
|
||||
PseudoElement::FirstLetter => Some(PropertyFlags::APPLIES_TO_FIRST_LETTER),
|
||||
PseudoElement::FirstLine => Some(PropertyFlags::APPLIES_TO_FIRST_LINE),
|
||||
PseudoElement::Placeholder => Some(PropertyFlags::APPLIES_TO_PLACEHOLDER),
|
||||
_ => None,
|
||||
}
|
||||
Some(match *self {
|
||||
PseudoElement::FirstLetter => PropertyFlags::APPLIES_TO_FIRST_LETTER,
|
||||
PseudoElement::FirstLine => PropertyFlags::APPLIES_TO_FIRST_LINE,
|
||||
PseudoElement::Placeholder => PropertyFlags::APPLIES_TO_PLACEHOLDER,
|
||||
PseudoElement::Cue => PropertyFlags::APPLIES_TO_CUE,
|
||||
PseudoElement::Marker
|
||||
if unsafe { structs::StaticPrefs::sVarCache_layout_css_marker_restricted } =>
|
||||
{
|
||||
PropertyFlags::APPLIES_TO_MARKER
|
||||
},
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether this pseudo-element should actually exist if it has
|
||||
|
|
|
@ -112,7 +112,7 @@ impl PseudoElement {
|
|||
% for pseudo in PSEUDOS:
|
||||
${pseudo_element_variant(pseudo)} =>
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
if unsafe { structs::StaticPrefs_sVarCache_layout_css_xul_tree_pseudos_content_enabled } {
|
||||
if unsafe { structs::StaticPrefs::sVarCache_layout_css_xul_tree_pseudos_content_enabled } {
|
||||
0
|
||||
} else {
|
||||
structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME
|
||||
|
@ -210,7 +210,7 @@ impl PseudoElement {
|
|||
return PseudoElement::tree_pseudo_element(name, Box::new([]))
|
||||
}
|
||||
if unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_unknown_webkit_pseudo_element
|
||||
structs::StaticPrefs::sVarCache_layout_css_unknown_webkit_pseudo_element
|
||||
} {
|
||||
const WEBKIT_PREFIX: &str = "-webkit-";
|
||||
if starts_with_ignore_ascii_case(name, WEBKIT_PREFIX) {
|
||||
|
|
|
@ -175,7 +175,7 @@ impl NonTSPseudoClass {
|
|||
// For pseudo-classes with pref, the availability in content
|
||||
// depends on the pref.
|
||||
NonTSPseudoClass::Fullscreen => unsafe {
|
||||
mozilla::StaticPrefs_sVarCache_full_screen_api_unprefix_enabled
|
||||
mozilla::StaticPrefs::sVarCache_full_screen_api_unprefix_enabled
|
||||
},
|
||||
// Otherwise, a pseudo-class is enabled in content when it
|
||||
// doesn't have any enabled flag.
|
||||
|
@ -355,7 +355,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
|||
#[inline]
|
||||
fn parse_part(&self) -> bool {
|
||||
self.chrome_rules_enabled() ||
|
||||
unsafe { structs::StaticPrefs_sVarCache_layout_css_shadow_parts_enabled }
|
||||
unsafe { structs::StaticPrefs::sVarCache_layout_css_shadow_parts_enabled }
|
||||
}
|
||||
|
||||
fn parse_non_ts_pseudo_class(
|
||||
|
|
|
@ -7,215 +7,15 @@
|
|||
//! Different kind of helpers to interact with Gecko values.
|
||||
|
||||
use crate::counter_style::{Symbol, Symbols};
|
||||
use crate::gecko_bindings::structs::StyleGridTrackBreadth;
|
||||
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
||||
use crate::values::computed::{Angle, Length, LengthPercentage};
|
||||
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
|
||||
use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
|
||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
||||
use crate::values::generics::{CounterStyleOrNone, NonNegative};
|
||||
use crate::gecko_bindings::structs::CounterStylePtr;
|
||||
use crate::values::generics::CounterStyleOrNone;
|
||||
use crate::values::Either;
|
||||
use crate::{Atom, Zero};
|
||||
use crate::Atom;
|
||||
use app_units::Au;
|
||||
use cssparser::RGBA;
|
||||
use nsstring::{nsACString, nsCStr};
|
||||
use std::cmp::max;
|
||||
|
||||
/// A trait that defines an interface to convert from and to `nsStyleCoord`s.
|
||||
///
|
||||
/// TODO(emilio): Almost everything that is in this file should be somehow
|
||||
/// switched to cbindgen.
|
||||
pub trait GeckoStyleCoordConvertible: Sized {
|
||||
/// Convert this to a `nsStyleCoord`.
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T);
|
||||
/// Given a `nsStyleCoord`, try to get a value of this type..
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl nsStyleCoord {
|
||||
#[inline]
|
||||
/// Set this `nsStyleCoord` value to `val`.
|
||||
pub fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
|
||||
val.to_gecko_style_coord(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner> GeckoStyleCoordConvertible for NonNegative<Inner>
|
||||
where
|
||||
Inner: GeckoStyleCoordConvertible,
|
||||
{
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
self.0.to_gecko_style_coord(coord)
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
Some(NonNegative(Inner::from_gecko_style_coord(coord)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for Number {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::Factor(*self));
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Factor(f) => Some(f),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for Percentage {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::Percent(self.0));
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Percent(p) => Some(Percentage(p)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for NumberOrPercentage {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
NumberOrPercentage::Number(ref n) => n.to_gecko_style_coord(coord),
|
||||
NumberOrPercentage::Percentage(ref p) => p.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Factor(f) => Some(NumberOrPercentage::Number(f)),
|
||||
CoordDataValue::Percent(p) => Some(NumberOrPercentage::Percentage(Percentage(p))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for LengthPercentage {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
if self.was_calc {
|
||||
return coord.set_value(CoordDataValue::Calc((*self).into()));
|
||||
}
|
||||
debug_assert!(!self.has_percentage || self.unclamped_length() == Length::zero());
|
||||
if self.has_percentage {
|
||||
return coord.set_value(CoordDataValue::Percent(self.percentage()));
|
||||
}
|
||||
coord.set_value(CoordDataValue::Coord(self.unclamped_length().to_i32_au()))
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Coord(coord) => Some(LengthPercentage::new(Au(coord).into(), None)),
|
||||
CoordDataValue::Percent(p) => {
|
||||
Some(LengthPercentage::new(Au(0).into(), Some(Percentage(p))))
|
||||
},
|
||||
CoordDataValue::Calc(calc) => Some(calc.into()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for Length {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::Coord(self.to_i32_au()));
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Coord(coord) => Some(Au(coord).into()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<LengthPercentage> GeckoStyleCoordConvertible for LengthPercentageOrAuto<LengthPercentage>
|
||||
where
|
||||
LengthPercentage: GeckoStyleCoordConvertible,
|
||||
{
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
LengthPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto),
|
||||
LengthPercentageOrAuto::LengthPercentage(ref lp) => lp.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Auto => Some(LengthPercentageOrAuto::Auto),
|
||||
_ => LengthPercentage::from_gecko_style_coord(coord)
|
||||
.map(LengthPercentageOrAuto::LengthPercentage),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<L> {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
TrackBreadth::Breadth(ref lp) => lp.to_gecko_style_coord(coord),
|
||||
TrackBreadth::Fr(fr) => coord.set_value(CoordDataValue::FlexFraction(fr)),
|
||||
TrackBreadth::Keyword(TrackKeyword::Auto) => coord.set_value(CoordDataValue::Auto),
|
||||
TrackBreadth::Keyword(TrackKeyword::MinContent) => coord.set_value(
|
||||
CoordDataValue::Enumerated(StyleGridTrackBreadth::MinContent as u32),
|
||||
),
|
||||
TrackBreadth::Keyword(TrackKeyword::MaxContent) => coord.set_value(
|
||||
CoordDataValue::Enumerated(StyleGridTrackBreadth::MaxContent as u32),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
L::from_gecko_style_coord(coord)
|
||||
.map(TrackBreadth::Breadth)
|
||||
.or_else(|| match coord.as_value() {
|
||||
CoordDataValue::Enumerated(v) => {
|
||||
if v == StyleGridTrackBreadth::MinContent as u32 {
|
||||
Some(TrackBreadth::Keyword(TrackKeyword::MinContent))
|
||||
} else if v == StyleGridTrackBreadth::MaxContent as u32 {
|
||||
Some(TrackBreadth::Keyword(TrackKeyword::MaxContent))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
CoordDataValue::FlexFraction(fr) => Some(TrackBreadth::Fr(fr)),
|
||||
CoordDataValue::Auto => Some(TrackBreadth::Keyword(TrackKeyword::Auto)),
|
||||
_ => L::from_gecko_style_coord(coord).map(TrackBreadth::Breadth),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
|
||||
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
|
||||
if let Some(ref me) = *self {
|
||||
me.to_gecko_style_coord(coord);
|
||||
} else {
|
||||
coord.set_value(CoordDataValue::None);
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<U: CoordData>(coord: &U) -> Option<Self> {
|
||||
Some(T::from_gecko_style_coord(coord))
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for Angle {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::from(*self));
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Degree(val) => Some(Angle::from_degrees(val)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a given RGBA value to `nscolor`.
|
||||
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
||||
((rgba.alpha as u32) << 24) |
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
mod ns_com_ptr;
|
||||
mod ns_compatibility;
|
||||
mod ns_style_auto_array;
|
||||
pub mod ns_style_coord;
|
||||
mod ns_t_array;
|
||||
pub mod origin_flags;
|
||||
pub mod ownership;
|
||||
|
|
|
@ -1,369 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! Rust helpers for Gecko's `nsStyleCoord`.
|
||||
|
||||
use crate::gecko_bindings::bindings;
|
||||
use crate::gecko_bindings::structs::nsStyleSides;
|
||||
use crate::gecko_bindings::structs::{nsStyleCoord, nsStyleCoord_Calc, nsStyleCoord_CalcValue};
|
||||
use crate::gecko_bindings::structs::{nsStyleUnion, nsStyleUnit, nscoord};
|
||||
use std::mem;
|
||||
|
||||
impl nsStyleCoord {
|
||||
#[inline]
|
||||
/// Get a `null` nsStyleCoord.
|
||||
pub fn null() -> Self {
|
||||
// Can't construct directly because it has private fields
|
||||
let mut coord: Self = unsafe { mem::zeroed() };
|
||||
coord.leaky_set_null();
|
||||
coord
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl CoordData for nsStyleCoord {
|
||||
#[inline]
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
unsafe { *self.get_mUnit() }
|
||||
}
|
||||
#[inline]
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
unsafe { *self.get_mValue() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl CoordDataMut for nsStyleCoord {
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
||||
let unit = self.get_mUnit_mut() as *mut _;
|
||||
let value = self.get_mValue_mut() as *mut _;
|
||||
(&mut *unit, &mut *value)
|
||||
}
|
||||
}
|
||||
|
||||
impl nsStyleCoord_CalcValue {
|
||||
/// Create an "empty" CalcValue (whose value is `0`).
|
||||
pub fn new() -> Self {
|
||||
nsStyleCoord_CalcValue {
|
||||
mLength: 0,
|
||||
mPercent: 0.0,
|
||||
mHasPercent: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for nsStyleCoord_CalcValue {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.mLength == other.mLength &&
|
||||
self.mPercent == other.mPercent &&
|
||||
self.mHasPercent == other.mHasPercent
|
||||
}
|
||||
}
|
||||
|
||||
impl nsStyleSides {
|
||||
/// Immutably get the `nsStyleCoord`-like object representing the side at
|
||||
/// index `index`.
|
||||
#[inline]
|
||||
pub fn data_at(&self, index: usize) -> SidesData {
|
||||
SidesData {
|
||||
sides: self,
|
||||
index: index,
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutably get the `nsStyleCoord`-like object representing the side at
|
||||
/// index `index`.
|
||||
#[inline]
|
||||
pub fn data_at_mut(&mut self, index: usize) -> SidesDataMut {
|
||||
SidesDataMut {
|
||||
sides: self,
|
||||
index: index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A `nsStyleCoord`-like object on top of an immutable reference to
|
||||
/// `nsStyleSides`.
|
||||
pub struct SidesData<'a> {
|
||||
sides: &'a nsStyleSides,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
/// A `nsStyleCoord`-like object on top of an mutable reference to
|
||||
/// `nsStyleSides`.
|
||||
pub struct SidesDataMut<'a> {
|
||||
sides: &'a mut nsStyleSides,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
unsafe impl<'a> CoordData for SidesData<'a> {
|
||||
#[inline]
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
unsafe { self.sides.get_mUnits()[self.index] }
|
||||
}
|
||||
#[inline]
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
unsafe { self.sides.get_mValues()[self.index] }
|
||||
}
|
||||
}
|
||||
unsafe impl<'a> CoordData for SidesDataMut<'a> {
|
||||
#[inline]
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
unsafe { self.sides.get_mUnits()[self.index] }
|
||||
}
|
||||
#[inline]
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
unsafe { self.sides.get_mValues()[self.index] }
|
||||
}
|
||||
}
|
||||
unsafe impl<'a> CoordDataMut for SidesDataMut<'a> {
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
||||
let unit = &mut self.sides.get_mUnits_mut()[self.index] as *mut _;
|
||||
let value = &mut self.sides.get_mValues_mut()[self.index] as *mut _;
|
||||
(&mut *unit, &mut *value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Enum representing the tagged union that is CoordData.
|
||||
///
|
||||
/// In release mode this should never actually exist in the code, and will be
|
||||
/// optimized out by threading matches and inlining.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum CoordDataValue {
|
||||
/// eStyleUnit_Null
|
||||
Null,
|
||||
/// eStyleUnit_Normal
|
||||
Normal,
|
||||
/// eStyleUnit_Auto
|
||||
Auto,
|
||||
/// eStyleUnit_None
|
||||
None,
|
||||
/// eStyleUnit_Percent
|
||||
Percent(f32),
|
||||
/// eStyleUnit_Factor
|
||||
Factor(f32),
|
||||
/// eStyleUnit_Degree
|
||||
Degree(f32),
|
||||
/// eStyleUnit_FlexFraction
|
||||
FlexFraction(f32),
|
||||
/// eStyleUnit_Coord
|
||||
Coord(nscoord),
|
||||
/// eStyleUnit_Integer
|
||||
Integer(i32),
|
||||
/// eStyleUnit_Enumerated
|
||||
Enumerated(u32),
|
||||
/// eStyleUnit_Calc
|
||||
Calc(nsStyleCoord_CalcValue),
|
||||
}
|
||||
|
||||
/// A trait to abstract on top of a mutable `nsStyleCoord`-like object.
|
||||
pub unsafe trait CoordDataMut: CoordData {
|
||||
/// Get mutably the unit and the union.
|
||||
///
|
||||
/// This is unsafe since it's possible to modify the unit without changing
|
||||
/// the union.
|
||||
///
|
||||
/// NB: This can't be two methods since we can't mutably borrow twice
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion);
|
||||
|
||||
/// Clean up any resources used by the union.
|
||||
///
|
||||
/// Currently, this only happens if the nsStyleUnit is a Calc.
|
||||
#[inline]
|
||||
fn reset(&mut self) {
|
||||
unsafe {
|
||||
if self.unit() == nsStyleUnit::eStyleUnit_Calc {
|
||||
let (unit, union) = self.values_mut();
|
||||
bindings::Gecko_ResetStyleCoord(unit, union);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Copies the unit and value from another `CoordData` type.
|
||||
fn copy_from<T: CoordData>(&mut self, other: &T) {
|
||||
unsafe {
|
||||
self.reset();
|
||||
self.copy_from_unchecked(other);
|
||||
self.addref_if_calc();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Moves the unit and value from another `CoordData` type.
|
||||
fn move_from<T: CoordData>(&mut self, other: T) {
|
||||
unsafe {
|
||||
self.reset();
|
||||
self.copy_from_unchecked(&other);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Copies the unit and value from another `CoordData` type without checking
|
||||
/// the type of the value (so refcounted values like calc may leak).
|
||||
unsafe fn copy_from_unchecked<T: CoordData>(&mut self, other: &T) {
|
||||
let (unit, union) = self.values_mut();
|
||||
*unit = other.unit();
|
||||
*union = other.union();
|
||||
}
|
||||
|
||||
/// Useful for initializing uninits, given that `set_value` may segfault on
|
||||
/// uninits.
|
||||
fn leaky_set_null(&mut self) {
|
||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
||||
unsafe {
|
||||
let (unit, union) = self.values_mut();
|
||||
*unit = eStyleUnit_Null;
|
||||
*union.mInt.as_mut() = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// Sets the inner value.
|
||||
fn set_value(&mut self, value: CoordDataValue) {
|
||||
use self::CoordDataValue::*;
|
||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
||||
self.reset();
|
||||
unsafe {
|
||||
let (unit, union) = self.values_mut();
|
||||
match value {
|
||||
Null => {
|
||||
*unit = eStyleUnit_Null;
|
||||
*union.mInt.as_mut() = 0;
|
||||
},
|
||||
Normal => {
|
||||
*unit = eStyleUnit_Normal;
|
||||
*union.mInt.as_mut() = 0;
|
||||
},
|
||||
Auto => {
|
||||
*unit = eStyleUnit_Auto;
|
||||
*union.mInt.as_mut() = 0;
|
||||
},
|
||||
None => {
|
||||
*unit = eStyleUnit_None;
|
||||
*union.mInt.as_mut() = 0;
|
||||
},
|
||||
Percent(f) => {
|
||||
*unit = eStyleUnit_Percent;
|
||||
*union.mFloat.as_mut() = f;
|
||||
},
|
||||
Factor(f) => {
|
||||
*unit = eStyleUnit_Factor;
|
||||
*union.mFloat.as_mut() = f;
|
||||
},
|
||||
Degree(f) => {
|
||||
*unit = eStyleUnit_Degree;
|
||||
*union.mFloat.as_mut() = f;
|
||||
},
|
||||
FlexFraction(f) => {
|
||||
*unit = eStyleUnit_FlexFraction;
|
||||
*union.mFloat.as_mut() = f;
|
||||
},
|
||||
Coord(coord) => {
|
||||
*unit = eStyleUnit_Coord;
|
||||
*union.mInt.as_mut() = coord;
|
||||
},
|
||||
Integer(i) => {
|
||||
*unit = eStyleUnit_Integer;
|
||||
*union.mInt.as_mut() = i;
|
||||
},
|
||||
Enumerated(i) => {
|
||||
*unit = eStyleUnit_Enumerated;
|
||||
*union.mInt.as_mut() = i as i32;
|
||||
},
|
||||
Calc(calc) => {
|
||||
// Gecko_SetStyleCoordCalcValue changes the unit internally
|
||||
bindings::Gecko_SetStyleCoordCalcValue(unit, union, calc);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Gets the `Calc` value mutably, asserts in debug builds if the unit is
|
||||
/// not `Calc`.
|
||||
unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
|
||||
debug_assert_eq!(self.unit(), nsStyleUnit::eStyleUnit_Calc);
|
||||
&mut *(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Does what it promises, if the unit is `calc`, it bumps the reference
|
||||
/// count _of the calc expression_.
|
||||
fn addref_if_calc(&mut self) {
|
||||
unsafe {
|
||||
if self.unit() == nsStyleUnit::eStyleUnit_Calc {
|
||||
bindings::Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A trait to abstract on top of a `nsStyleCoord`-like object.
|
||||
pub unsafe trait CoordData {
|
||||
/// Get the unit of this object.
|
||||
fn unit(&self) -> nsStyleUnit;
|
||||
/// Get the `nsStyleUnion` for this object.
|
||||
fn union(&self) -> nsStyleUnion;
|
||||
|
||||
#[inline(always)]
|
||||
/// Get the appropriate value for this object.
|
||||
fn as_value(&self) -> CoordDataValue {
|
||||
use self::CoordDataValue::*;
|
||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
||||
unsafe {
|
||||
match self.unit() {
|
||||
eStyleUnit_Null => Null,
|
||||
eStyleUnit_Normal => Normal,
|
||||
eStyleUnit_Auto => Auto,
|
||||
eStyleUnit_None => None,
|
||||
eStyleUnit_Percent => Percent(self.get_float()),
|
||||
eStyleUnit_Factor => Factor(self.get_float()),
|
||||
eStyleUnit_Degree => Degree(self.get_float()),
|
||||
eStyleUnit_FlexFraction => FlexFraction(self.get_float()),
|
||||
eStyleUnit_Coord => Coord(self.get_integer()),
|
||||
eStyleUnit_Integer => Integer(self.get_integer()),
|
||||
eStyleUnit_Enumerated => Enumerated(self.get_integer() as u32),
|
||||
eStyleUnit_Calc => Calc(self.get_calc_value()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend inner value is a float; obtain it.
|
||||
unsafe fn get_float(&self) -> f32 {
|
||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
||||
debug_assert!(
|
||||
self.unit() == eStyleUnit_Percent ||
|
||||
self.unit() == eStyleUnit_Factor ||
|
||||
self.unit() == eStyleUnit_Degree ||
|
||||
self.unit() == eStyleUnit_FlexFraction
|
||||
);
|
||||
*self.union().mFloat.as_ref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend inner value is an int; obtain it.
|
||||
unsafe fn get_integer(&self) -> i32 {
|
||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
||||
debug_assert!(
|
||||
self.unit() == eStyleUnit_Coord ||
|
||||
self.unit() == eStyleUnit_Integer ||
|
||||
self.unit() == eStyleUnit_Enumerated
|
||||
);
|
||||
*self.union().mInt.as_ref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend inner value is a calc; obtain it.
|
||||
/// Ensure that the unit is Calc before calling this.
|
||||
unsafe fn get_calc_value(&self) -> nsStyleCoord_CalcValue {
|
||||
debug_assert_eq!(self.unit(), nsStyleUnit::eStyleUnit_Calc);
|
||||
(*self.as_calc())._base
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend the inner value is a calc expression, and obtain it.
|
||||
unsafe fn as_calc(&self) -> &nsStyleCoord_Calc {
|
||||
debug_assert_eq!(self.unit(), nsStyleUnit::eStyleUnit_Calc);
|
||||
&*(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)
|
||||
}
|
||||
}
|
|
@ -503,30 +503,32 @@ trait PrivateMatchMethods: TElement {
|
|||
let old_display = old_values.get_box().clone_display();
|
||||
let new_display = new_values.get_box().clone_display();
|
||||
|
||||
// If we used to be a display: none element, and no longer are,
|
||||
// our children need to be restyled because they're unstyled.
|
||||
//
|
||||
// NOTE(emilio): Gecko has the special-case of -moz-binding, but
|
||||
// that gets handled on the frame constructor when processing
|
||||
// the reframe, so no need to handle that here.
|
||||
if old_display == Display::None && old_display != new_display {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
}
|
||||
|
||||
// Blockification of children may depend on our display value,
|
||||
// so we need to actually do the recascade. We could potentially
|
||||
// do better, but it doesn't seem worth it.
|
||||
if old_display.is_item_container() != new_display.is_item_container() {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
}
|
||||
|
||||
// Line break suppression may also be affected if the display
|
||||
// type changes from ruby to non-ruby.
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
if old_display.is_ruby_type() != new_display.is_ruby_type() {
|
||||
if old_display != new_display {
|
||||
// If we used to be a display: none element, and no longer are, our
|
||||
// children need to be restyled because they're unstyled.
|
||||
if old_display == Display::None {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
}
|
||||
// Blockification of children may depend on our display value,
|
||||
// so we need to actually do the recascade. We could potentially
|
||||
// do better, but it doesn't seem worth it.
|
||||
if old_display.is_item_container() != new_display.is_item_container() {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
}
|
||||
// We may also need to blockify and un-blockify descendants if our
|
||||
// display goes from / to display: contents, since the "layout
|
||||
// parent style" changes.
|
||||
if old_display.is_contents() || new_display.is_contents() {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
}
|
||||
// Line break suppression may also be affected if the display
|
||||
// type changes from ruby to non-ruby.
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
if old_display.is_ruby_type() != new_display.is_ruby_type() {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Children with justify-items: auto may depend on our
|
||||
|
|
|
@ -302,7 +302,7 @@ impl MediaFeatureExpression {
|
|||
feature_name = &feature_name[8..];
|
||||
requirements.insert(ParsingRequirements::WEBKIT_PREFIX);
|
||||
if unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_prefixes_device_pixel_ratio_webkit
|
||||
structs::StaticPrefs::sVarCache_layout_css_prefixes_device_pixel_ratio_webkit
|
||||
} {
|
||||
requirements.insert(
|
||||
ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED,
|
||||
|
|
|
@ -686,7 +686,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
return;
|
||||
}
|
||||
|
||||
let use_document_fonts = unsafe { structs::StaticPrefs_sVarCache_browser_display_use_document_fonts != 0 };
|
||||
let use_document_fonts = unsafe { structs::StaticPrefs::sVarCache_browser_display_use_document_fonts != 0 };
|
||||
let builder = &mut self.context.builder;
|
||||
let (default_font_type, prioritize_user_fonts) = {
|
||||
let font = builder.get_font().gecko();
|
||||
|
|
|
@ -336,7 +336,9 @@ class Longhand(object):
|
|||
"MozScriptLevel",
|
||||
"MozScriptMinSize",
|
||||
"MozScriptSizeMultiplier",
|
||||
"TextDecorationSkipInk",
|
||||
"NonNegativeNumber",
|
||||
"Number",
|
||||
"OffsetRotate",
|
||||
"Opacity",
|
||||
"OutlineStyle",
|
||||
|
@ -556,7 +558,7 @@ class PropertiesData(object):
|
|||
|
||||
longhand = Longhand(self.current_style_struct, name, **kwargs)
|
||||
self.add_prefixed_aliases(longhand)
|
||||
longhand.alias = list(map(lambda (x, p): Alias(x, longhand, p), longhand.alias))
|
||||
longhand.alias = list(map(lambda xp: Alias(xp[0], longhand, xp[1]), longhand.alias))
|
||||
self.longhand_aliases += longhand.alias
|
||||
self.current_style_struct.longhands.append(longhand)
|
||||
self.longhands.append(longhand)
|
||||
|
@ -572,7 +574,7 @@ class PropertiesData(object):
|
|||
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
|
||||
shorthand = Shorthand(name, sub_properties, *args, **kwargs)
|
||||
self.add_prefixed_aliases(shorthand)
|
||||
shorthand.alias = list(map(lambda (x, p): Alias(x, shorthand, p), shorthand.alias))
|
||||
shorthand.alias = list(map(lambda xp: Alias(xp[0], shorthand, xp[1]), shorthand.alias))
|
||||
self.shorthand_aliases += shorthand.alias
|
||||
self.shorthands.append(shorthand)
|
||||
return shorthand
|
||||
|
|
|
@ -36,7 +36,6 @@ use crate::gecko_bindings::bindings::Gecko_SetNullImageValue;
|
|||
use crate::gecko_bindings::structs;
|
||||
use crate::gecko_bindings::structs::nsCSSPropertyID;
|
||||
use crate::gecko_bindings::structs::mozilla::PseudoStyleType;
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::CoordDataMut;
|
||||
use crate::gecko_bindings::sugar::refptr::RefPtr;
|
||||
use crate::gecko::values::round_border_to_device_pixels;
|
||||
use crate::logical_geometry::WritingMode;
|
||||
|
@ -524,107 +523,6 @@ def set_gecko_property(ffi_name, expr):
|
|||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_svg_paint(ident, gecko_ffi_name)">
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set_${ident}(&mut self, mut v: longhands::${ident}::computed_value::T) {
|
||||
use crate::values::generics::svg::SVGPaintKind;
|
||||
use self::structs::nsStyleSVGPaintType;
|
||||
use self::structs::nsStyleSVGFallbackType;
|
||||
|
||||
let ref mut paint = ${get_gecko_property(gecko_ffi_name)};
|
||||
unsafe {
|
||||
bindings::Gecko_nsStyleSVGPaint_Reset(paint);
|
||||
}
|
||||
let fallback = v.fallback.take();
|
||||
match v.kind {
|
||||
SVGPaintKind::None => return,
|
||||
SVGPaintKind::ContextFill => {
|
||||
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextFill;
|
||||
}
|
||||
SVGPaintKind::ContextStroke => {
|
||||
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke;
|
||||
}
|
||||
SVGPaintKind::PaintServer(url) => {
|
||||
unsafe {
|
||||
bindings::Gecko_nsStyleSVGPaint_SetURLValue(
|
||||
paint,
|
||||
&url
|
||||
)
|
||||
}
|
||||
}
|
||||
SVGPaintKind::Color(color) => {
|
||||
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color;
|
||||
unsafe {
|
||||
*paint.mPaint.mColor.as_mut() = color.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
paint.mFallbackType = match fallback {
|
||||
Some(Either::First(color)) => {
|
||||
paint.mFallbackColor = color.into();
|
||||
nsStyleSVGFallbackType::eStyleSVGFallbackType_Color
|
||||
},
|
||||
Some(Either::Second(_)) => {
|
||||
nsStyleSVGFallbackType::eStyleSVGFallbackType_None
|
||||
},
|
||||
None => nsStyleSVGFallbackType::eStyleSVGFallbackType_NotSet
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
unsafe {
|
||||
bindings::Gecko_nsStyleSVGPaint_CopyFrom(
|
||||
&mut ${get_gecko_property(gecko_ffi_name)},
|
||||
& ${get_gecko_property(gecko_ffi_name, "other")}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn reset_${ident}(&mut self, other: &Self) {
|
||||
self.copy_${ident}_from(other)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
use crate::values::generics::svg::{SVGPaint, SVGPaintKind};
|
||||
use self::structs::nsStyleSVGPaintType;
|
||||
use self::structs::nsStyleSVGFallbackType;
|
||||
let ref paint = ${get_gecko_property(gecko_ffi_name)};
|
||||
|
||||
let fallback = match paint.mFallbackType {
|
||||
nsStyleSVGFallbackType::eStyleSVGFallbackType_Color => {
|
||||
Some(Either::First(paint.mFallbackColor.into()))
|
||||
},
|
||||
nsStyleSVGFallbackType::eStyleSVGFallbackType_None => {
|
||||
Some(Either::Second(None_))
|
||||
},
|
||||
nsStyleSVGFallbackType::eStyleSVGFallbackType_NotSet => None,
|
||||
};
|
||||
|
||||
let kind = match paint.mType {
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_None => SVGPaintKind::None,
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_ContextFill => SVGPaintKind::ContextFill,
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke => SVGPaintKind::ContextStroke,
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_Server => {
|
||||
SVGPaintKind::PaintServer(unsafe {
|
||||
paint.mPaint.mPaintServer.as_ref().clone()
|
||||
})
|
||||
}
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_Color => {
|
||||
let col = unsafe { *paint.mPaint.mColor.as_ref() };
|
||||
SVGPaintKind::Color(col.into())
|
||||
}
|
||||
};
|
||||
SVGPaint {
|
||||
kind: kind,
|
||||
fallback: fallback,
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_non_negative_length(ident, gecko_ffi_name, inherit_from=None,
|
||||
round_to_pixels=False)">
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -834,7 +732,6 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
"MozScriptMinSize": impl_absolute_length,
|
||||
"SVGLength": impl_svg_length,
|
||||
"SVGOpacity": impl_svg_opacity,
|
||||
"SVGPaint": impl_svg_paint,
|
||||
"SVGWidth": impl_svg_length,
|
||||
}
|
||||
|
||||
|
@ -880,15 +777,8 @@ class Side(object):
|
|||
self.ident = name.lower()
|
||||
self.index = index
|
||||
|
||||
class GridLine(object):
|
||||
def __init__(self, name):
|
||||
self.ident = "grid-" + name.lower()
|
||||
self.name = self.ident.replace('-', '_')
|
||||
self.gecko = "m" + to_camel_case(self.ident)
|
||||
|
||||
SIDES = [Side("Top", 0), Side("Right", 1), Side("Bottom", 2), Side("Left", 3)]
|
||||
CORNERS = ["top_left", "top_right", "bottom_right", "bottom_left"]
|
||||
GRID_LINES = map(GridLine, ["row-start", "row-end", "column-start", "column-end"])
|
||||
%>
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -1077,12 +967,11 @@ fn static_assert() {
|
|||
% endfor
|
||||
</%self:impl_trait>
|
||||
|
||||
<% skip_position_longhands = " ".join(x.ident for x in SIDES + GRID_LINES) %>
|
||||
<% skip_position_longhands = " ".join(x.ident for x in SIDES) %>
|
||||
<%self:impl_trait style_struct_name="Position"
|
||||
skip_longhands="${skip_position_longhands} order
|
||||
align-content justify-content align-self
|
||||
justify-self align-items justify-items
|
||||
grid-auto-rows grid-auto-columns
|
||||
grid-auto-flow grid-template-rows
|
||||
grid-template-columns">
|
||||
% for side in SIDES:
|
||||
|
@ -1132,92 +1021,14 @@ fn static_assert() {
|
|||
|
||||
${impl_simple_copy('order', 'mOrder')}
|
||||
|
||||
% for value in GRID_LINES:
|
||||
pub fn set_${value.name}(&mut self, v: longhands::${value.name}::computed_value::T) {
|
||||
use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
|
||||
|
||||
let line = &mut self.gecko.${value.gecko};
|
||||
line.mLineName.set_move(unsafe {
|
||||
RefPtr::from_addrefed(match v.ident {
|
||||
Some(i) => i.0,
|
||||
None => atom!(""),
|
||||
}.into_addrefed())
|
||||
});
|
||||
line.mHasSpan = v.is_span;
|
||||
if let Some(integer) = v.line_num {
|
||||
// clamping the integer between a range
|
||||
line.mInteger = cmp::max(
|
||||
nsStyleGridLine_kMinLine,
|
||||
cmp::min(integer, nsStyleGridLine_kMaxLine),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_${value.name}_from(&mut self, other: &Self) {
|
||||
self.gecko.${value.gecko}.mHasSpan = other.gecko.${value.gecko}.mHasSpan;
|
||||
self.gecko.${value.gecko}.mInteger = other.gecko.${value.gecko}.mInteger;
|
||||
unsafe {
|
||||
self.gecko.${value.gecko}.mLineName.set(&other.gecko.${value.gecko}.mLineName);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset_${value.name}(&mut self, other: &Self) {
|
||||
self.copy_${value.name}_from(other)
|
||||
}
|
||||
|
||||
pub fn clone_${value.name}(&self) -> longhands::${value.name}::computed_value::T {
|
||||
use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
|
||||
|
||||
longhands::${value.name}::computed_value::T {
|
||||
is_span: self.gecko.${value.gecko}.mHasSpan,
|
||||
ident: {
|
||||
let name = unsafe { Atom::from_raw(self.gecko.${value.gecko}.mLineName.mRawPtr) };
|
||||
if name == atom!("") {
|
||||
None
|
||||
} else {
|
||||
Some(CustomIdent(name))
|
||||
}
|
||||
},
|
||||
line_num:
|
||||
if self.gecko.${value.gecko}.mInteger == 0 {
|
||||
None
|
||||
} else {
|
||||
debug_assert!(nsStyleGridLine_kMinLine <= self.gecko.${value.gecko}.mInteger);
|
||||
debug_assert!(self.gecko.${value.gecko}.mInteger <= nsStyleGridLine_kMaxLine);
|
||||
Some(self.gecko.${value.gecko}.mInteger)
|
||||
},
|
||||
}
|
||||
}
|
||||
% endfor
|
||||
|
||||
% for kind in ["rows", "columns"]:
|
||||
pub fn set_grid_auto_${kind}(&mut self, v: longhands::grid_auto_${kind}::computed_value::T) {
|
||||
let gecko = &mut *self.gecko;
|
||||
v.to_gecko_style_coords(&mut gecko.mGridAuto${kind.title()}Min,
|
||||
&mut gecko.mGridAuto${kind.title()}Max)
|
||||
}
|
||||
|
||||
pub fn copy_grid_auto_${kind}_from(&mut self, other: &Self) {
|
||||
self.gecko.mGridAuto${kind.title()}Min.copy_from(&other.gecko.mGridAuto${kind.title()}Min);
|
||||
self.gecko.mGridAuto${kind.title()}Max.copy_from(&other.gecko.mGridAuto${kind.title()}Max);
|
||||
}
|
||||
|
||||
pub fn reset_grid_auto_${kind}(&mut self, other: &Self) {
|
||||
self.copy_grid_auto_${kind}_from(other)
|
||||
}
|
||||
|
||||
pub fn clone_grid_auto_${kind}(&self) -> longhands::grid_auto_${kind}::computed_value::T {
|
||||
crate::values::generics::grid::TrackSize::from_gecko_style_coords(&self.gecko.mGridAuto${kind.title()}Min,
|
||||
&self.gecko.mGridAuto${kind.title()}Max)
|
||||
}
|
||||
|
||||
pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
|
||||
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
|
||||
use crate::gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine};
|
||||
use crate::gecko_bindings::structs::nsTArray;
|
||||
use std::usize;
|
||||
use crate::values::CustomIdent;
|
||||
use crate::values::generics::grid::TrackListType::Auto;
|
||||
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount};
|
||||
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, TrackListValue, MAX_GRID_LINE};
|
||||
|
||||
#[inline]
|
||||
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<structs::RefPtr<structs::nsAtom>>) {
|
||||
|
@ -1232,7 +1043,7 @@ fn static_assert() {
|
|||
}
|
||||
}
|
||||
|
||||
let max_lines = nsStyleGridLine_kMaxLine as usize - 1; // for accounting the final <line-names>
|
||||
let max_lines = MAX_GRID_LINE as usize - 1; // for accounting the final <line-names>
|
||||
|
||||
let result = match v {
|
||||
GridTemplateComponent::None => ptr::null_mut(),
|
||||
|
@ -1276,20 +1087,21 @@ fn static_assert() {
|
|||
let mut line_names = track.line_names.into_iter();
|
||||
let mut values_iter = track.values.into_iter();
|
||||
{
|
||||
let min_max_iter = value.mMinTrackSizingFunctions.iter_mut()
|
||||
.zip(value.mMaxTrackSizingFunctions.iter_mut());
|
||||
for (i, (gecko_min, gecko_max)) in min_max_iter.enumerate().take(max_lines) {
|
||||
for (i, track_size) in value.mTrackSizingFunctions.iter_mut().enumerate().take(max_lines) {
|
||||
let name_list = line_names.next().expect("expected line-names");
|
||||
set_line_names(&name_list, &mut value.mLineNameLists[i]);
|
||||
if i == auto_idx {
|
||||
let track_size = auto_track_size.take()
|
||||
.expect("expected <track-size> for <auto-track-repeat>");
|
||||
track_size.to_gecko_style_coords(gecko_min, gecko_max);
|
||||
continue
|
||||
}
|
||||
|
||||
let track_size = values_iter.next().expect("expected <track-size> value");
|
||||
track_size.to_gecko_style_coords(gecko_min, gecko_max);
|
||||
*track_size = if i == auto_idx {
|
||||
auto_track_size.take().expect("expected <track-size> for <auto-track-repeat>")
|
||||
} else {
|
||||
match values_iter.next().expect("expected <track-size> value") {
|
||||
TrackListValue::TrackSize(size) => size,
|
||||
// FIXME(emilio): This shouldn't be
|
||||
// representable in the first place.
|
||||
TrackListValue::TrackRepeat(..) => {
|
||||
unreachable!("Shouldn't have track-repeats in computed track lists")
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1156,7 @@ fn static_assert() {
|
|||
use crate::gecko_bindings::structs::nsTArray;
|
||||
use crate::values::CustomIdent;
|
||||
use crate::values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount};
|
||||
use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat, TrackSize};
|
||||
use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat};
|
||||
|
||||
let value = match unsafe { ${self_grid}.mPtr.as_ref() } {
|
||||
None => return GridTemplateComponent::None,
|
||||
|
@ -1386,13 +1198,8 @@ fn static_assert() {
|
|||
let mut auto_repeat = None;
|
||||
let mut list_type = TrackListType::Normal;
|
||||
let line_names = to_line_names_vec(&value.mLineNameLists).into_boxed_slice();
|
||||
let mut values = Vec::with_capacity(value.mMinTrackSizingFunctions.len());
|
||||
|
||||
let min_max_iter = value.mMinTrackSizingFunctions.iter()
|
||||
.zip(value.mMaxTrackSizingFunctions.iter());
|
||||
for (i, (gecko_min, gecko_max)) in min_max_iter.enumerate() {
|
||||
let track_size = TrackSize::from_gecko_style_coords(gecko_min, gecko_max);
|
||||
|
||||
let mut values = Vec::with_capacity(value.mTrackSizingFunctions.len());
|
||||
for (i, track_size) in value.mTrackSizingFunctions.iter().enumerate() {
|
||||
if i == repeat_auto_index {
|
||||
list_type = TrackListType::Auto(repeat_auto_index as u16);
|
||||
|
||||
|
@ -1411,11 +1218,11 @@ fn static_assert() {
|
|||
vec.into_boxed_slice()
|
||||
};
|
||||
|
||||
let track_sizes = vec!(track_size);
|
||||
let track_sizes = vec!(track_size.clone());
|
||||
|
||||
auto_repeat = Some(TrackRepeat{count, line_names, track_sizes});
|
||||
} else {
|
||||
values.push(TrackListValue::TrackSize(track_size));
|
||||
values.push(TrackListValue::TrackSize(track_size.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ ${helpers.predefined_type(
|
|||
animation_value_type="AnimatedColor",
|
||||
ignored_when_colors_disabled=True,
|
||||
allow_quirks="Yes",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER \
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER \
|
||||
CAN_ANIMATE_ON_COMPOSITOR",
|
||||
)}
|
||||
|
||||
|
@ -28,7 +28,7 @@ ${helpers.predefined_type(
|
|||
vector="True",
|
||||
animation_value_type="discrete",
|
||||
ignored_when_colors_disabled="True",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
)}
|
||||
|
||||
% for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]:
|
||||
|
@ -41,7 +41,7 @@ ${helpers.predefined_type(
|
|||
animation_value_type="ComputedValue",
|
||||
vector=True,
|
||||
vector_animation_type="repeatable_list",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
)}
|
||||
% endfor
|
||||
|
||||
|
@ -53,7 +53,7 @@ ${helpers.predefined_type(
|
|||
animation_value_type="discrete",
|
||||
vector=True,
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
)}
|
||||
|
||||
${helpers.single_keyword(
|
||||
|
@ -63,7 +63,7 @@ ${helpers.single_keyword(
|
|||
gecko_enum_prefix="StyleImageLayerAttachment",
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
)}
|
||||
|
||||
${helpers.single_keyword(
|
||||
|
@ -75,7 +75,7 @@ ${helpers.single_keyword(
|
|||
gecko_inexhaustive=True,
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#the-background-clip",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
)}
|
||||
|
||||
${helpers.single_keyword(
|
||||
|
@ -86,7 +86,7 @@ ${helpers.single_keyword(
|
|||
gecko_inexhaustive=True,
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#the-background-origin",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER"
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER"
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
|
@ -98,7 +98,7 @@ ${helpers.predefined_type(
|
|||
vector=True,
|
||||
vector_animation_type="repeatable_list",
|
||||
animation_value_type="BackgroundSizeList",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
extra_prefixes="webkit")}
|
||||
|
||||
// https://drafts.fxtf.org/compositing/#background-blend-mode
|
||||
|
@ -110,5 +110,5 @@ ${helpers.single_keyword(
|
|||
gecko_constant_prefix="NS_STYLE_BLEND",
|
||||
vector=True, products="gecko", animation_value_type="discrete",
|
||||
spec="https://drafts.fxtf.org/compositing/#background-blend-mode",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
)}
|
||||
|
|
|
@ -13,6 +13,7 @@ ${helpers.predefined_type(
|
|||
initial_specified_value="specified::Content::normal()",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-content/#propdef-content",
|
||||
flags="APPLIES_TO_MARKER",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ ${helpers.predefined_type(
|
|||
"Opacity",
|
||||
"1.0",
|
||||
animation_value_type="ComputedValue",
|
||||
flags="CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER \
|
||||
flags="APPLIES_TO_CUE CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER \
|
||||
CAN_ANIMATE_ON_COMPOSITOR",
|
||||
spec="https://drafts.csswg.org/css-color/#opacity",
|
||||
servo_restyle_damage = "reflow_out_of_flow",
|
||||
|
@ -57,6 +57,22 @@ ${helpers.predefined_type(
|
|||
spec="https://drafts.fxtf.org/filters/#propdef-filter",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
"backdrop-filter",
|
||||
"Filter",
|
||||
None,
|
||||
vector=True,
|
||||
simple_vector_bindings=True,
|
||||
gecko_ffi_name="mBackdropFilters",
|
||||
separator="Space",
|
||||
animation_value_type="AnimatedFilterList",
|
||||
vector_animation_type="with_zero",
|
||||
flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
|
||||
gecko_pref="layout.css.backdrop-filter.enabled",
|
||||
spec="https://drafts.fxtf.org/filter-effects-2/#propdef-backdrop-filter",
|
||||
products="gecko",
|
||||
)}
|
||||
|
||||
${helpers.single_keyword(
|
||||
"mix-blend-mode",
|
||||
"""normal multiply screen overlay darken lighten color-dodge
|
||||
|
|
|
@ -12,7 +12,7 @@ ${helpers.predefined_type(
|
|||
"FontFamily",
|
||||
initial_value="computed::FontFamily::serif()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-family",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -23,7 +23,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontStyle::normal()",
|
||||
initial_specified_value="specified::FontStyle::normal()",
|
||||
animation_value_type="FontStyle",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-style",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -42,7 +42,7 @@ ${helpers.single_keyword_system(
|
|||
gecko_ffi_name="mFont.variantCaps",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps",
|
||||
custom_consts=font_variant_caps_custom_consts,
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
animation_value_type="discrete",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -53,7 +53,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontWeight::normal()",
|
||||
initial_specified_value="specified::FontWeight::normal()",
|
||||
animation_value_type="Number",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -65,7 +65,7 @@ ${helpers.predefined_type(
|
|||
initial_specified_value="specified::FontSize::medium()",
|
||||
animation_value_type="NonNegativeLength",
|
||||
allow_quirks="Yes",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -77,7 +77,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontSizeAdjust::none()",
|
||||
initial_specified_value="specified::FontSizeAdjust::none()",
|
||||
animation_value_type="ComputedValue",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust",
|
||||
)}
|
||||
|
||||
|
@ -87,7 +87,7 @@ ${helpers.predefined_type(
|
|||
products="gecko",
|
||||
initial_value="specified::FontSynthesis::get_initial_value()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-synthesis",
|
||||
)}
|
||||
|
||||
|
@ -97,7 +97,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontStretch::hundred()",
|
||||
initial_specified_value="specified::FontStretch::normal()",
|
||||
animation_value_type="Percentage",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -109,7 +109,7 @@ ${helpers.single_keyword_system(
|
|||
gecko_ffi_name="mFont.kerning",
|
||||
gecko_constant_prefix="NS_FONT_KERNING",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-kerning",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
animation_value_type="discrete",
|
||||
)}
|
||||
|
||||
|
@ -120,7 +120,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontVariantAlternates::get_initial_value()",
|
||||
initial_specified_value="specified::FontVariantAlternates::get_initial_specified_value()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates",
|
||||
)}
|
||||
|
||||
|
@ -131,7 +131,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontVariantEastAsian::empty()",
|
||||
initial_specified_value="specified::FontVariantEastAsian::empty()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian",
|
||||
)}
|
||||
|
||||
|
@ -142,7 +142,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontVariantLigatures::empty()",
|
||||
initial_specified_value="specified::FontVariantLigatures::empty()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures",
|
||||
)}
|
||||
|
||||
|
@ -153,7 +153,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontVariantNumeric::empty()",
|
||||
initial_specified_value="specified::FontVariantNumeric::empty()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric",
|
||||
)}
|
||||
|
||||
|
@ -164,7 +164,7 @@ ${helpers.single_keyword_system(
|
|||
gecko_ffi_name="mFont.variantPosition",
|
||||
gecko_constant_prefix="NS_FONT_VARIANT_POSITION",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
animation_value_type="discrete",
|
||||
)}
|
||||
|
||||
|
@ -176,7 +176,7 @@ ${helpers.predefined_type(
|
|||
initial_specified_value="specified::FontFeatureSettings::normal()",
|
||||
extra_prefixes="moz:layout.css.prefixes.font-features",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings",
|
||||
)}
|
||||
|
||||
|
@ -195,7 +195,7 @@ ${helpers.predefined_type(
|
|||
initial_value="computed::FontVariationSettings::normal()",
|
||||
initial_specified_value="specified::FontVariationSettings::normal()",
|
||||
animation_value_type="ComputedValue",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="${variation_spec}",
|
||||
)}
|
||||
|
||||
|
@ -207,7 +207,7 @@ ${helpers.predefined_type(
|
|||
initial_specified_value="specified::FontLanguageOverride::normal()",
|
||||
animation_value_type="discrete",
|
||||
extra_prefixes="moz:layout.css.prefixes.font-features",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override",
|
||||
)}
|
||||
|
||||
|
@ -219,7 +219,7 @@ ${helpers.single_keyword_system(
|
|||
gecko_ffi_name="mFont.opticalSizing",
|
||||
gecko_constant_prefix="NS_FONT_OPTICAL_SIZING",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
spec="https://www.w3.org/TR/css-fonts-4/#font-optical-sizing-def",
|
||||
)}
|
||||
|
||||
|
@ -412,7 +412,7 @@ ${helpers.predefined_type(
|
|||
is_system_font: true,
|
||||
},
|
||||
font_size: FontSize {
|
||||
size: Au(system.size).into(),
|
||||
size: cx.maybe_zoom_text(Au(system.size).into()),
|
||||
keyword_info: None
|
||||
},
|
||||
font_weight,
|
||||
|
@ -514,7 +514,7 @@ ${helpers.single_keyword(
|
|||
gecko_pref="layout.css.osx-font-smoothing.enabled",
|
||||
products="gecko",
|
||||
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
animation_value_type="discrete",
|
||||
)}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ ${helpers.single_keyword(
|
|||
gecko_ffi_name="mVisible",
|
||||
animation_value_type="ComputedValue",
|
||||
spec="https://drafts.csswg.org/css-box/#propdef-visibility",
|
||||
flags="APPLIES_TO_CUE",
|
||||
)}
|
||||
|
||||
// CSS Writing Modes Level 3
|
||||
|
@ -37,6 +38,7 @@ ${helpers.single_keyword(
|
|||
animation_value_type="none",
|
||||
spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
|
||||
needs_conversion=True,
|
||||
flags="APPLIES_TO_MARKER",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ ${helpers.predefined_type(
|
|||
"ColorPropertyValue",
|
||||
"::cssparser::RGBA::new(0, 0, 0, 255)",
|
||||
animation_value_type="AnimatedRGBA",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
|
||||
ignored_when_colors_disabled="True",
|
||||
spec="https://drafts.csswg.org/css-color/#color",
|
||||
)}
|
||||
|
@ -21,7 +21,7 @@ ${helpers.predefined_type(
|
|||
"LineHeight",
|
||||
"computed::LineHeight::normal()",
|
||||
animation_value_type="LineHeight",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE \
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE \
|
||||
APPLIES_TO_PLACEHOLDER GETCS_NEEDS_LAYOUT_FLUSH",
|
||||
spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height",
|
||||
servo_restyle_damage="reflow"
|
||||
|
@ -181,7 +181,7 @@ ${helpers.predefined_type(
|
|||
needs_conversion="True"
|
||||
animation_value_type="discrete"
|
||||
// Only allowed for UA sheets, which set it !important.
|
||||
flags="APPLIES_TO_PLACEHOLDER"
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_PLACEHOLDER"
|
||||
spec="https://drafts.csswg.org/css-text/#propdef-white-space"
|
||||
servo_restyle_damage="rebuild_and_reflow"
|
||||
>
|
||||
|
@ -229,7 +229,7 @@ ${helpers.predefined_type(
|
|||
animation_value_type="AnimatedTextShadowList",
|
||||
ignored_when_colors_disabled=True,
|
||||
simple_vector_bindings=True,
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
spec="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property",
|
||||
)}
|
||||
|
||||
|
@ -337,6 +337,7 @@ ${helpers.single_keyword(
|
|||
products="gecko",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-ruby/#ruby-position-property",
|
||||
flags="APPLIES_TO_CUE",
|
||||
)}
|
||||
|
||||
// CSS Writing Modes Module Level 3
|
||||
|
@ -348,6 +349,7 @@ ${helpers.single_keyword(
|
|||
products="gecko",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-writing-modes-3/#text-combine-upright",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_MARKER",
|
||||
)}
|
||||
|
||||
// SVG 1.1: Section 11 - Painting: Filling, Stroking and Marker Symbols
|
||||
|
@ -382,3 +384,15 @@ ${helpers.predefined_type(
|
|||
gecko_pref="layout.css.text-underline-offset.enabled",
|
||||
spec="https://drafts.csswg.org/css-text-decor-4/#underline-offset",
|
||||
)}
|
||||
|
||||
// text decoration skip ink
|
||||
${helpers.predefined_type(
|
||||
"text-decoration-skip-ink",
|
||||
"TextDecorationSkipInk",
|
||||
"computed::TextDecorationSkipInk::Auto",
|
||||
products="gecko",
|
||||
needs_context=False,
|
||||
animation_value_type="discrete",
|
||||
gecko_pref="layout.css.text-decoration-skip-ink.enabled",
|
||||
spec="https://drafts.csswg.org/css-text-decor-4/#text-decoration-skip-ink-property",
|
||||
)}
|
||||
|
|
|
@ -18,6 +18,7 @@ ${helpers.predefined_type(
|
|||
animation_value_type="AnimatedColor",
|
||||
ignored_when_colors_disabled=True,
|
||||
spec="https://drafts.csswg.org/css-ui/#propdef-outline-color",
|
||||
flags="APPLIES_TO_CUE",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
|
@ -27,6 +28,7 @@ ${helpers.predefined_type(
|
|||
initial_specified_value="specified::OutlineStyle::none()",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-ui/#propdef-outline-style",
|
||||
flags="APPLIES_TO_CUE",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
|
@ -37,6 +39,7 @@ ${helpers.predefined_type(
|
|||
computed_type="crate::values::computed::NonNegativeLength",
|
||||
animation_value_type="NonNegativeLength",
|
||||
spec="https://drafts.csswg.org/css-ui/#propdef-outline-width",
|
||||
flags="APPLIES_TO_CUE",
|
||||
)}
|
||||
|
||||
// The -moz-outline-radius-* properties are non-standard and not on a standards track.
|
||||
|
|
|
@ -322,7 +322,6 @@ ${helpers.predefined_type(
|
|||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-%s" % (kind, range),
|
||||
products="gecko",
|
||||
boxed=True,
|
||||
)}
|
||||
% endfor
|
||||
|
||||
|
@ -392,3 +391,17 @@ ${helpers.predefined_type(
|
|||
animation_value_type="NonNegativeLengthPercentageOrNormal",
|
||||
servo_restyle_damage="reflow",
|
||||
)}
|
||||
|
||||
// NOTE(emilio): Before exposing this property to content, we probably need to
|
||||
// change syntax and such, and make it apply to more elements.
|
||||
//
|
||||
// For now, it's used only for mapped attributes.
|
||||
${helpers.predefined_type(
|
||||
"aspect-ratio",
|
||||
"Number",
|
||||
"computed::Number::zero()",
|
||||
animation_value_type="ComputedValue",
|
||||
spec="Internal, for now",
|
||||
enabled_in="",
|
||||
servo_restyle_damage="reflow",
|
||||
)}
|
||||
|
|
|
@ -23,6 +23,7 @@ ${helpers.single_keyword(
|
|||
"normal embed isolate bidi-override isolate-override plaintext",
|
||||
animation_value_type="none",
|
||||
spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi",
|
||||
flags="APPLIES_TO_MARKER",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
||||
|
@ -32,7 +33,7 @@ ${helpers.predefined_type(
|
|||
"specified::TextDecorationLine::none()",
|
||||
initial_specified_value="specified::TextDecorationLine::none()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
)}
|
||||
|
@ -42,7 +43,7 @@ ${helpers.single_keyword(
|
|||
"solid double dotted dashed wavy -moz-none",
|
||||
products="gecko",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-style",
|
||||
)}
|
||||
|
||||
|
@ -54,7 +55,7 @@ ${helpers.predefined_type(
|
|||
products="gecko",
|
||||
animation_value_type="AnimatedColor",
|
||||
ignored_when_colors_disabled=True,
|
||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color",
|
||||
)}
|
||||
|
||||
|
|
|
@ -939,7 +939,7 @@ impl CSSWideKeyword {
|
|||
|
||||
bitflags! {
|
||||
/// A set of flags for properties.
|
||||
pub struct PropertyFlags: u8 {
|
||||
pub struct PropertyFlags: u16 {
|
||||
/// This property requires a stacking context.
|
||||
const CREATES_STACKING_CONTEXT = 1 << 0;
|
||||
/// This property has values that can establish a containing block for
|
||||
|
@ -954,13 +954,17 @@ bitflags! {
|
|||
const APPLIES_TO_FIRST_LINE = 1 << 4;
|
||||
/// This longhand property applies to ::placeholder.
|
||||
const APPLIES_TO_PLACEHOLDER = 1 << 5;
|
||||
/// This longhand property applies to ::cue.
|
||||
const APPLIES_TO_CUE = 1 << 6;
|
||||
/// This longhand property applies to ::marker.
|
||||
const APPLIES_TO_MARKER = 1 << 7;
|
||||
/// This property's getComputedStyle implementation requires layout
|
||||
/// to be flushed.
|
||||
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 6;
|
||||
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 8;
|
||||
/// This property is a legacy shorthand.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-cascade/#legacy-shorthand
|
||||
const IS_LEGACY_SHORTHAND = 1 << 7;
|
||||
const IS_LEGACY_SHORTHAND = 1 << 9;
|
||||
|
||||
/* The following flags are currently not used in Rust code, they
|
||||
* only need to be listed in corresponding properties so that
|
||||
|
@ -1184,7 +1188,7 @@ impl LonghandId {
|
|||
pub fn flags(self) -> PropertyFlags {
|
||||
// TODO(emilio): This can be simplified further as Rust gains more
|
||||
// constant expression support.
|
||||
const FLAGS: [u8; ${len(data.longhands)}] = [
|
||||
const FLAGS: [u16; ${len(data.longhands)}] = [
|
||||
% for property in data.longhands:
|
||||
% for flag in property.flags:
|
||||
PropertyFlags::${flag}.bits |
|
||||
|
@ -1446,7 +1450,7 @@ impl ShorthandId {
|
|||
/// Returns PropertyFlags for the given shorthand property.
|
||||
#[inline]
|
||||
pub fn flags(self) -> PropertyFlags {
|
||||
const FLAGS: [u8; ${len(data.shorthands)}] = [
|
||||
const FLAGS: [u16; ${len(data.shorthands)}] = [
|
||||
% for property in data.shorthands:
|
||||
% for flag in property.flags:
|
||||
PropertyFlags::${flag}.bits |
|
||||
|
@ -2834,6 +2838,19 @@ impl ComputedValues {
|
|||
pub fn resolve_color(&self, color: computed::Color) -> RGBA {
|
||||
color.to_rgba(self.get_inherited_text().clone_color())
|
||||
}
|
||||
|
||||
/// Returns which longhand properties have different values in the two
|
||||
/// ComputedValues.
|
||||
#[cfg(feature = "gecko_debug")]
|
||||
pub fn differing_properties(&self, other: &ComputedValues) -> LonghandIdSet {
|
||||
let mut set = LonghandIdSet::new();
|
||||
% for prop in data.longhands:
|
||||
if self.clone_${prop.ident}() != other.clone_${prop.ident}() {
|
||||
set.insert(LonghandId::${prop.camel_case});
|
||||
}
|
||||
% endfor
|
||||
set
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
|
|
|
@ -144,6 +144,7 @@
|
|||
products="gecko">
|
||||
use crate::values::specified::GridLine;
|
||||
use crate::parser::Parse;
|
||||
use crate::Zero;
|
||||
|
||||
// NOTE: Since both the shorthands have the same code, we should (re-)use code from one to implement
|
||||
// the other. This might not be a big deal for now, but we should consider looking into this in the future
|
||||
|
@ -157,8 +158,8 @@
|
|||
GridLine::parse(context, input)?
|
||||
} else {
|
||||
let mut line = GridLine::auto();
|
||||
if start.line_num.is_none() && !start.is_span {
|
||||
line.ident = start.ident.clone(); // ident from start value should be taken
|
||||
if start.line_num.is_zero() && !start.is_span {
|
||||
line.ident = start.ident.clone(); // ident from start value should be taken
|
||||
}
|
||||
|
||||
line
|
||||
|
@ -186,6 +187,7 @@
|
|||
products="gecko">
|
||||
use crate::values::specified::GridLine;
|
||||
use crate::parser::Parse;
|
||||
use crate::Zero;
|
||||
|
||||
// The code is the same as `grid-{row,column}` except that this can have four values at most.
|
||||
pub fn parse_value<'i, 't>(
|
||||
|
@ -194,7 +196,7 @@
|
|||
) -> Result<Longhands, ParseError<'i>> {
|
||||
fn line_with_ident_from(other: &GridLine) -> GridLine {
|
||||
let mut this = GridLine::auto();
|
||||
if other.line_num.is_none() && !other.is_span {
|
||||
if other.line_num.is_zero() && !other.is_span {
|
||||
this.ident = other.ident.clone();
|
||||
}
|
||||
|
||||
|
|
|
@ -950,8 +950,8 @@ mod gecko_leak_checking {
|
|||
use std::os::raw::{c_char, c_void};
|
||||
|
||||
extern "C" {
|
||||
pub fn NS_LogCtor(aPtr: *const c_void, aTypeName: *const c_char, aSize: u32);
|
||||
pub fn NS_LogDtor(aPtr: *const c_void, aTypeName: *const c_char, aSize: u32);
|
||||
fn NS_LogCtor(aPtr: *mut c_void, aTypeName: *const c_char, aSize: u32);
|
||||
fn NS_LogDtor(aPtr: *mut c_void, aTypeName: *const c_char, aSize: u32);
|
||||
}
|
||||
|
||||
static NAME: &'static [u8] = b"RuleNode\0";
|
||||
|
@ -960,7 +960,7 @@ mod gecko_leak_checking {
|
|||
pub fn log_ctor(ptr: *const RuleNode) {
|
||||
let s = NAME as *const [u8] as *const u8 as *const c_char;
|
||||
unsafe {
|
||||
NS_LogCtor(ptr as *const c_void, s, size_of::<RuleNode>() as u32);
|
||||
NS_LogCtor(ptr as *mut c_void, s, size_of::<RuleNode>() as u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -968,7 +968,7 @@ mod gecko_leak_checking {
|
|||
pub fn log_dtor(ptr: *const RuleNode) {
|
||||
let s = NAME as *const [u8] as *const u8 as *const c_char;
|
||||
unsafe {
|
||||
NS_LogDtor(ptr as *const c_void, s, size_of::<RuleNode>() as u32);
|
||||
NS_LogDtor(ptr as *mut c_void, s, size_of::<RuleNode>() as u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -260,12 +260,12 @@ impl DocumentCondition {
|
|||
return true;
|
||||
}
|
||||
|
||||
if unsafe { structs::StaticPrefs_sVarCache_layout_css_moz_document_content_enabled } {
|
||||
if unsafe { structs::StaticPrefs::sVarCache_layout_css_moz_document_content_enabled } {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_moz_document_url_prefix_hack_enabled
|
||||
structs::StaticPrefs::sVarCache_layout_css_moz_document_url_prefix_hack_enabled
|
||||
} {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -324,7 +324,7 @@ impl RawSelector {
|
|||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
if unsafe {
|
||||
!crate::gecko_bindings::structs::StaticPrefs_sVarCache_layout_css_supports_selector_enabled
|
||||
!crate::gecko_bindings::structs::StaticPrefs::sVarCache_layout_css_supports_selector_enabled
|
||||
} {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,9 @@ pub type AnimatedSimpleShadow = GenericSimpleShadow<Color, Length, Length>;
|
|||
|
||||
/// An animated value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type AnimatedFilter = GenericFilter<Angle, Number, Length, AnimatedSimpleShadow, ComputedUrl>;
|
||||
pub type AnimatedFilter =
|
||||
GenericFilter<Angle, Number, Number, Length, AnimatedSimpleShadow, ComputedUrl>;
|
||||
|
||||
/// An animated value for a single `filter`.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type AnimatedFilter = GenericFilter<Angle, Number, Length, Impossible, Impossible>;
|
||||
pub type AnimatedFilter = GenericFilter<Angle, Number, Number, Length, Impossible, Impossible>;
|
||||
|
|
|
@ -62,10 +62,7 @@ impl Animate for TrackSize {
|
|||
}
|
||||
}
|
||||
|
||||
impl Animate for generics::TrackRepeat<LengthPercentage, Integer>
|
||||
where
|
||||
generics::RepeatCount<Integer>: PartialEq,
|
||||
{
|
||||
impl Animate for generics::TrackRepeat<LengthPercentage, Integer> {
|
||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||
// If the keyword, auto-fit/fill, is the same it can result in different
|
||||
// number of tracks. For both auto-fit/fill, the number of columns isn't
|
||||
|
|
|
@ -447,17 +447,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedZero for Box<[T]>
|
||||
impl<T> ToAnimatedZero for crate::OwnedSlice<T>
|
||||
where
|
||||
T: ToAnimatedZero,
|
||||
{
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
let v = self
|
||||
.iter()
|
||||
.map(|v| v.to_animated_zero())
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(v.into_boxed_slice())
|
||||
self.iter().map(|v| v.to_animated_zero()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,25 +4,10 @@
|
|||
|
||||
//! Animation implementations for various SVG-related types.
|
||||
|
||||
use super::{Animate, Procedure, ToAnimatedZero};
|
||||
use super::{Animate, Procedure};
|
||||
use crate::properties::animated_properties::ListAnimation;
|
||||
use crate::values::animated::color::Color as AnimatedColor;
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use crate::values::generics::svg::{SVGPaint, SVGStrokeDashArray};
|
||||
|
||||
/// Animated SVGPaint.
|
||||
pub type IntermediateSVGPaint = SVGPaint<AnimatedColor, ComputedUrl>;
|
||||
|
||||
impl ToAnimatedZero for IntermediateSVGPaint {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
Ok(IntermediateSVGPaint {
|
||||
kind: self.kind.to_animated_zero()?,
|
||||
fallback: self.fallback.and_then(|v| v.to_animated_zero().ok()),
|
||||
})
|
||||
}
|
||||
}
|
||||
use crate::values::generics::svg::SVGStrokeDashArray;
|
||||
|
||||
/// <https://www.w3.org/TR/SVG11/painting.html#StrokeDasharrayProperty>
|
||||
impl<L> Animate for SVGStrokeDashArray<L>
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::values::computed::color::Color;
|
|||
use crate::values::computed::length::{Length, NonNegativeLength};
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::values::computed::{Angle, NonNegativeNumber};
|
||||
use crate::values::computed::{Angle, NonNegativeNumber, ZeroToOneNumber};
|
||||
use crate::values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
use crate::values::generics::effects::Filter as GenericFilter;
|
||||
use crate::values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||
|
@ -20,13 +20,25 @@ pub type BoxShadow = GenericBoxShadow<Color, Length, NonNegativeLength, Length>;
|
|||
|
||||
/// A computed value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type Filter =
|
||||
GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow, ComputedUrl>;
|
||||
pub type Filter = GenericFilter<
|
||||
Angle,
|
||||
NonNegativeNumber,
|
||||
ZeroToOneNumber,
|
||||
NonNegativeLength,
|
||||
SimpleShadow,
|
||||
ComputedUrl,
|
||||
>;
|
||||
|
||||
/// A computed value for a single `filter`.
|
||||
#[cfg(feature = "servo")]
|
||||
pub type Filter =
|
||||
GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible, Impossible>;
|
||||
pub type Filter = GenericFilter<
|
||||
Angle,
|
||||
NonNegativeNumber,
|
||||
ZeroToOneNumber,
|
||||
NonNegativeLength,
|
||||
Impossible,
|
||||
Impossible,
|
||||
>;
|
||||
|
||||
/// A computed value for the `drop-shadow()` filter.
|
||||
pub type SimpleShadow = GenericSimpleShadow<Color, Length, NonNegativeLength>;
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
use self::transform::DirectionVector;
|
||||
use super::animated::ToAnimatedValue;
|
||||
use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
||||
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||
use super::generics::grid::{GenericGridLine, GenericTrackBreadth};
|
||||
use super::generics::grid::{GenericTrackSize, TrackList as GenericTrackList};
|
||||
use super::generics::transform::IsParallelTo;
|
||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
|
||||
use super::specified;
|
||||
use super::{CSSFloat, CSSInteger};
|
||||
use crate::context::QuirksMode;
|
||||
|
@ -75,6 +75,7 @@ pub use self::svg::MozContextProperties;
|
|||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
||||
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
|
||||
pub use self::table::XSpan;
|
||||
pub use self::text::TextDecorationSkipInk;
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineBreak, LineHeight};
|
||||
pub use self::text::{OverflowWrap, TextOverflow, WordBreak, WordSpacing};
|
||||
pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle};
|
||||
|
@ -519,6 +520,30 @@ impl From<NonNegativeNumber> for CSSFloat {
|
|||
}
|
||||
}
|
||||
|
||||
/// A wrapper of Number, but the value between 0 and 1
|
||||
pub type ZeroToOneNumber = ZeroToOne<CSSFloat>;
|
||||
|
||||
impl ToAnimatedValue for ZeroToOneNumber {
|
||||
type AnimatedValue = CSSFloat;
|
||||
|
||||
#[inline]
|
||||
fn to_animated_value(self) -> Self::AnimatedValue {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||
Self(animated.max(0.).min(1.))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CSSFloat> for ZeroToOneNumber {
|
||||
#[inline]
|
||||
fn from(number: CSSFloat) -> Self {
|
||||
Self(number)
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper of Number, but the value >= 1.
|
||||
pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<CSSFloat>;
|
||||
|
||||
|
|
|
@ -11,23 +11,13 @@ use crate::values::generics::svg as generic;
|
|||
use crate::values::RGBA;
|
||||
use crate::Zero;
|
||||
|
||||
pub use crate::values::specified::SVGPaintOrder;
|
||||
|
||||
pub use crate::values::specified::MozContextProperties;
|
||||
pub use crate::values::specified::{MozContextProperties, SVGPaintOrder};
|
||||
|
||||
/// Computed SVG Paint value
|
||||
pub type SVGPaint = generic::SVGPaint<Color, ComputedUrl>;
|
||||
/// Computed SVG Paint Kind value
|
||||
pub type SVGPaintKind = generic::SVGPaintKind<Color, ComputedUrl>;
|
||||
pub type SVGPaint = generic::GenericSVGPaint<Color, ComputedUrl>;
|
||||
|
||||
impl Default for SVGPaint {
|
||||
fn default() -> Self {
|
||||
SVGPaint {
|
||||
kind: generic::SVGPaintKind::None,
|
||||
fallback: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Computed SVG Paint Kind value
|
||||
pub type SVGPaintKind = generic::GenericSVGPaintKind<Color, ComputedUrl>;
|
||||
|
||||
impl SVGPaint {
|
||||
/// Opaque black color
|
||||
|
@ -35,7 +25,7 @@ impl SVGPaint {
|
|||
let rgba = RGBA::from_floats(0., 0., 0., 1.).into();
|
||||
SVGPaint {
|
||||
kind: generic::SVGPaintKind::Color(rgba),
|
||||
fallback: None,
|
||||
fallback: generic::SVGPaintFallback::Unset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,16 +52,16 @@ impl SVGWidth {
|
|||
}
|
||||
|
||||
/// [ <length> | <percentage> | <number> ]# | context-value
|
||||
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthPercentage>;
|
||||
pub type SVGStrokeDashArray = generic::GenericSVGStrokeDashArray<NonNegativeLengthPercentage>;
|
||||
|
||||
impl Default for SVGStrokeDashArray {
|
||||
fn default() -> Self {
|
||||
generic::SVGStrokeDashArray::Values(vec![])
|
||||
generic::SVGStrokeDashArray::Values(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// <opacity-value> | context-fill-opacity | context-stroke-opacity
|
||||
pub type SVGOpacity = generic::SVGOpacity<Opacity>;
|
||||
pub type SVGOpacity = generic::GenericSVGOpacity<Opacity>;
|
||||
|
||||
impl Default for SVGOpacity {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -19,9 +19,9 @@ use std::fmt::{self, Write};
|
|||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
pub use crate::values::specified::TextAlignKeyword as TextAlign;
|
||||
pub use crate::values::specified::TextTransform;
|
||||
pub use crate::values::specified::{LineBreak, OverflowWrap, WordBreak};
|
||||
pub use crate::values::specified::{TextDecorationLine, TextEmphasisPosition};
|
||||
pub use crate::values::specified::{TextDecorationSkipInk, TextTransform};
|
||||
|
||||
/// A computed value for the `initial-letter` property.
|
||||
pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
|
||||
|
|
|
@ -70,7 +70,7 @@ pub enum TimingKeyword {
|
|||
#[cfg(feature = "gecko")]
|
||||
fn step_position_jump_enabled(_context: &ParserContext) -> bool {
|
||||
use crate::gecko_bindings::structs;
|
||||
unsafe { structs::StaticPrefs_sVarCache_layout_css_step_position_jump_enabled }
|
||||
unsafe { structs::StaticPrefs::sVarCache_layout_css_step_position_jump_enabled }
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
|
|
|
@ -52,34 +52,34 @@ pub use self::GenericBoxShadow as BoxShadow;
|
|||
ToShmem,
|
||||
)]
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericFilter<Angle, Factor, Length, Shadow, U> {
|
||||
pub enum GenericFilter<Angle, NonNegativeFactor, ZeroToOneFactor, Length, Shadow, U> {
|
||||
/// `blur(<length>)`
|
||||
#[css(function)]
|
||||
Blur(Length),
|
||||
/// `brightness(<factor>)`
|
||||
#[css(function)]
|
||||
Brightness(Factor),
|
||||
Brightness(NonNegativeFactor),
|
||||
/// `contrast(<factor>)`
|
||||
#[css(function)]
|
||||
Contrast(Factor),
|
||||
Contrast(NonNegativeFactor),
|
||||
/// `grayscale(<factor>)`
|
||||
#[css(function)]
|
||||
Grayscale(Factor),
|
||||
Grayscale(ZeroToOneFactor),
|
||||
/// `hue-rotate(<angle>)`
|
||||
#[css(function)]
|
||||
HueRotate(Angle),
|
||||
/// `invert(<factor>)`
|
||||
#[css(function)]
|
||||
Invert(Factor),
|
||||
Invert(ZeroToOneFactor),
|
||||
/// `opacity(<factor>)`
|
||||
#[css(function)]
|
||||
Opacity(Factor),
|
||||
Opacity(ZeroToOneFactor),
|
||||
/// `saturate(<factor>)`
|
||||
#[css(function)]
|
||||
Saturate(Factor),
|
||||
Saturate(NonNegativeFactor),
|
||||
/// `sepia(<factor>)`
|
||||
#[css(function)]
|
||||
Sepia(Factor),
|
||||
Sepia(ZeroToOneFactor),
|
||||
/// `drop-shadow(...)`
|
||||
#[css(function)]
|
||||
DropShadow(Shadow),
|
||||
|
|
|
@ -6,15 +6,22 @@
|
|||
//! [grids](https://drafts.csswg.org/css-grid/).
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::computed::{Context, ToComputedValue};
|
||||
use crate::values::specified;
|
||||
use crate::values::specified::grid::parse_line_names;
|
||||
use crate::values::{CSSFloat, CustomIdent};
|
||||
use crate::{Atom, Zero};
|
||||
use cssparser::Parser;
|
||||
use std::fmt::{self, Write};
|
||||
use std::{mem, usize};
|
||||
use std::{cmp, mem, usize};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
|
||||
/// These are the limits that we choose to clamp grid line numbers to.
|
||||
/// http://drafts.csswg.org/css-grid/#overlarge-grids
|
||||
/// line_num is clamped to this range at parse time.
|
||||
pub const MIN_GRID_LINE: i32 = -10000;
|
||||
/// See above.
|
||||
pub const MAX_GRID_LINE: i32 = 10000;
|
||||
|
||||
/// A `<grid-line>` type.
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line>
|
||||
|
@ -29,36 +36,48 @@ use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub struct GridLine<Integer> {
|
||||
/// Flag to check whether it's a `span` keyword.
|
||||
pub is_span: bool,
|
||||
/// A custom identifier for named lines.
|
||||
#[repr(C)]
|
||||
pub struct GenericGridLine<Integer> {
|
||||
/// A custom identifier for named lines, or the empty atom otherwise.
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#grid-placement-slot>
|
||||
pub ident: Option<CustomIdent>,
|
||||
pub ident: Atom,
|
||||
/// Denotes the nth grid line from grid item's placement.
|
||||
pub line_num: Option<Integer>,
|
||||
///
|
||||
/// This is clamped by MIN_GRID_LINE and MAX_GRID_LINE.
|
||||
///
|
||||
/// NOTE(emilio): If we ever allow animating these we need to either do
|
||||
/// something more complicated for the clamping, or do this clamping at
|
||||
/// used-value time.
|
||||
pub line_num: Integer,
|
||||
/// Flag to check whether it's a `span` keyword.
|
||||
pub is_span: bool,
|
||||
}
|
||||
|
||||
impl<Integer> GridLine<Integer> {
|
||||
pub use self::GenericGridLine as GridLine;
|
||||
|
||||
impl<Integer> GridLine<Integer>
|
||||
where
|
||||
Integer: Zero,
|
||||
{
|
||||
/// The `auto` value.
|
||||
pub fn auto() -> Self {
|
||||
Self {
|
||||
is_span: false,
|
||||
line_num: None,
|
||||
ident: None,
|
||||
line_num: Zero::zero(),
|
||||
ident: atom!(""),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check whether this `<grid-line>` represents an `auto` value.
|
||||
pub fn is_auto(&self) -> bool {
|
||||
self.ident.is_none() && self.line_num.is_none() && !self.is_span
|
||||
self.ident == atom!("") && self.line_num.is_zero() && !self.is_span
|
||||
}
|
||||
}
|
||||
|
||||
impl<Integer> ToCss for GridLine<Integer>
|
||||
where
|
||||
Integer: ToCss,
|
||||
Integer: ToCss + Zero,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
|
@ -72,18 +91,18 @@ where
|
|||
dest.write_str("span")?;
|
||||
}
|
||||
|
||||
if let Some(ref i) = self.line_num {
|
||||
if !self.line_num.is_zero() {
|
||||
if self.is_span {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
i.to_css(dest)?;
|
||||
self.line_num.to_css(dest)?;
|
||||
}
|
||||
|
||||
if let Some(ref s) = self.ident {
|
||||
if self.is_span || self.line_num.is_some() {
|
||||
if self.ident != atom!("") {
|
||||
if self.is_span || !self.line_num.is_zero() {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
s.to_css(dest)?;
|
||||
CustomIdent(self.ident.clone()).to_css(dest)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -114,25 +133,29 @@ impl Parse for GridLine<specified::Integer> {
|
|||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
if grid_line.line_num.is_some() || grid_line.ident.is_some() {
|
||||
if !grid_line.line_num.is_zero() || grid_line.ident != atom!("") {
|
||||
val_before_span = true;
|
||||
}
|
||||
|
||||
grid_line.is_span = true;
|
||||
} else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) {
|
||||
// FIXME(emilio): Probably shouldn't reject if it's calc()...
|
||||
if i.value() == 0 || val_before_span || grid_line.line_num.is_some() {
|
||||
let value = i.value();
|
||||
if value == 0 || val_before_span || !grid_line.line_num.is_zero() {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
grid_line.line_num = Some(i);
|
||||
grid_line.line_num = specified::Integer::new(cmp::max(
|
||||
MIN_GRID_LINE,
|
||||
cmp::min(value, MAX_GRID_LINE),
|
||||
));
|
||||
} else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
|
||||
if val_before_span || grid_line.ident.is_some() {
|
||||
if val_before_span || grid_line.ident != atom!("") {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
// NOTE(emilio): `span` is consumed above, so we only need to
|
||||
// reject `auto`.
|
||||
grid_line.ident = Some(CustomIdent::from_ident(location, &name, &["auto"])?);
|
||||
grid_line.ident = CustomIdent::from_ident(location, &name, &["auto"])?.0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -143,12 +166,12 @@ impl Parse for GridLine<specified::Integer> {
|
|||
}
|
||||
|
||||
if grid_line.is_span {
|
||||
if let Some(i) = grid_line.line_num {
|
||||
if i.value() <= 0 {
|
||||
if !grid_line.line_num.is_zero() {
|
||||
if grid_line.line_num.value() <= 0 {
|
||||
// disallow negative integers for grid spans
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
} else if grid_line.ident.is_none() {
|
||||
} else if grid_line.ident == atom!("") {
|
||||
// integer could be omitted
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
@ -158,33 +181,12 @@ impl Parse for GridLine<specified::Integer> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum TrackKeyword {
|
||||
Auto,
|
||||
MaxContent,
|
||||
MinContent,
|
||||
}
|
||||
|
||||
/// A track breadth for explicit grid track sizing. It's generic solely to
|
||||
/// avoid re-implementing it for the computed type.
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#typedef-track-breadth>
|
||||
///
|
||||
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
|
@ -197,16 +199,23 @@ pub enum TrackKeyword {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum TrackBreadth<L> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericTrackBreadth<L> {
|
||||
/// The generic type is almost always a non-negative `<length-percentage>`
|
||||
Breadth(L),
|
||||
/// A flex fraction specified in `fr` units.
|
||||
#[css(dimension)]
|
||||
Fr(CSSFloat),
|
||||
/// One of the track-sizing keywords (`auto`, `min-content`, `max-content`)
|
||||
Keyword(TrackKeyword),
|
||||
/// `auto`
|
||||
Auto,
|
||||
/// `min-content`
|
||||
MinContent,
|
||||
/// `max-content`
|
||||
MaxContent,
|
||||
}
|
||||
|
||||
pub use self::GenericTrackBreadth as TrackBreadth;
|
||||
|
||||
impl<L> TrackBreadth<L> {
|
||||
/// Check whether this is a `<fixed-breadth>` (i.e., it only has `<length-percentage>`)
|
||||
///
|
||||
|
@ -221,23 +230,40 @@ impl<L> TrackBreadth<L> {
|
|||
/// generic only to avoid code bloat. It only takes `<length-percentage>`
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#typedef-track-size>
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToResolvedValue, ToShmem)]
|
||||
pub enum TrackSize<L> {
|
||||
///
|
||||
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericTrackSize<L> {
|
||||
/// A flexible `<track-breadth>`
|
||||
Breadth(TrackBreadth<L>),
|
||||
Breadth(GenericTrackBreadth<L>),
|
||||
/// A `minmax` function for a range over an inflexible `<track-breadth>`
|
||||
/// and a flexible `<track-breadth>`
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax>
|
||||
#[css(function)]
|
||||
Minmax(TrackBreadth<L>, TrackBreadth<L>),
|
||||
Minmax(GenericTrackBreadth<L>, GenericTrackBreadth<L>),
|
||||
/// A `fit-content` function.
|
||||
///
|
||||
/// This stores a TrackBreadth<L> for convenience, but it can only be a
|
||||
/// LengthPercentage.
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-fit-content>
|
||||
#[css(function)]
|
||||
FitContent(L),
|
||||
FitContent(GenericTrackBreadth<L>),
|
||||
}
|
||||
|
||||
pub use self::GenericTrackSize as TrackSize;
|
||||
|
||||
impl<L> TrackSize<L> {
|
||||
/// Check whether this is a `<fixed-size>`
|
||||
///
|
||||
|
@ -266,7 +292,7 @@ impl<L> TrackSize<L> {
|
|||
|
||||
impl<L> Default for TrackSize<L> {
|
||||
fn default() -> Self {
|
||||
TrackSize::Breadth(TrackBreadth::Keyword(TrackKeyword::Auto))
|
||||
TrackSize::Breadth(TrackBreadth::Auto)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +313,7 @@ impl<L: ToCss> ToCss for TrackSize<L> {
|
|||
TrackSize::Minmax(ref min, ref max) => {
|
||||
// According to gecko minmax(auto, <flex>) is equivalent to <flex>,
|
||||
// and both are serialized as <flex>.
|
||||
if let TrackBreadth::Keyword(TrackKeyword::Auto) = *min {
|
||||
if let TrackBreadth::Auto = *min {
|
||||
if let TrackBreadth::Fr(_) = *max {
|
||||
return max.to_css(dest);
|
||||
}
|
||||
|
@ -308,48 +334,6 @@ impl<L: ToCss> ToCss for TrackSize<L> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<L: ToComputedValue> ToComputedValue for TrackSize<L> {
|
||||
type ComputedValue = TrackSize<L::ComputedValue>;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
TrackSize::Breadth(TrackBreadth::Fr(ref f)) => {
|
||||
// <flex> outside `minmax()` expands to `mimmax(auto, <flex>)`
|
||||
// https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-flex
|
||||
// FIXME(nox): This sounds false, the spec just says that <flex>
|
||||
// implies `minmax(auto, <flex>)`, not that it should be changed
|
||||
// into `minmax` at computed value time.
|
||||
TrackSize::Minmax(
|
||||
TrackBreadth::Keyword(TrackKeyword::Auto),
|
||||
TrackBreadth::Fr(f.to_computed_value(context)),
|
||||
)
|
||||
},
|
||||
TrackSize::Breadth(ref b) => TrackSize::Breadth(b.to_computed_value(context)),
|
||||
TrackSize::Minmax(ref b1, ref b2) => {
|
||||
TrackSize::Minmax(b1.to_computed_value(context), b2.to_computed_value(context))
|
||||
},
|
||||
TrackSize::FitContent(ref lp) => TrackSize::FitContent(lp.to_computed_value(context)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
match *computed {
|
||||
TrackSize::Breadth(ref b) => {
|
||||
TrackSize::Breadth(ToComputedValue::from_computed_value(b))
|
||||
},
|
||||
TrackSize::Minmax(ref b1, ref b2) => TrackSize::Minmax(
|
||||
ToComputedValue::from_computed_value(b1),
|
||||
ToComputedValue::from_computed_value(b2),
|
||||
),
|
||||
TrackSize::FitContent(ref lp) => {
|
||||
TrackSize::FitContent(ToComputedValue::from_computed_value(lp))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function for serializing identifiers with a prefix and suffix, used
|
||||
/// for serializing <line-names> (in grid).
|
||||
pub fn concat_serialize_idents<W>(
|
||||
|
|
|
@ -103,7 +103,12 @@ pub enum CounterStyleOrNone {
|
|||
Name(CustomIdent),
|
||||
/// `symbols()`
|
||||
#[css(function)]
|
||||
Symbols(SymbolsType, Symbols),
|
||||
Symbols(#[css(skip_if = "is_symbolic")] SymbolsType, Symbols),
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_symbolic(symbols_type: &SymbolsType) -> bool {
|
||||
*symbols_type == SymbolsType::Symbolic
|
||||
}
|
||||
|
||||
impl CounterStyleOrNone {
|
||||
|
@ -227,6 +232,28 @@ impl<T: Zero> Zero for NonNegative<T> {
|
|||
)]
|
||||
pub struct GreaterThanOrEqualToOne<T>(pub T);
|
||||
|
||||
/// A wrapper of values between zero and one.
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(transparent)]
|
||||
pub struct ZeroToOne<T>(pub T);
|
||||
|
||||
/// A clip rect for clip and image-region
|
||||
#[allow(missing_docs)]
|
||||
#[derive(
|
||||
|
|
|
@ -5,14 +5,11 @@
|
|||
//! Generic types for CSS values in SVG
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::{Either, None_};
|
||||
use cssparser::Parser;
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use style_traits::ParseError;
|
||||
|
||||
/// An SVG paint value
|
||||
///
|
||||
/// <https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint>
|
||||
#[animation(no_bound(UrlPaintServer))]
|
||||
/// The fallback of an SVG paint server value.
|
||||
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
|
@ -20,26 +17,35 @@ use style_traits::{ParseError, StyleParseErrorKind};
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub struct SVGPaint<ColorType, UrlPaintServer> {
|
||||
/// The paint source
|
||||
pub kind: SVGPaintKind<ColorType, UrlPaintServer>,
|
||||
/// The fallback color. It would be empty, the `none` keyword or <color>.
|
||||
pub fallback: Option<Either<ColorType, None_>>,
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericSVGPaintFallback<C> {
|
||||
/// The `none` keyword.
|
||||
None,
|
||||
/// A magic value that represents no fallback specified and serializes to
|
||||
/// the empty string.
|
||||
#[css(skip)]
|
||||
Unset,
|
||||
/// A color.
|
||||
Color(C),
|
||||
}
|
||||
|
||||
/// An SVG paint value without the fallback
|
||||
pub use self::GenericSVGPaintFallback as SVGPaintFallback;
|
||||
|
||||
/// An SVG paint value
|
||||
///
|
||||
/// Whereas the spec only allows PaintServer
|
||||
/// to have a fallback, Gecko lets the context
|
||||
/// properties have a fallback as well.
|
||||
#[animation(no_bound(UrlPaintServer))]
|
||||
/// <https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint>
|
||||
///
|
||||
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||
#[animation(no_bound(Url))]
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
|
@ -55,80 +61,82 @@ pub struct SVGPaint<ColorType, UrlPaintServer> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum SVGPaintKind<ColorType, UrlPaintServer> {
|
||||
#[repr(C)]
|
||||
pub struct GenericSVGPaint<Color, Url> {
|
||||
/// The paint source.
|
||||
pub kind: GenericSVGPaintKind<Color, Url>,
|
||||
/// The fallback color.
|
||||
pub fallback: GenericSVGPaintFallback<Color>,
|
||||
}
|
||||
|
||||
pub use self::GenericSVGPaint as SVGPaint;
|
||||
|
||||
impl<C, U> Default for SVGPaint<C, U> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kind: SVGPaintKind::None,
|
||||
fallback: SVGPaintFallback::Unset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An SVG paint value without the fallback.
|
||||
///
|
||||
/// Whereas the spec only allows PaintServer to have a fallback, Gecko lets the
|
||||
/// context properties have a fallback as well.
|
||||
///
|
||||
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||
#[animation(no_bound(U))]
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
Parse,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericSVGPaintKind<C, U> {
|
||||
/// `none`
|
||||
#[animation(error)]
|
||||
None,
|
||||
/// `<color>`
|
||||
Color(ColorType),
|
||||
Color(C),
|
||||
/// `url(...)`
|
||||
#[animation(error)]
|
||||
PaintServer(UrlPaintServer),
|
||||
PaintServer(U),
|
||||
/// `context-fill`
|
||||
ContextFill,
|
||||
/// `context-stroke`
|
||||
ContextStroke,
|
||||
}
|
||||
|
||||
impl<ColorType, UrlPaintServer> SVGPaintKind<ColorType, UrlPaintServer> {
|
||||
/// Parse a keyword value only
|
||||
fn parse_ident<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"none" => Ok(SVGPaintKind::None),
|
||||
"context-fill" => Ok(SVGPaintKind::ContextFill),
|
||||
"context-stroke" => Ok(SVGPaintKind::ContextStroke),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use self::GenericSVGPaintKind as SVGPaintKind;
|
||||
|
||||
/// Parse SVGPaint's fallback.
|
||||
/// fallback is keyword(none), Color or empty.
|
||||
/// <https://svgwg.org/svg2-draft/painting.html#SpecifyingPaint>
|
||||
fn parse_fallback<'i, 't, ColorType: Parse>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Option<Either<ColorType, None_>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
Some(Either::Second(None_))
|
||||
} else {
|
||||
if let Ok(color) = input.try(|i| ColorType::parse(context, i)) {
|
||||
Some(Either::First(color))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlPaintServer> {
|
||||
impl<C: Parse, U: Parse> Parse for SVGPaint<C, U> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(url) = input.try(|i| UrlPaintServer::parse(context, i)) {
|
||||
Ok(SVGPaint {
|
||||
kind: SVGPaintKind::PaintServer(url),
|
||||
fallback: parse_fallback(context, input),
|
||||
})
|
||||
} else if let Ok(kind) = input.try(SVGPaintKind::parse_ident) {
|
||||
if let SVGPaintKind::None = kind {
|
||||
Ok(SVGPaint {
|
||||
kind: kind,
|
||||
fallback: None,
|
||||
})
|
||||
} else {
|
||||
Ok(SVGPaint {
|
||||
kind: kind,
|
||||
fallback: parse_fallback(context, input),
|
||||
})
|
||||
}
|
||||
} else if let Ok(color) = input.try(|i| ColorType::parse(context, i)) {
|
||||
Ok(SVGPaint {
|
||||
kind: SVGPaintKind::Color(color),
|
||||
fallback: None,
|
||||
})
|
||||
} else {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
let kind = SVGPaintKind::parse(context, input)?;
|
||||
if matches!(kind, SVGPaintKind::None | SVGPaintKind::Color(..)) {
|
||||
return Ok(SVGPaint {
|
||||
kind,
|
||||
fallback: SVGPaintFallback::Unset,
|
||||
});
|
||||
}
|
||||
let fallback = input
|
||||
.try(|i| SVGPaintFallback::parse(context, i))
|
||||
.unwrap_or(SVGPaintFallback::Unset);
|
||||
Ok(SVGPaint { kind, fallback })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,14 +179,17 @@ pub enum SVGLength<L> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum SVGStrokeDashArray<L> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericSVGStrokeDashArray<L> {
|
||||
/// `[ <length> | <percentage> | <number> ]#`
|
||||
#[css(comma)]
|
||||
Values(#[css(if_empty = "none", iterable)] Vec<L>),
|
||||
Values(#[css(if_empty = "none", iterable)] crate::OwnedSlice<L>),
|
||||
/// `context-value`
|
||||
ContextValue,
|
||||
}
|
||||
|
||||
pub use self::GenericSVGStrokeDashArray as SVGStrokeDashArray;
|
||||
|
||||
/// An SVG opacity value accepts `context-{fill,stroke}-opacity` in
|
||||
/// addition to opacity value.
|
||||
#[derive(
|
||||
|
@ -197,7 +208,8 @@ pub enum SVGStrokeDashArray<L> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum SVGOpacity<OpacityType> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericSVGOpacity<OpacityType> {
|
||||
/// `<opacity-value>`
|
||||
Opacity(OpacityType),
|
||||
/// `context-fill-opacity`
|
||||
|
@ -207,3 +219,5 @@ pub enum SVGOpacity<OpacityType> {
|
|||
#[animation(error)]
|
||||
ContextStrokeOpacity,
|
||||
}
|
||||
|
||||
pub use self::GenericSVGOpacity as SVGOpacity;
|
||||
|
|
|
@ -75,7 +75,7 @@ fn line_height_moz_block_height_enabled(context: &ParserContext) -> bool {
|
|||
use crate::gecko_bindings::structs;
|
||||
context.in_ua_sheet() ||
|
||||
unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_line_height_moz_block_height_content_enabled
|
||||
structs::StaticPrefs::sVarCache_layout_css_line_height_moz_block_height_content_enabled
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -542,11 +542,7 @@ impl<T: ToMatrix> Transform<T> {
|
|||
)
|
||||
};
|
||||
|
||||
let (m, is_3d) = match self.to_transform_3d_matrix_f64(reference_box) {
|
||||
Ok(result) => result,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
let (m, is_3d) = self.to_transform_3d_matrix_f64(reference_box)?;
|
||||
Ok((cast_3d_transform(m), is_3d))
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ pub type Polygon = generic::GenericPolygon<LengthPercentage>;
|
|||
fn is_clip_path_path_enabled(context: &ParserContext) -> bool {
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
context.chrome_rules_enabled() ||
|
||||
unsafe { mozilla::StaticPrefs_sVarCache_layout_css_clip_path_path_enabled }
|
||||
unsafe { mozilla::StaticPrefs::sVarCache_layout_css_clip_path_path_enabled }
|
||||
}
|
||||
#[cfg(feature = "servo")]
|
||||
fn is_clip_path_path_enabled(_: &ParserContext) -> bool {
|
||||
|
|
|
@ -242,7 +242,7 @@ impl Parse for BorderSpacing {
|
|||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Size2D::parse_with(context, input, |context, input| {
|
||||
NonNegativeLength::parse_quirky(context, input, AllowQuirks::Yes).map(From::from)
|
||||
NonNegativeLength::parse_quirky(context, input, AllowQuirks::Yes)
|
||||
})
|
||||
.map(GenericBorderSpacing)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
|||
fn moz_display_values_enabled(context: &ParserContext) -> bool {
|
||||
use crate::gecko_bindings::structs;
|
||||
context.in_ua_or_chrome_sheet() ||
|
||||
unsafe { structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled }
|
||||
unsafe { structs::StaticPrefs::sVarCache_layout_css_xul_display_values_content_enabled }
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -33,7 +33,7 @@ fn moz_box_display_values_enabled(context: &ParserContext) -> bool {
|
|||
use crate::gecko_bindings::structs;
|
||||
context.in_ua_or_chrome_sheet() ||
|
||||
unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_xul_box_display_values_content_enabled
|
||||
structs::StaticPrefs::sVarCache_layout_css_xul_box_display_values_content_enabled
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::parser::{Parse, ParserContext};
|
|||
use crate::values::computed::effects::BoxShadow as ComputedBoxShadow;
|
||||
use crate::values::computed::effects::SimpleShadow as ComputedSimpleShadow;
|
||||
use crate::values::computed::NonNegativeNumber as ComputedNonNegativeNumber;
|
||||
use crate::values::computed::ZeroToOneNumber as ComputedZeroToOneNumber;
|
||||
use crate::values::computed::{Context, ToComputedValue};
|
||||
use crate::values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
use crate::values::generics::effects::Filter as GenericFilter;
|
||||
|
@ -30,74 +31,98 @@ pub type BoxShadow =
|
|||
|
||||
/// A specified value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type SpecifiedFilter =
|
||||
GenericFilter<Angle, Factor, NonNegativeLength, SimpleShadow, SpecifiedUrl>;
|
||||
pub type SpecifiedFilter = GenericFilter<
|
||||
Angle,
|
||||
NonNegativeFactor,
|
||||
ZeroToOneFactor,
|
||||
NonNegativeLength,
|
||||
SimpleShadow,
|
||||
SpecifiedUrl,
|
||||
>;
|
||||
|
||||
/// A specified value for a single `filter`.
|
||||
#[cfg(feature = "servo")]
|
||||
pub type SpecifiedFilter = GenericFilter<Angle, Factor, NonNegativeLength, Impossible, Impossible>;
|
||||
pub type SpecifiedFilter = GenericFilter<
|
||||
Angle,
|
||||
NonNegativeFactor,
|
||||
ZeroToOneFactor,
|
||||
NonNegativeLength,
|
||||
Impossible,
|
||||
Impossible,
|
||||
>;
|
||||
|
||||
pub use self::SpecifiedFilter as Filter;
|
||||
|
||||
/// A value for the `<factor>` parts in `Filter`.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
pub struct Factor(NumberOrPercentage);
|
||||
pub struct NonNegativeFactor(NumberOrPercentage);
|
||||
|
||||
impl Factor {
|
||||
/// Parse this factor but clamp to one if the value is over 100%.
|
||||
#[inline]
|
||||
pub fn parse_with_clamping_to_one<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Factor::parse(context, input).map(|v| v.clamp_to_one())
|
||||
}
|
||||
/// A value for the `<factor>` parts in `Filter` which clamps to one.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
pub struct ZeroToOneFactor(NumberOrPercentage);
|
||||
|
||||
/// Clamp the value to 1 if the value is over 100%.
|
||||
#[inline]
|
||||
fn clamp_to_one(self) -> Self {
|
||||
match self.0 {
|
||||
NumberOrPercentage::Percentage(percent) => {
|
||||
Factor(NumberOrPercentage::Percentage(percent.clamp_to_hundred()))
|
||||
},
|
||||
NumberOrPercentage::Number(number) => {
|
||||
Factor(NumberOrPercentage::Number(number.clamp_to_one()))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
Factor(NumberOrPercentage::Number(Number::new(1.0)))
|
||||
/// Clamp the value to 1 if the value is over 100%.
|
||||
#[inline]
|
||||
fn clamp_to_one(number: NumberOrPercentage) -> NumberOrPercentage {
|
||||
match number {
|
||||
NumberOrPercentage::Percentage(percent) => {
|
||||
NumberOrPercentage::Percentage(percent.clamp_to_hundred())
|
||||
},
|
||||
NumberOrPercentage::Number(number) => NumberOrPercentage::Number(number.clamp_to_one()),
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Factor {
|
||||
macro_rules! factor_impl_common {
|
||||
($ty:ty, $computed_ty:ty) => {
|
||||
impl $ty {
|
||||
fn one() -> Self {
|
||||
Self(NumberOrPercentage::Number(Number::new(1.)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for $ty {
|
||||
type ComputedValue = $computed_ty;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
use crate::values::computed::NumberOrPercentage;
|
||||
match self.0.to_computed_value(context) {
|
||||
NumberOrPercentage::Number(n) => n.into(),
|
||||
NumberOrPercentage::Percentage(p) => p.0.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Self(NumberOrPercentage::Number(
|
||||
ToComputedValue::from_computed_value(&computed.0),
|
||||
))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
factor_impl_common!(NonNegativeFactor, ComputedNonNegativeNumber);
|
||||
factor_impl_common!(ZeroToOneFactor, ComputedZeroToOneNumber);
|
||||
|
||||
impl Parse for NonNegativeFactor {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
NumberOrPercentage::parse_non_negative(context, input).map(Factor)
|
||||
NumberOrPercentage::parse_non_negative(context, input).map(Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for Factor {
|
||||
type ComputedValue = ComputedNonNegativeNumber;
|
||||
|
||||
impl Parse for ZeroToOneFactor {
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
use crate::values::computed::NumberOrPercentage;
|
||||
match self.0.to_computed_value(context) {
|
||||
NumberOrPercentage::Number(n) => n.into(),
|
||||
NumberOrPercentage::Percentage(p) => p.0.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Factor(NumberOrPercentage::Number(
|
||||
ToComputedValue::from_computed_value(&computed.0),
|
||||
))
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
NumberOrPercentage::parse_non_negative(context, input)
|
||||
.map(clamp_to_one)
|
||||
.map(Self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,19 +246,19 @@ impl Parse for Filter {
|
|||
.unwrap_or(Zero::zero()),
|
||||
)),
|
||||
"brightness" => Ok(GenericFilter::Brightness(
|
||||
i.try(|i| Factor::parse(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| NonNegativeFactor::parse(context, i))
|
||||
.unwrap_or(NonNegativeFactor::one()),
|
||||
)),
|
||||
"contrast" => Ok(GenericFilter::Contrast(
|
||||
i.try(|i| Factor::parse(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| NonNegativeFactor::parse(context, i))
|
||||
.unwrap_or(NonNegativeFactor::one()),
|
||||
)),
|
||||
"grayscale" => {
|
||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-grayscale
|
||||
Ok(GenericFilter::Grayscale(
|
||||
i.try(|i| Factor::parse_with_clamping_to_one(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
||||
.unwrap_or(ZeroToOneFactor::one()),
|
||||
))
|
||||
},
|
||||
"hue-rotate" => {
|
||||
|
@ -248,28 +273,28 @@ impl Parse for Filter {
|
|||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-invert
|
||||
Ok(GenericFilter::Invert(
|
||||
i.try(|i| Factor::parse_with_clamping_to_one(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
||||
.unwrap_or(ZeroToOneFactor::one()),
|
||||
))
|
||||
},
|
||||
"opacity" => {
|
||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-opacity
|
||||
Ok(GenericFilter::Opacity(
|
||||
i.try(|i| Factor::parse_with_clamping_to_one(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
||||
.unwrap_or(ZeroToOneFactor::one()),
|
||||
))
|
||||
},
|
||||
"saturate" => Ok(GenericFilter::Saturate(
|
||||
i.try(|i| Factor::parse(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| NonNegativeFactor::parse(context, i))
|
||||
.unwrap_or(NonNegativeFactor::one()),
|
||||
)),
|
||||
"sepia" => {
|
||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-sepia
|
||||
Ok(GenericFilter::Sepia(
|
||||
i.try(|i| Factor::parse_with_clamping_to_one(context, i))
|
||||
.unwrap_or(Factor::one()),
|
||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
||||
.unwrap_or(ZeroToOneFactor::one()),
|
||||
))
|
||||
},
|
||||
"drop-shadow" => Ok(GenericFilter::DropShadow(Parse::parse(context, i)?)),
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::computed::{self, Context, ToComputedValue};
|
||||
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth};
|
||||
use crate::values::generics::grid::{LineNameList, TrackKeyword, TrackRepeat, TrackSize};
|
||||
use crate::values::generics::grid::{LineNameList, TrackRepeat, TrackSize};
|
||||
use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue};
|
||||
use crate::values::specified::{Integer, LengthPercentage};
|
||||
use crate::values::{CSSFloat, CustomIdent};
|
||||
|
@ -27,11 +27,32 @@ pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseE
|
|||
}
|
||||
}
|
||||
|
||||
impl<L> TrackBreadth<L> {
|
||||
fn parse_keyword<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
#[derive(Parse)]
|
||||
enum TrackKeyword {
|
||||
Auto,
|
||||
MaxContent,
|
||||
MinContent,
|
||||
}
|
||||
|
||||
Ok(match TrackKeyword::parse(input)? {
|
||||
TrackKeyword::Auto => TrackBreadth::Auto,
|
||||
TrackKeyword::MaxContent => TrackBreadth::MaxContent,
|
||||
TrackKeyword::MinContent => TrackBreadth::MinContent,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for TrackBreadth<LengthPercentage> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// FIXME: This and other callers in this file should use
|
||||
// NonNegativeLengthPercentage instead.
|
||||
//
|
||||
// Though it seems these cannot be animated so it's ~ok.
|
||||
if let Ok(lp) = input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
||||
return Ok(TrackBreadth::Breadth(lp));
|
||||
}
|
||||
|
@ -40,7 +61,7 @@ impl Parse for TrackBreadth<LengthPercentage> {
|
|||
return Ok(TrackBreadth::Fr(f));
|
||||
}
|
||||
|
||||
TrackKeyword::parse(input).map(TrackBreadth::Keyword)
|
||||
Self::parse_keyword(input)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,10 +79,7 @@ impl Parse for TrackSize<LengthPercentage> {
|
|||
let inflexible_breadth =
|
||||
match input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
||||
Ok(lp) => TrackBreadth::Breadth(lp),
|
||||
Err(..) => {
|
||||
let keyword = TrackKeyword::parse(input)?;
|
||||
TrackBreadth::Keyword(keyword)
|
||||
},
|
||||
Err(..) => TrackBreadth::parse_keyword(input)?,
|
||||
};
|
||||
|
||||
input.expect_comma()?;
|
||||
|
@ -74,7 +92,7 @@ impl Parse for TrackSize<LengthPercentage> {
|
|||
|
||||
input.expect_function_matching("fit-content")?;
|
||||
let lp = input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?;
|
||||
Ok(TrackSize::FitContent(lp))
|
||||
Ok(TrackSize::FitContent(TrackBreadth::Breadth(lp)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,7 +399,7 @@ impl ToComputedValue for TrackList<LengthPercentage, Integer> {
|
|||
#[inline]
|
||||
fn allow_grid_template_subgrids() -> bool {
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
unsafe { mozilla::StaticPrefs_sVarCache_layout_css_grid_template_subgrid_value_enabled }
|
||||
unsafe { mozilla::StaticPrefs::sVarCache_layout_css_grid_template_subgrid_value_enabled }
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
|
|
|
@ -17,9 +17,9 @@ use crate::context::QuirksMode;
|
|||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::serialize_atom_identifier;
|
||||
use crate::values::specified::calc::CalcNode;
|
||||
use crate::{Atom, Namespace, Prefix};
|
||||
use crate::{Atom, Namespace, Prefix, Zero};
|
||||
use cssparser::{Parser, Token};
|
||||
use num_traits::{One, Zero};
|
||||
use num_traits::One;
|
||||
use std::f32;
|
||||
use std::fmt::{self, Write};
|
||||
use std::ops::Add;
|
||||
|
@ -74,14 +74,14 @@ pub use self::position::{PositionComponent, ZIndex};
|
|||
pub use self::rect::NonNegativeLengthOrNumberRect;
|
||||
pub use self::resolution::Resolution;
|
||||
pub use self::svg::MozContextProperties;
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint};
|
||||
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
|
||||
pub use self::svg_path::SVGPathData;
|
||||
pub use self::table::XSpan;
|
||||
pub use self::text::TextTransform;
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineBreak, LineHeight, TextAlign};
|
||||
pub use self::text::{OverflowWrap, TextEmphasisPosition, TextEmphasisStyle, WordBreak};
|
||||
pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing};
|
||||
pub use self::text::{TextDecorationSkipInk, TextTransform};
|
||||
pub use self::time::Time;
|
||||
pub use self::transform::{Rotate, Scale, Transform};
|
||||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||
|
@ -342,8 +342,6 @@ impl Parse for GreaterThanOrEqualToOneNumber {
|
|||
/// <number> | <percentage>
|
||||
///
|
||||
/// Accepts only non-negative numbers.
|
||||
///
|
||||
/// FIXME(emilio): Should probably use Either.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
pub enum NumberOrPercentage {
|
||||
|
@ -449,6 +447,18 @@ pub struct Integer {
|
|||
was_calc: bool,
|
||||
}
|
||||
|
||||
impl Zero for Integer {
|
||||
#[inline]
|
||||
fn zero() -> Self {
|
||||
Self::new(0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
self.value() == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl One for Integer {
|
||||
#[inline]
|
||||
fn one() -> Self {
|
||||
|
|
|
@ -18,10 +18,7 @@ use style_traits::{CommaWithSpace, CssWriter, ParseError, Separator};
|
|||
use style_traits::{StyleParseErrorKind, ToCss};
|
||||
|
||||
/// Specified SVG Paint value
|
||||
pub type SVGPaint = generic::SVGPaint<Color, SpecifiedUrl>;
|
||||
|
||||
/// Specified SVG Paint Kind value
|
||||
pub type SVGPaintKind = generic::SVGPaintKind<Color, SpecifiedUrl>;
|
||||
pub type SVGPaint = generic::GenericSVGPaint<Color, SpecifiedUrl>;
|
||||
|
||||
/// <length> | <percentage> | <number> | context-value
|
||||
pub type SVGLength = generic::SVGLength<LengthPercentage>;
|
||||
|
@ -36,7 +33,7 @@ pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthPerce
|
|||
#[cfg(feature = "gecko")]
|
||||
pub fn is_context_value_enabled() -> bool {
|
||||
use crate::gecko_bindings::structs::mozilla;
|
||||
unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled }
|
||||
unsafe { mozilla::StaticPrefs::sVarCache_gfx_font_rendering_opentype_svg_enabled }
|
||||
}
|
||||
|
||||
/// Whether the `context-value` value is enabled.
|
||||
|
@ -80,14 +77,14 @@ impl Parse for SVGStrokeDashArray {
|
|||
NonNegativeLengthPercentage::parse_quirky(context, i, AllowQuirks::Always)
|
||||
})
|
||||
}) {
|
||||
return Ok(generic::SVGStrokeDashArray::Values(values));
|
||||
return Ok(generic::SVGStrokeDashArray::Values(values.into()));
|
||||
}
|
||||
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"context-value" if is_context_value_enabled() => {
|
||||
Ok(generic::SVGStrokeDashArray::ContextValue)
|
||||
},
|
||||
"none" => Ok(generic::SVGStrokeDashArray::Values(vec![])),
|
||||
"none" => Ok(generic::SVGStrokeDashArray::Values(Default::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +197,7 @@ impl Parse for SVGPaintOrder {
|
|||
|
||||
// fill in rest
|
||||
for i in pos..PAINT_ORDER_COUNT {
|
||||
for paint in 0..PAINT_ORDER_COUNT {
|
||||
for paint in 1..(PAINT_ORDER_COUNT + 1) {
|
||||
// if not seen, set bit at position, mark as seen
|
||||
if (seen & (1 << paint)) == 0 {
|
||||
seen |= 1 << paint;
|
||||
|
|
|
@ -1054,3 +1054,28 @@ pub enum OverflowWrap {
|
|||
BreakWord,
|
||||
Anywhere,
|
||||
}
|
||||
|
||||
/// Implements text-decoration-skip-ink which takes the keywords auto | none
|
||||
///
|
||||
/// https://drafts.csswg.org/css-text-decor-4/#text-decoration-skip-ink-property
|
||||
#[repr(u8)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum TextDecorationSkipInk {
|
||||
Auto,
|
||||
None,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue