mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
style: Use cbindgen for grid track sizing.
Differential Revision: https://phabricator.services.mozilla.com/D36118
This commit is contained in:
parent
034557a717
commit
cc15afa348
6 changed files with 75 additions and 257 deletions
|
@ -14,14 +14,11 @@ use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||||
use crate::gecko_bindings::bindings;
|
use crate::gecko_bindings::bindings;
|
||||||
use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue, Matrix4x4Components};
|
use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue, Matrix4x4Components};
|
||||||
use crate::gecko_bindings::structs::{nsStyleImage, nsresult};
|
use crate::gecko_bindings::structs::{nsStyleImage, nsresult};
|
||||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
|
||||||
use crate::stylesheets::RulesMutateError;
|
use crate::stylesheets::RulesMutateError;
|
||||||
use crate::values::computed::transform::Matrix3D;
|
use crate::values::computed::transform::Matrix3D;
|
||||||
use crate::values::computed::url::ComputedImageUrl;
|
use crate::values::computed::url::ComputedImageUrl;
|
||||||
use crate::values::computed::{Angle, Gradient, Image};
|
use crate::values::computed::{Gradient, Image, LengthPercentage};
|
||||||
use crate::values::computed::{Integer, LengthPercentage};
|
|
||||||
use crate::values::computed::{Length, Percentage, TextAlign};
|
use crate::values::computed::{Length, Percentage, TextAlign};
|
||||||
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
|
||||||
use crate::values::generics::image::GenericImage;
|
use crate::values::generics::image::GenericImage;
|
||||||
use crate::values::generics::rect::Rect;
|
use crate::values::generics::rect::Rect;
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
|
@ -56,11 +53,6 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<Angle> for CoordDataValue {
|
|
||||||
fn from(reference: Angle) -> Self {
|
|
||||||
CoordDataValue::Degree(reference.degrees())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl nsStyleImage {
|
impl nsStyleImage {
|
||||||
/// Set a given Servo `Image` value into this `nsStyleImage`.
|
/// Set a given Servo `Image` value into this `nsStyleImage`.
|
||||||
|
@ -331,73 +323,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>
|
impl<T> Rect<T>
|
||||||
where
|
where
|
||||||
T: GeckoStyleCoordConvertible,
|
T: GeckoStyleCoordConvertible,
|
||||||
|
|
|
@ -7,12 +7,10 @@
|
||||||
//! Different kind of helpers to interact with Gecko values.
|
//! Different kind of helpers to interact with Gecko values.
|
||||||
|
|
||||||
use crate::counter_style::{Symbol, Symbols};
|
use crate::counter_style::{Symbol, Symbols};
|
||||||
use crate::gecko_bindings::structs::StyleGridTrackBreadth;
|
|
||||||
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
|
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
|
||||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
||||||
use crate::values::computed::{Angle, Length, LengthPercentage};
|
use crate::values::computed::{Length, LengthPercentage};
|
||||||
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
|
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
|
||||||
use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
|
|
||||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
use crate::values::generics::length::LengthPercentageOrAuto;
|
||||||
use crate::values::generics::{CounterStyleOrNone, NonNegative};
|
use crate::values::generics::{CounterStyleOrNone, NonNegative};
|
||||||
use crate::values::Either;
|
use crate::values::Either;
|
||||||
|
@ -154,41 +152,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
|
||||||
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
|
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
|
||||||
if let Some(ref me) = *self {
|
if let Some(ref me) = *self {
|
||||||
|
@ -203,19 +166,6 @@ impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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`.
|
/// Convert a given RGBA value to `nscolor`.
|
||||||
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
||||||
((rgba.alpha as u32) << 24) |
|
((rgba.alpha as u32) << 24) |
|
||||||
|
|
|
@ -36,7 +36,6 @@ use crate::gecko_bindings::bindings::Gecko_SetNullImageValue;
|
||||||
use crate::gecko_bindings::structs;
|
use crate::gecko_bindings::structs;
|
||||||
use crate::gecko_bindings::structs::nsCSSPropertyID;
|
use crate::gecko_bindings::structs::nsCSSPropertyID;
|
||||||
use crate::gecko_bindings::structs::mozilla::PseudoStyleType;
|
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_bindings::sugar::refptr::RefPtr;
|
||||||
use crate::gecko::values::round_border_to_device_pixels;
|
use crate::gecko::values::round_border_to_device_pixels;
|
||||||
use crate::logical_geometry::WritingMode;
|
use crate::logical_geometry::WritingMode;
|
||||||
|
@ -1075,7 +1074,6 @@ fn static_assert() {
|
||||||
skip_longhands="${skip_position_longhands} order
|
skip_longhands="${skip_position_longhands} order
|
||||||
align-content justify-content align-self
|
align-content justify-content align-self
|
||||||
justify-self align-items justify-items
|
justify-self align-items justify-items
|
||||||
grid-auto-rows grid-auto-columns
|
|
||||||
grid-auto-flow grid-template-rows
|
grid-auto-flow grid-template-rows
|
||||||
grid-template-columns">
|
grid-template-columns">
|
||||||
% for side in SIDES:
|
% for side in SIDES:
|
||||||
|
@ -1126,33 +1124,13 @@ fn static_assert() {
|
||||||
${impl_simple_copy('order', 'mOrder')}
|
${impl_simple_copy('order', 'mOrder')}
|
||||||
|
|
||||||
% for kind in ["rows", "columns"]:
|
% 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) {
|
pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
|
||||||
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
|
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
|
||||||
use crate::gecko_bindings::structs::nsTArray;
|
use crate::gecko_bindings::structs::nsTArray;
|
||||||
use std::usize;
|
use std::usize;
|
||||||
use crate::values::CustomIdent;
|
use crate::values::CustomIdent;
|
||||||
use crate::values::generics::grid::TrackListType::Auto;
|
use crate::values::generics::grid::TrackListType::Auto;
|
||||||
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, MAX_GRID_LINE};
|
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, TrackListValue, MAX_GRID_LINE};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<structs::RefPtr<structs::nsAtom>>) {
|
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<structs::RefPtr<structs::nsAtom>>) {
|
||||||
|
@ -1211,20 +1189,19 @@ fn static_assert() {
|
||||||
let mut line_names = track.line_names.into_iter();
|
let mut line_names = track.line_names.into_iter();
|
||||||
let mut values_iter = track.values.into_iter();
|
let mut values_iter = track.values.into_iter();
|
||||||
{
|
{
|
||||||
let min_max_iter = value.mMinTrackSizingFunctions.iter_mut()
|
for (i, track_size) in value.mTrackSizingFunctions.iter_mut().enumerate().take(max_lines) {
|
||||||
.zip(value.mMaxTrackSizingFunctions.iter_mut());
|
|
||||||
for (i, (gecko_min, gecko_max)) in min_max_iter.enumerate().take(max_lines) {
|
|
||||||
let name_list = line_names.next().expect("expected line-names");
|
let name_list = line_names.next().expect("expected line-names");
|
||||||
set_line_names(&name_list, &mut value.mLineNameLists[i]);
|
set_line_names(&name_list, &mut value.mLineNameLists[i]);
|
||||||
if i == auto_idx {
|
*track_size = if i == auto_idx {
|
||||||
let track_size = auto_track_size.take()
|
auto_track_size.take().expect("expected <track-size> for <auto-track-repeat>")
|
||||||
.expect("expected <track-size> for <auto-track-repeat>");
|
} else {
|
||||||
track_size.to_gecko_style_coords(gecko_min, gecko_max);
|
match values_iter.next().expect("expected <track-size> value") {
|
||||||
continue
|
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"),
|
||||||
}
|
}
|
||||||
|
};
|
||||||
let track_size = values_iter.next().expect("expected <track-size> value");
|
|
||||||
track_size.to_gecko_style_coords(gecko_min, gecko_max);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,7 +1256,7 @@ fn static_assert() {
|
||||||
use crate::gecko_bindings::structs::nsTArray;
|
use crate::gecko_bindings::structs::nsTArray;
|
||||||
use crate::values::CustomIdent;
|
use crate::values::CustomIdent;
|
||||||
use crate::values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount};
|
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() } {
|
let value = match unsafe { ${self_grid}.mPtr.as_ref() } {
|
||||||
None => return GridTemplateComponent::None,
|
None => return GridTemplateComponent::None,
|
||||||
|
@ -1321,13 +1298,8 @@ fn static_assert() {
|
||||||
let mut auto_repeat = None;
|
let mut auto_repeat = None;
|
||||||
let mut list_type = TrackListType::Normal;
|
let mut list_type = TrackListType::Normal;
|
||||||
let line_names = to_line_names_vec(&value.mLineNameLists).into_boxed_slice();
|
let line_names = to_line_names_vec(&value.mLineNameLists).into_boxed_slice();
|
||||||
let mut values = Vec::with_capacity(value.mMinTrackSizingFunctions.len());
|
let mut values = Vec::with_capacity(value.mTrackSizingFunctions.len());
|
||||||
|
for (i, track_size) in value.mTrackSizingFunctions.iter().enumerate() {
|
||||||
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);
|
|
||||||
|
|
||||||
if i == repeat_auto_index {
|
if i == repeat_auto_index {
|
||||||
list_type = TrackListType::Auto(repeat_auto_index as u16);
|
list_type = TrackListType::Auto(repeat_auto_index as u16);
|
||||||
|
|
||||||
|
@ -1346,11 +1318,11 @@ fn static_assert() {
|
||||||
vec.into_boxed_slice()
|
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});
|
auto_repeat = Some(TrackRepeat{count, line_names, track_sizes});
|
||||||
} else {
|
} else {
|
||||||
values.push(TrackListValue::TrackSize(track_size));
|
values.push(TrackListValue::TrackSize(track_size.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
use self::transform::DirectionVector;
|
use self::transform::DirectionVector;
|
||||||
use super::animated::ToAnimatedValue;
|
use super::animated::ToAnimatedValue;
|
||||||
use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||||
use super::generics::grid::{GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
use super::generics::grid::{GenericGridLine, GenericTrackBreadth};
|
||||||
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
use super::generics::grid::{TrackList as GenericTrackList, GenericTrackSize};
|
||||||
use super::generics::transform::IsParallelTo;
|
use super::generics::transform::IsParallelTo;
|
||||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
|
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
|
||||||
use super::specified;
|
use super::specified;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
use crate::{Atom, Zero};
|
use crate::{Atom, Zero};
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::values::computed::{Context, ToComputedValue};
|
|
||||||
use crate::values::specified;
|
use crate::values::specified;
|
||||||
use crate::values::specified::grid::parse_line_names;
|
use crate::values::specified::grid::parse_line_names;
|
||||||
use crate::values::{CSSFloat, CustomIdent};
|
use crate::values::{CSSFloat, CustomIdent};
|
||||||
|
@ -180,33 +179,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
|
/// A track breadth for explicit grid track sizing. It's generic solely to
|
||||||
/// avoid re-implementing it for the computed type.
|
/// avoid re-implementing it for the computed type.
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-grid/#typedef-track-breadth>
|
/// <https://drafts.csswg.org/css-grid/#typedef-track-breadth>
|
||||||
|
///
|
||||||
|
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||||
#[derive(
|
#[derive(
|
||||||
Animate,
|
Animate,
|
||||||
Clone,
|
Clone,
|
||||||
|
@ -219,16 +197,23 @@ pub enum TrackKeyword {
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
pub enum TrackBreadth<L> {
|
#[repr(C, u8)]
|
||||||
|
pub enum GenericTrackBreadth<L> {
|
||||||
/// The generic type is almost always a non-negative `<length-percentage>`
|
/// The generic type is almost always a non-negative `<length-percentage>`
|
||||||
Breadth(L),
|
Breadth(L),
|
||||||
/// A flex fraction specified in `fr` units.
|
/// A flex fraction specified in `fr` units.
|
||||||
#[css(dimension)]
|
#[css(dimension)]
|
||||||
Fr(CSSFloat),
|
Fr(CSSFloat),
|
||||||
/// One of the track-sizing keywords (`auto`, `min-content`, `max-content`)
|
/// `auto`
|
||||||
Keyword(TrackKeyword),
|
Auto,
|
||||||
|
/// `min-content`
|
||||||
|
MinContent,
|
||||||
|
/// `max-content`
|
||||||
|
MaxContent,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::GenericTrackBreadth as TrackBreadth;
|
||||||
|
|
||||||
impl<L> TrackBreadth<L> {
|
impl<L> TrackBreadth<L> {
|
||||||
/// Check whether this is a `<fixed-breadth>` (i.e., it only has `<length-percentage>`)
|
/// Check whether this is a `<fixed-breadth>` (i.e., it only has `<length-percentage>`)
|
||||||
///
|
///
|
||||||
|
@ -243,23 +228,31 @@ impl<L> TrackBreadth<L> {
|
||||||
/// generic only to avoid code bloat. It only takes `<length-percentage>`
|
/// generic only to avoid code bloat. It only takes `<length-percentage>`
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-grid/#typedef-track-size>
|
/// <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>`
|
/// A flexible `<track-breadth>`
|
||||||
Breadth(TrackBreadth<L>),
|
Breadth(GenericTrackBreadth<L>),
|
||||||
/// A `minmax` function for a range over an inflexible `<track-breadth>`
|
/// A `minmax` function for a range over an inflexible `<track-breadth>`
|
||||||
/// and a flexible `<track-breadth>`
|
/// and a flexible `<track-breadth>`
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax>
|
/// <https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax>
|
||||||
#[css(function)]
|
#[css(function)]
|
||||||
Minmax(TrackBreadth<L>, TrackBreadth<L>),
|
Minmax(GenericTrackBreadth<L>, GenericTrackBreadth<L>),
|
||||||
/// A `fit-content` function.
|
/// 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>
|
/// <https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-fit-content>
|
||||||
#[css(function)]
|
#[css(function)]
|
||||||
FitContent(L),
|
FitContent(GenericTrackBreadth<L>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::GenericTrackSize as TrackSize;
|
||||||
|
|
||||||
impl<L> TrackSize<L> {
|
impl<L> TrackSize<L> {
|
||||||
/// Check whether this is a `<fixed-size>`
|
/// Check whether this is a `<fixed-size>`
|
||||||
///
|
///
|
||||||
|
@ -288,7 +281,7 @@ impl<L> TrackSize<L> {
|
||||||
|
|
||||||
impl<L> Default for TrackSize<L> {
|
impl<L> Default for TrackSize<L> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
TrackSize::Breadth(TrackBreadth::Keyword(TrackKeyword::Auto))
|
TrackSize::Breadth(TrackBreadth::Auto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +302,7 @@ impl<L: ToCss> ToCss for TrackSize<L> {
|
||||||
TrackSize::Minmax(ref min, ref max) => {
|
TrackSize::Minmax(ref min, ref max) => {
|
||||||
// According to gecko minmax(auto, <flex>) is equivalent to <flex>,
|
// According to gecko minmax(auto, <flex>) is equivalent to <flex>,
|
||||||
// and both are serialized as <flex>.
|
// and both are serialized as <flex>.
|
||||||
if let TrackBreadth::Keyword(TrackKeyword::Auto) = *min {
|
if let TrackBreadth::Auto = *min {
|
||||||
if let TrackBreadth::Fr(_) = *max {
|
if let TrackBreadth::Fr(_) = *max {
|
||||||
return max.to_css(dest);
|
return max.to_css(dest);
|
||||||
}
|
}
|
||||||
|
@ -330,48 +323,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
|
/// Helper function for serializing identifiers with a prefix and suffix, used
|
||||||
/// for serializing <line-names> (in grid).
|
/// for serializing <line-names> (in grid).
|
||||||
pub fn concat_serialize_idents<W>(
|
pub fn concat_serialize_idents<W>(
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::values::computed::{self, Context, ToComputedValue};
|
use crate::values::computed::{self, Context, ToComputedValue};
|
||||||
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth};
|
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::generics::grid::{TrackList, TrackListType, TrackListValue};
|
||||||
use crate::values::specified::{Integer, LengthPercentage};
|
use crate::values::specified::{Integer, LengthPercentage};
|
||||||
use crate::values::{CSSFloat, CustomIdent};
|
use crate::values::{CSSFloat, CustomIdent};
|
||||||
|
@ -27,11 +27,34 @@ 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> {
|
impl Parse for TrackBreadth<LengthPercentage> {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> 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)) {
|
if let Ok(lp) = input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
||||||
return Ok(TrackBreadth::Breadth(lp));
|
return Ok(TrackBreadth::Breadth(lp));
|
||||||
}
|
}
|
||||||
|
@ -40,7 +63,7 @@ impl Parse for TrackBreadth<LengthPercentage> {
|
||||||
return Ok(TrackBreadth::Fr(f));
|
return Ok(TrackBreadth::Fr(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackKeyword::parse(input).map(TrackBreadth::Keyword)
|
Self::parse_keyword(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,10 +81,7 @@ impl Parse for TrackSize<LengthPercentage> {
|
||||||
let inflexible_breadth =
|
let inflexible_breadth =
|
||||||
match input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
match input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
||||||
Ok(lp) => TrackBreadth::Breadth(lp),
|
Ok(lp) => TrackBreadth::Breadth(lp),
|
||||||
Err(..) => {
|
Err(..) => TrackBreadth::parse_keyword(input)?,
|
||||||
let keyword = TrackKeyword::parse(input)?;
|
|
||||||
TrackBreadth::Keyword(keyword)
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
|
@ -74,7 +94,7 @@ impl Parse for TrackSize<LengthPercentage> {
|
||||||
|
|
||||||
input.expect_function_matching("fit-content")?;
|
input.expect_function_matching("fit-content")?;
|
||||||
let lp = input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?;
|
let lp = input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?;
|
||||||
Ok(TrackSize::FitContent(lp))
|
Ok(TrackSize::FitContent(TrackBreadth::Breadth(lp)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue