embedder_traits/
user_contents.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 std::path::PathBuf;
6use std::sync::atomic::{AtomicU32, Ordering};
7
8use malloc_size_of::MallocSizeOfOps;
9use malloc_size_of_derive::MallocSizeOf;
10use serde::{Deserialize, Serialize};
11use url::Url;
12
13static USER_CONTENT_MANAGER_ID: AtomicU32 = AtomicU32::new(1);
14
15#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
16pub struct UserContentManagerId(u32);
17
18impl UserContentManagerId {
19    pub fn next() -> Self {
20        Self(USER_CONTENT_MANAGER_ID.fetch_add(1, Ordering::Relaxed))
21    }
22}
23
24#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)]
25pub struct UserContents {
26    pub scripts: Vec<UserScript>,
27    pub stylesheets: Vec<UserStyleSheet>,
28}
29
30impl UserContents {
31    pub fn new() -> Self {
32        UserContents::default()
33    }
34}
35
36static USER_STYLE_SHEET_ID: AtomicU32 = AtomicU32::new(1);
37
38#[doc(hidden)]
39#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
40pub struct UserStyleSheetId(u32);
41
42impl UserStyleSheetId {
43    fn next() -> Self {
44        UserStyleSheetId(USER_STYLE_SHEET_ID.fetch_add(1, Ordering::Relaxed))
45    }
46}
47
48#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
49pub struct UserStyleSheet {
50    id: UserStyleSheetId,
51    source: String,
52    url: Url,
53}
54
55impl UserStyleSheet {
56    /// Create a new `UserStyleSheet` for the given source and url representing its location. The
57    /// `url` can be a local file url.
58    pub fn new(source: String, url: Url) -> Self {
59        Self {
60            id: UserStyleSheetId::next(),
61            source,
62            url,
63        }
64    }
65
66    #[doc(hidden)]
67    pub fn id(&self) -> UserStyleSheetId {
68        self.id
69    }
70
71    /// Return a reference to the source string of this `UserStyleSheet`.
72    pub fn source(&self) -> &String {
73        &self.source
74    }
75
76    /// Return the source url of this `UserStyleSheet`.
77    pub fn url(&self) -> Url {
78        self.url.clone()
79    }
80}
81
82static USER_SCRIPT_ID: AtomicU32 = AtomicU32::new(1);
83
84#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
85pub struct UserScriptId(u32);
86
87impl UserScriptId {
88    fn next() -> Self {
89        UserScriptId(USER_SCRIPT_ID.fetch_add(1, Ordering::Relaxed))
90    }
91}
92
93#[derive(Clone, Debug, Deserialize, Serialize)]
94pub struct UserScript {
95    id: UserScriptId,
96    script: String,
97    source_file: Option<PathBuf>,
98}
99
100impl UserScript {
101    /// Create a new `UserStyleSheet` for the given source string and an optional `PathBuf` representing
102    /// the location of the script on disk.
103    pub fn new(script: String, source_file: Option<PathBuf>) -> Self {
104        Self {
105            id: UserScriptId::next(),
106            script,
107            source_file,
108        }
109    }
110
111    #[doc(hidden)]
112    pub fn id(&self) -> UserScriptId {
113        self.id
114    }
115
116    /// Returns the optional path that represents the location of this `UserScript`.
117    pub fn source_file(&self) -> Option<PathBuf> {
118        self.source_file.clone()
119    }
120
121    // Returns a reference to the source string of this `UserScript`.
122    pub fn script(&self) -> &String {
123        &self.script
124    }
125}
126
127// Maybe we should implement `MallocSizeOf` for `PathBuf` in `malloc_size_of` crate?
128impl malloc_size_of::MallocSizeOf for UserScript {
129    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
130        let mut sum = 0;
131        sum += self.id.0.size_of(ops);
132        sum += self.script.size_of(ops);
133        if let Some(path) = &self.source_file {
134            sum += unsafe { ops.malloc_size_of(path.as_path()) };
135        }
136        sum
137    }
138}
139
140impl<T: Into<String>> From<T> for UserScript {
141    fn from(script: T) -> Self {
142        UserScript::new(script.into(), None)
143    }
144}