script/dom/css/
stylesheetlist.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
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(&self, owner_node: &Element, sheet: Arc<Stylesheet>) {
50 match *self {
51 StyleSheetListOwner::Document(ref doc) => doc.add_owned_stylesheet(owner_node, sheet),
52 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
53 shadow_root.add_owned_stylesheet(owner_node, sheet)
54 },
55 }
56 }
57
58 pub(crate) fn append_constructed_stylesheet(&self, cssom_stylesheet: &CSSStyleSheet) {
59 match *self {
60 StyleSheetListOwner::Document(ref doc) => {
61 doc.append_constructed_stylesheet(cssom_stylesheet)
62 },
63 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
64 shadow_root.append_constructed_stylesheet(cssom_stylesheet)
65 },
66 }
67 }
68
69 #[cfg_attr(crown, expect(crown::unrooted_must_root))] pub(crate) fn remove_stylesheet(&self, owner: StylesheetSource, s: &Arc<Stylesheet>) {
71 match *self {
72 StyleSheetListOwner::Document(ref doc) => doc.remove_stylesheet(owner, s),
73 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
74 shadow_root.remove_stylesheet(owner, s)
75 },
76 }
77 }
78
79 pub(crate) fn invalidate_stylesheets(&self) {
80 match *self {
81 StyleSheetListOwner::Document(ref doc) => doc.invalidate_stylesheets(),
82 StyleSheetListOwner::ShadowRoot(ref shadow_root) => {
83 shadow_root.invalidate_stylesheets()
84 },
85 }
86 }
87}
88
89#[dom_struct]
90pub(crate) struct StyleSheetList {
91 reflector_: Reflector,
92 document_or_shadow_root: StyleSheetListOwner,
93}
94
95impl StyleSheetList {
96 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
97 fn new_inherited(doc_or_sr: StyleSheetListOwner) -> StyleSheetList {
98 StyleSheetList {
99 reflector_: Reflector::new(),
100 document_or_shadow_root: doc_or_sr,
101 }
102 }
103
104 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
105 pub(crate) fn new(
106 cx: &mut js::context::JSContext,
107 window: &Window,
108 doc_or_sr: StyleSheetListOwner,
109 ) -> DomRoot<StyleSheetList> {
110 reflect_dom_object_with_cx(
111 Box::new(StyleSheetList::new_inherited(doc_or_sr)),
112 window,
113 cx,
114 )
115 }
116}
117
118impl StyleSheetListMethods<crate::DomTypeHolder> for StyleSheetList {
119 fn Length(&self) -> u32 {
121 self.document_or_shadow_root.stylesheet_count() as u32
122 }
123
124 fn Item(&self, cx: &mut JSContext, index: u32) -> Option<DomRoot<StyleSheet>> {
126 self.document_or_shadow_root
129 .stylesheet_at(cx, index as usize)
130 .map(DomRoot::upcast)
131 }
132
133 fn IndexedGetter(&self, cx: &mut JSContext, index: u32) -> Option<DomRoot<StyleSheet>> {
135 self.Item(cx, index)
136 }
137}