script/dom/css/
cssgroupingrule.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use servo_arc::Arc;
8use style::shared_lock::{Locked, SharedRwLock, SharedRwLockReadGuard};
9use style::stylesheets::CssRules;
10
11use super::cssconditionrule::CSSConditionRule;
12use super::csslayerblockrule::CSSLayerBlockRule;
13use super::cssrule::CSSRule;
14use super::cssrulelist::{CSSRuleList, RulesSource};
15use super::cssstylerule::CSSStyleRule;
16use super::cssstylesheet::CSSStyleSheet;
17use crate::dom::bindings::codegen::Bindings::CSSGroupingRuleBinding::CSSGroupingRuleMethods;
18use crate::dom::bindings::error::{ErrorResult, Fallible};
19use crate::dom::bindings::inheritance::Castable;
20use crate::dom::bindings::reflector::DomGlobal;
21use crate::dom::bindings::root::{DomRoot, MutNullableDom};
22use crate::dom::bindings::str::DOMString;
23
24#[dom_struct]
25pub(crate) struct CSSGroupingRule {
26 css_rule: CSSRule,
27 rule_list: MutNullableDom<CSSRuleList>,
28}
29
30impl CSSGroupingRule {
31 pub(crate) fn new_inherited(
32 parent_rule: Option<&CSSGroupingRule>,
33 parent_stylesheet: &CSSStyleSheet,
34 ) -> CSSGroupingRule {
35 CSSGroupingRule {
36 css_rule: CSSRule::new_inherited(parent_rule, parent_stylesheet),
37 rule_list: MutNullableDom::new(None),
38 }
39 }
40
41 fn rulelist(&self, cx: &mut JSContext) -> DomRoot<CSSRuleList> {
42 let parent_stylesheet = self.upcast::<CSSRule>().parent_stylesheet();
43 self.rule_list.or_init(|| {
44 let rules = if let Some(rule) = self.downcast::<CSSConditionRule>() {
45 rule.clone_rules()
46 } else if let Some(rule) = self.downcast::<CSSLayerBlockRule>() {
47 rule.clone_rules()
48 } else if let Some(rule) = self.downcast::<CSSStyleRule>() {
49 rule.ensure_rules()
50 } else {
51 unreachable!()
52 };
53 CSSRuleList::new(
54 cx,
55 self.global().as_window(),
56 Some(self),
57 parent_stylesheet,
58 RulesSource::Rules(rules),
59 )
60 })
61 }
62
63 pub(crate) fn parent_stylesheet(&self) -> &CSSStyleSheet {
64 self.css_rule.parent_stylesheet()
65 }
66
67 pub(crate) fn shared_lock(&self) -> &SharedRwLock {
68 self.css_rule.shared_lock()
69 }
70
71 pub(crate) fn update_rules(
72 &self,
73 rules: &Arc<Locked<CssRules>>,
74 guard: &SharedRwLockReadGuard,
75 ) {
76 if let Some(rulelist) = self.rule_list.get() {
77 rulelist.update_rules(RulesSource::Rules(rules.clone()), guard);
78 }
79 }
80}
81
82impl CSSGroupingRuleMethods<crate::DomTypeHolder> for CSSGroupingRule {
83 fn CssRules(&self, cx: &mut JSContext) -> DomRoot<CSSRuleList> {
85 self.rulelist(cx)
87 }
88
89 fn InsertRule(&self, cx: &mut JSContext, rule: DOMString, index: u32) -> Fallible<u32> {
91 self.rulelist(cx).insert_rule(cx, &rule, index)
92 }
93
94 fn DeleteRule(&self, cx: &mut JSContext, index: u32) -> ErrorResult {
96 self.rulelist(cx).remove_rule(cx, index)
97 }
98}