Skip to main content

script/dom/css/
cssfontfeaturevaluesmap.rs

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
5use dom_struct::dom_struct;
6use indexmap::IndexMap;
7use js::context::JSContext;
8use script_bindings::cell::DomRefCell;
9use script_bindings::like::Maplike;
10use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
11use style::stylesheets::font_feature_values_rule::{
12    FFVDeclaration, PairValues, SingleValue, VectorValues,
13};
14
15use crate::dom::GlobalScope;
16use crate::dom::bindings::codegen::Bindings::CSSFontFeatureValuesRuleBinding::CSSFontFeatureValuesMapMethods;
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::maplike;
20
21/// <https://drafts.csswg.org/css-fonts/#cssfontfeaturevaluesmap>
22#[dom_struct]
23pub(crate) struct CSSFontFeatureValuesMap {
24    reflector: Reflector,
25
26    /// The map from identifiers to font feature values, derived from a single block
27    /// of the `@font-feature-values` rule.
28    #[custom_trace]
29    internal: DomRefCell<IndexMap<DOMString, Vec<u32>>>,
30}
31
32impl CSSFontFeatureValuesMap {
33    fn new_inherited(map: IndexMap<DOMString, Vec<u32>>) -> CSSFontFeatureValuesMap {
34        CSSFontFeatureValuesMap {
35            reflector: Reflector::new(),
36            internal: DomRefCell::new(map),
37        }
38    }
39
40    pub(crate) fn new(
41        cx: &mut JSContext,
42        global: &GlobalScope,
43        map: IndexMap<DOMString, Vec<u32>>,
44    ) -> DomRoot<CSSFontFeatureValuesMap> {
45        reflect_dom_object_with_cx(
46            Box::new(CSSFontFeatureValuesMap::new_inherited(map)),
47            global,
48            cx,
49        )
50    }
51
52    pub(crate) fn build_from<DeclarationValue>(
53        cx: &mut JSContext,
54        global: &GlobalScope,
55        declarations: &[FFVDeclaration<DeclarationValue>],
56    ) -> DomRoot<Self>
57    where
58        DeclarationValue: AsValues,
59    {
60        let mut map = IndexMap::default();
61        for declaration in declarations {
62            map.insert(
63                declaration.name.to_string().into(),
64                declaration.value.as_vec(),
65            );
66        }
67        Self::new(cx, global, map)
68    }
69}
70
71impl Maplike for CSSFontFeatureValuesMap {
72    type Key = DOMString;
73    type Value = Vec<u32>;
74
75    maplike!(self, internal);
76}
77
78impl CSSFontFeatureValuesMapMethods<crate::DomTypeHolder> for CSSFontFeatureValuesMap {
79    fn Size(&self) -> u32 {
80        self.internal.borrow().len() as u32
81    }
82}
83
84/// A trait to generalize over [SingleValue], [PairValues] and [VectorValues].
85pub(crate) trait AsValues {
86    fn as_vec(&self) -> Vec<u32>;
87}
88
89impl AsValues for SingleValue {
90    fn as_vec(&self) -> Vec<u32> {
91        vec![self.0]
92    }
93}
94
95impl AsValues for PairValues {
96    fn as_vec(&self) -> Vec<u32> {
97        let mut result = vec![self.0];
98        if let Some(second_value) = self.1 {
99            result.push(second_value);
100        }
101        result
102    }
103}
104
105impl AsValues for VectorValues {
106    fn as_vec(&self) -> Vec<u32> {
107        self.0.clone()
108    }
109}