script/dom/css/
cssfontfacerule.rs1use std::cell::RefCell;
6
7use dom_struct::dom_struct;
8use js::context::JSContext;
9use script_bindings::dom::MutNullableDom;
10use script_bindings::reflector::reflect_dom_object;
11use servo_arc::Arc;
12use style::font_face::DescriptorId;
13use style::shared_lock::{Locked, ToCssWithGuard};
14use style::stylesheets::{CssRuleType, FontFaceRule};
15
16use super::cssrule::{CSSRule, SpecificCSSRule};
17use super::cssstylesheet::CSSStyleSheet;
18use crate::dom::bindings::codegen::Bindings::CSSFontFaceRuleBinding::CSSFontFaceRuleMethods;
19use crate::dom::bindings::reflector::DomGlobal;
20use crate::dom::bindings::root::DomRoot;
21use crate::dom::bindings::str::DOMString;
22use crate::dom::css::cssfontfacedescriptors::CSSFontFaceDescriptors;
23use crate::dom::cssgroupingrule::CSSGroupingRule;
24use crate::dom::window::Window;
25
26#[dom_struct]
27pub(crate) struct CSSFontFaceRule {
28 css_rule: CSSRule,
29 #[ignore_malloc_size_of = "Stylo"]
30 #[no_trace]
31 font_face_rule: RefCell<Arc<Locked<FontFaceRule>>>,
32 descriptors: MutNullableDom<CSSFontFaceDescriptors>,
33}
34
35impl CSSFontFaceRule {
36 fn new_inherited(
37 parent_rule: Option<&CSSGroupingRule>,
38 parent_stylesheet: &CSSStyleSheet,
39 fontfacerule: Arc<Locked<FontFaceRule>>,
40 ) -> CSSFontFaceRule {
41 CSSFontFaceRule {
42 css_rule: CSSRule::new_inherited(parent_rule, parent_stylesheet),
43 font_face_rule: RefCell::new(fontfacerule),
44 descriptors: Default::default(),
45 }
46 }
47
48 pub(crate) fn new(
49 cx: &mut JSContext,
50 window: &Window,
51 parent_rule: Option<&CSSGroupingRule>,
52 parent_stylesheet: &CSSStyleSheet,
53 fontfacerule: Arc<Locked<FontFaceRule>>,
54 ) -> DomRoot<CSSFontFaceRule> {
55 reflect_dom_object(
56 cx,
57 Box::new(CSSFontFaceRule::new_inherited(
58 parent_rule,
59 parent_stylesheet,
60 fontfacerule,
61 )),
62 window,
63 )
64 }
65
66 pub(crate) fn update_rule(&self, fontfacerule: Arc<Locked<FontFaceRule>>) {
67 *self.font_face_rule.borrow_mut() = fontfacerule;
68 }
69
70 pub(crate) fn get_descriptor(&self, descriptor_id: DescriptorId) -> DOMString {
72 let guard = self.css_rule.shared_lock().read();
73 let mut result = String::new();
74 self.font_face_rule
75 .borrow()
76 .read_with(&guard)
77 .descriptors
78 .get(descriptor_id, &mut result)
79 .expect("Writing to a string should never fail");
80
81 result.into()
82 }
83
84 pub(crate) fn get_descriptor_by_index(&self, index: u32) -> Option<DOMString> {
86 let guard = self.css_rule.shared_lock().read();
87 let descriptor_id_at_index = self
88 .font_face_rule
89 .borrow()
90 .read_with(&guard)
91 .descriptors
92 .at(index as usize)?;
93 Some(self.get_descriptor(descriptor_id_at_index))
94 }
95
96 pub(crate) fn descriptor_length(&self) -> usize {
98 let guard = self.css_rule.shared_lock().read();
99 self.font_face_rule
100 .borrow()
101 .read_with(&guard)
102 .descriptors
103 .len()
104 }
105}
106
107impl SpecificCSSRule for CSSFontFaceRule {
108 fn ty(&self) -> CssRuleType {
109 CssRuleType::FontFace
110 }
111
112 fn get_css(&self) -> DOMString {
113 let guard = self.css_rule.shared_lock().read();
114 self.font_face_rule
115 .borrow()
116 .read_with(&guard)
117 .to_css_string(&guard)
118 .into()
119 }
120}
121
122impl CSSFontFaceRuleMethods<crate::DomTypeHolder> for CSSFontFaceRule {
123 fn Style(&self, cx: &mut JSContext) -> DomRoot<CSSFontFaceDescriptors> {
124 self.descriptors.or_init(|| {
125 let global = self.css_rule.global();
126 CSSFontFaceDescriptors::new(cx, &global, self)
127 })
128 }
129}