tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

counters.rs (7901B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 //! Generic types for counters-related CSS values.
      6 
      7 #[cfg(feature = "servo")]
      8 use crate::computed_values::list_style_type::T as ListStyleType;
      9 #[cfg(feature = "gecko")]
     10 use crate::counter_style::CounterStyle;
     11 use crate::derives::*;
     12 use crate::values::specified::Attr;
     13 use crate::values::CustomIdent;
     14 use std::fmt::{self, Write};
     15 use std::ops::Deref;
     16 use style_traits::{CssWriter, ToCss};
     17 
     18 /// A name / value pair for counters.
     19 #[derive(
     20    Clone,
     21    Debug,
     22    MallocSizeOf,
     23    PartialEq,
     24    SpecifiedValueInfo,
     25    ToComputedValue,
     26    ToResolvedValue,
     27    ToShmem,
     28 )]
     29 #[repr(C)]
     30 pub struct GenericCounterPair<Integer> {
     31    /// The name of the counter.
     32    pub name: CustomIdent,
     33    /// The value of the counter / increment / etc.
     34    pub value: Integer,
     35    /// If true, then this represents `reversed(name)`.
     36    /// NOTE: It can only be true on `counter-reset` values.
     37    pub is_reversed: bool,
     38 }
     39 pub use self::GenericCounterPair as CounterPair;
     40 
     41 impl<Integer> ToCss for CounterPair<Integer>
     42 where
     43    Integer: ToCss + PartialEq<i32>,
     44 {
     45    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     46    where
     47        W: Write,
     48    {
     49        if self.is_reversed {
     50            dest.write_str("reversed(")?;
     51        }
     52        self.name.to_css(dest)?;
     53        if self.is_reversed {
     54            dest.write_char(')')?;
     55            if self.value == i32::min_value() {
     56                return Ok(());
     57            }
     58        }
     59        dest.write_char(' ')?;
     60        self.value.to_css(dest)
     61    }
     62 }
     63 
     64 /// A generic value for the `counter-increment` property.
     65 #[derive(
     66    Clone,
     67    Debug,
     68    Default,
     69    MallocSizeOf,
     70    PartialEq,
     71    SpecifiedValueInfo,
     72    ToComputedValue,
     73    ToCss,
     74    ToResolvedValue,
     75    ToShmem,
     76    ToTyped,
     77 )]
     78 #[repr(transparent)]
     79 pub struct GenericCounterIncrement<I>(#[css(field_bound)] pub GenericCounters<I>);
     80 pub use self::GenericCounterIncrement as CounterIncrement;
     81 
     82 impl<I> CounterIncrement<I> {
     83    /// Returns a new value for `counter-increment`.
     84    #[inline]
     85    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
     86        CounterIncrement(Counters(counters.into()))
     87    }
     88 }
     89 
     90 impl<I> Deref for CounterIncrement<I> {
     91    type Target = [CounterPair<I>];
     92 
     93    #[inline]
     94    fn deref(&self) -> &Self::Target {
     95        &(self.0).0
     96    }
     97 }
     98 
     99 /// A generic value for the `counter-set` property.
    100 #[derive(
    101    Clone,
    102    Debug,
    103    Default,
    104    MallocSizeOf,
    105    PartialEq,
    106    SpecifiedValueInfo,
    107    ToComputedValue,
    108    ToCss,
    109    ToResolvedValue,
    110    ToShmem,
    111    ToTyped,
    112 )]
    113 #[repr(transparent)]
    114 pub struct GenericCounterSet<I>(#[css(field_bound)] pub GenericCounters<I>);
    115 pub use self::GenericCounterSet as CounterSet;
    116 
    117 impl<I> CounterSet<I> {
    118    /// Returns a new value for `counter-set`.
    119    #[inline]
    120    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
    121        CounterSet(Counters(counters.into()))
    122    }
    123 }
    124 
    125 impl<I> Deref for CounterSet<I> {
    126    type Target = [CounterPair<I>];
    127 
    128    #[inline]
    129    fn deref(&self) -> &Self::Target {
    130        &(self.0).0
    131    }
    132 }
    133 
    134 /// A generic value for the `counter-reset` property.
    135 #[derive(
    136    Clone,
    137    Debug,
    138    Default,
    139    MallocSizeOf,
    140    PartialEq,
    141    SpecifiedValueInfo,
    142    ToComputedValue,
    143    ToCss,
    144    ToResolvedValue,
    145    ToShmem,
    146    ToTyped,
    147 )]
    148 #[repr(transparent)]
    149 pub struct GenericCounterReset<I>(#[css(field_bound)] pub GenericCounters<I>);
    150 pub use self::GenericCounterReset as CounterReset;
    151 
    152 impl<I> CounterReset<I> {
    153    /// Returns a new value for `counter-reset`.
    154    #[inline]
    155    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
    156        CounterReset(Counters(counters.into()))
    157    }
    158 }
    159 
    160 impl<I> Deref for CounterReset<I> {
    161    type Target = [CounterPair<I>];
    162 
    163    #[inline]
    164    fn deref(&self) -> &Self::Target {
    165        &(self.0).0
    166    }
    167 }
    168 
    169 /// A generic value for lists of counters.
    170 ///
    171 /// Keyword `none` is represented by an empty vector.
    172 #[derive(
    173    Clone,
    174    Debug,
    175    Default,
    176    MallocSizeOf,
    177    PartialEq,
    178    SpecifiedValueInfo,
    179    ToComputedValue,
    180    ToCss,
    181    ToResolvedValue,
    182    ToShmem,
    183 )]
    184 #[repr(transparent)]
    185 pub struct GenericCounters<I>(
    186    #[css(field_bound)]
    187    #[css(iterable, if_empty = "none")]
    188    crate::OwnedSlice<GenericCounterPair<I>>,
    189 );
    190 pub use self::GenericCounters as Counters;
    191 
    192 #[cfg(feature = "servo")]
    193 type CounterStyleType = ListStyleType;
    194 
    195 #[cfg(feature = "gecko")]
    196 type CounterStyleType = CounterStyle;
    197 
    198 #[cfg(feature = "servo")]
    199 #[inline]
    200 fn is_decimal(counter_type: &CounterStyleType) -> bool {
    201    *counter_type == ListStyleType::Decimal
    202 }
    203 
    204 #[cfg(feature = "gecko")]
    205 #[inline]
    206 fn is_decimal(counter_type: &CounterStyleType) -> bool {
    207    *counter_type == CounterStyle::decimal()
    208 }
    209 
    210 /// The non-normal, non-none values of the content property.
    211 #[derive(
    212    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
    213 )]
    214 #[repr(C)]
    215 pub struct GenericContentItems<Image> {
    216    /// The actual content items. Note that, past the alt marker, only some subset (strings,
    217    /// attr(), counter())
    218    pub items: thin_vec::ThinVec<GenericContentItem<Image>>,
    219    /// The index at which alt text starts, always non-zero. If equal to items.len(), no alt text
    220    /// exists.
    221    pub alt_start: usize,
    222 }
    223 
    224 impl<Image> ToCss for GenericContentItems<Image>
    225 where
    226    Image: ToCss,
    227 {
    228    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    229    where
    230        W: Write,
    231    {
    232        for (i, item) in self.items.iter().enumerate() {
    233            if i == self.alt_start {
    234                dest.write_str(" /")?;
    235            }
    236            if i != 0 {
    237                dest.write_str(" ")?;
    238            }
    239            item.to_css(dest)?;
    240        }
    241        Ok(())
    242    }
    243 }
    244 
    245 /// The specified value for the `content` property.
    246 ///
    247 /// https://drafts.csswg.org/css-content/#propdef-content
    248 #[derive(
    249    Clone,
    250    Debug,
    251    Eq,
    252    MallocSizeOf,
    253    PartialEq,
    254    SpecifiedValueInfo,
    255    ToComputedValue,
    256    ToCss,
    257    ToShmem,
    258    ToTyped,
    259 )]
    260 #[repr(u8)]
    261 pub enum GenericContent<Image> {
    262    /// `normal` reserved keyword.
    263    Normal,
    264    /// `none` reserved keyword.
    265    None,
    266    /// Content items.
    267    Items(GenericContentItems<Image>),
    268 }
    269 
    270 pub use self::GenericContent as Content;
    271 
    272 impl<Image> Content<Image> {
    273    /// Whether `self` represents list of items.
    274    #[inline]
    275    pub fn is_items(&self) -> bool {
    276        matches!(*self, Self::Items(..))
    277    }
    278 
    279    /// Set `content` property to `normal`.
    280    #[inline]
    281    pub fn normal() -> Self {
    282        Content::Normal
    283    }
    284 }
    285 
    286 /// Items for the `content` property.
    287 #[derive(
    288    Clone,
    289    Debug,
    290    Eq,
    291    MallocSizeOf,
    292    PartialEq,
    293    ToComputedValue,
    294    SpecifiedValueInfo,
    295    ToCss,
    296    ToResolvedValue,
    297    ToShmem,
    298 )]
    299 #[repr(u8)]
    300 pub enum GenericContentItem<I> {
    301    /// Literal string content.
    302    String(crate::OwnedStr),
    303    /// `counter(name, style)`.
    304    #[css(comma, function)]
    305    Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
    306    /// `counters(name, separator, style)`.
    307    #[css(comma, function)]
    308    Counters(
    309        CustomIdent,
    310        crate::OwnedStr,
    311        #[css(skip_if = "is_decimal")] CounterStyleType,
    312    ),
    313    /// `open-quote`.
    314    OpenQuote,
    315    /// `close-quote`.
    316    CloseQuote,
    317    /// `no-open-quote`.
    318    NoOpenQuote,
    319    /// `no-close-quote`.
    320    NoCloseQuote,
    321    /// `-moz-alt-content`.
    322    #[cfg(feature = "gecko")]
    323    MozAltContent,
    324    /// `-moz-label-content`.
    325    /// This is needed to make `accesskey` work for XUL labels. It's basically
    326    /// attr(value) otherwise.
    327    #[cfg(feature = "gecko")]
    328    MozLabelContent,
    329    /// `attr([namespace? `|`]? ident)`
    330    Attr(Attr),
    331    /// image-set(url) | url(url)
    332    Image(I),
    333 }
    334 
    335 pub use self::GenericContentItem as ContentItem;