tauri_plugin_cef_webview/
registry.rs1use std::{
2 collections::HashMap,
3 sync::{
4 atomic::{AtomicU64, Ordering},
5 Arc, Mutex,
6 },
7};
8
9use tauri::{
10 webview::Webview, LogicalPosition, LogicalSize, Rect, Runtime, Url,
11};
12
13use crate::{scripts, Config};
14
15pub struct Registry<R: Runtime> {
17 webviews: Mutex<HashMap<String, Webview<R>>>,
18 css_sequence: Arc<AtomicU64>,
19 config: Config,
20}
21
22impl<R: Runtime> Registry<R> {
23 pub(crate) fn new(config: Config) -> Self {
24 Self {
25 webviews: Mutex::new(HashMap::new()),
26 css_sequence: Arc::new(AtomicU64::new(0)),
27 config,
28 }
29 }
30
31 pub(crate) fn config(&self) -> &Config {
32 &self.config
33 }
34
35 pub(crate) fn insert(&self, label: &str, webview: Webview<R>) {
36 self.webviews
37 .lock()
38 .unwrap_or_else(|error| error.into_inner())
39 .insert(label.to_string(), webview);
40 }
41
42 pub(crate) fn remove(&self, label: &str) -> Option<Webview<R>> {
43 self.webviews
44 .lock()
45 .unwrap_or_else(|error| error.into_inner())
46 .remove(label)
47 }
48
49 pub fn get(&self, label: &str) -> Option<CefWebview<R>> {
51 self.webviews
52 .lock()
53 .unwrap_or_else(|error| error.into_inner())
54 .get(label)
55 .cloned()
56 .map(|webview| CefWebview {
57 webview,
58 css_sequence: Arc::clone(&self.css_sequence),
59 })
60 }
61
62 pub fn labels(&self) -> Vec<String> {
64 self.webviews
65 .lock()
66 .unwrap_or_else(|error| error.into_inner())
67 .keys()
68 .cloned()
69 .collect()
70 }
71}
72
73#[derive(Clone)]
75pub struct CefWebview<R: Runtime> {
76 pub(crate) webview: Webview<R>,
77 css_sequence: Arc<AtomicU64>,
78}
79
80impl<R: Runtime> CefWebview<R> {
81 pub fn label(&self) -> &str {
83 self.webview.label()
84 }
85
86 pub fn inner(&self) -> &Webview<R> {
88 &self.webview
89 }
90
91 pub fn eval(&self, js: impl Into<String>) -> tauri::Result<()> {
93 self.webview.eval(js)
94 }
95
96 pub fn insert_css(&self, css: &str) -> tauri::Result<String> {
98 let key = format!(
99 "cwv-css-{}",
100 self.css_sequence.fetch_add(1, Ordering::Relaxed)
101 );
102 self.webview.eval(scripts::insert_style(&key, css))?;
103 Ok(key)
104 }
105
106 pub fn remove_inserted_css(&self, key: &str) -> tauri::Result<()> {
108 self.webview.eval(scripts::remove_style(key))
109 }
110
111 pub fn navigate(&self, url: &str) -> Result<(), String> {
113 let url = Url::parse(url).map_err(|error| error.to_string())?;
114 self.webview.navigate(url).map_err(|error| error.to_string())
115 }
116
117 pub fn reload(&self) -> tauri::Result<()> {
119 self.webview.reload()
120 }
121
122 #[cfg(any(debug_assertions, feature = "devtools"))]
124 pub fn open_devtools(&self) {
125 self.webview.open_devtools();
126 }
127
128 #[cfg(not(any(debug_assertions, feature = "devtools")))]
130 pub fn open_devtools(&self) {}
131
132 pub fn set_rect(&self, x: f64, y: f64, width: f64, height: f64) -> tauri::Result<()> {
134 self.webview.set_bounds(Rect {
135 position: LogicalPosition::new(x, y).into(),
136 size: LogicalSize::new(width, height).into(),
137 })
138 }
139
140 pub fn set_visible(&self, visible: bool) -> tauri::Result<()> {
142 if visible {
143 self.webview.show()
144 } else {
145 self.webview.hide()
146 }
147 }
148
149 pub fn close(&self) -> tauri::Result<()> {
151 self.webview.close()
152 }
153}