script/dom/css/
stylesheetlist.rs1use dom_struct::dom_struct;
6use js::context::{JSContext, NoGC};
7use script_bindings::reflector::{Reflector, reflect_dom_object};
8use servo_arc::Arc;
9use style::stylesheets::Stylesheet;
10
11use super::cssstylesheet::CSSStyleSheet;
12use super::stylesheet::StyleSheet;
13use crate::dom::bindings::codegen::Bindings::StyleSheetListBinding::StyleSheetListMethods;
14use crate::dom::bindings::root::{Dom, DomRoot};
15use crate::dom::document::Document;
16use crate::dom::documentorshadowroot::StylesheetSource;
17use crate::dom::element::Element;
18use crate::dom::shadowroot::ShadowRoot;
19use crate::dom::window::Window;
20
21#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
22#[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)]
23pub(crate) enum StyleSheetListOwner {
24 Document(Dom<Document>),
25 ShadowRoot(Dom<ShadowRoot>),
26}
27
28impl StyleSheetListOwner {
29 pub(crate) fn stylesheet_count(&self) -> usize {
30 match *self {
31 StyleSheetListOwner::Document(ref doc) => doc.stylesheet_count(),
32 StyleSheetListOwner::ShadowRoot(ref shadow_root) => shadow_root.stylesheet_count(),
33 }
34 }
35
36 pub(crate) fn stylesheet_at(
37 &self,
38 cx: &mut JSContext,
39 index: usize,
40 ) -> Option<DomRoot<CSSStyleSheet>> {
41 match *self {
42 StyleSheetListOwner::Document(ref doc) => doc.stylesheet_at(cx, index),
43 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
44 shadow_root.stylesheet_at(cx, index)
45 },
46 }
47 }
48
49 pub(crate) fn add_owned_stylesheet(
50 &self,
51 no_gc: &NoGC,
52 owner_node: &Element,
53 sheet: Arc<Stylesheet>,
54 ) {
55 match *self {
56 StyleSheetListOwner::Document(ref doc) => {
57 doc.add_owned_stylesheet(no_gc, owner_node, sheet)
58 },
59 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
60 shadow_root.add_owned_stylesheet(no_gc, owner_node, sheet)
61 },
62 }
63 }
64
65 pub(crate) fn append_constructed_stylesheet(&self, cssom_stylesheet: &CSSStyleSheet) {
66 match *self {
67 StyleSheetListOwner::Document(ref doc) => {
68 doc.append_constructed_stylesheet(cssom_stylesheet)
69 },
70 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
71 shadow_root.append_constructed_stylesheet(cssom_stylesheet)
72 },
73 }
74 }
75
76 #[cfg_attr(crown, expect(crown::unrooted_must_root))] pub(crate) fn remove_stylesheet(&self, owner: StylesheetSource, s: &Arc<Stylesheet>) {
78 match *self {
79 StyleSheetListOwner::Document(ref doc) => doc.remove_stylesheet(owner, s),
80 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
81 shadow_root.remove_stylesheet(owner, s)
82 },
83 }
84 }
85
86 pub(crate) fn invalidate_stylesheets(&self, no_gc: &NoGC) {
87 match *self {
88 StyleSheetListOwner::Document(ref doc) => doc.invalidate_stylesheets(no_gc),
89 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
90 shadow_root.invalidate_stylesheets(no_gc)
91 },
92 }
93 }
94}
95
96#[dom_struct]
97pub(crate) struct StyleSheetList {
98 reflector_: Reflector,
99 document_or_shadow_root: StyleSheetListOwner,
100}
101
102impl StyleSheetList {
103 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
104 fn new_inherited(doc_or_sr: StyleSheetListOwner) -> StyleSheetList {
105 StyleSheetList {
106 reflector_: Reflector::new(),
107 document_or_shadow_root: doc_or_sr,
108 }
109 }
110
111 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
112 pub(crate) fn new(
113 cx: &mut js::context::JSContext,
114 window: &Window,
115 doc_or_sr: StyleSheetListOwner,
116 ) -> DomRoot<StyleSheetList> {
117 reflect_dom_object(
118 cx,
119 Box::new(StyleSheetList::new_inherited(doc_or_sr)),
120 window,
121 )
122 }
123}
124
125impl StyleSheetListMethods<crate::DomTypeHolder> for StyleSheetList {
126 fn Length(&self) -> u32 {
128 self.document_or_shadow_root.stylesheet_count() as u32
129 }
130
131 fn Item(&self, cx: &mut JSContext, index: u32) -> Option<DomRoot<StyleSheet>> {
133 self.document_or_shadow_root
136 .stylesheet_at(cx, index as usize)
137 .map(DomRoot::upcast)
138 }
139
140 fn IndexedGetter(&self, cx: &mut JSContext, index: u32) -> Option<DomRoot<StyleSheet>> {
142 self.Item(cx, index)
143 }
144}