Browse Source

chore(docs): split app and window implementations

Lucas Nogueira 3 years ago
parent
commit
b7281317ba
2 changed files with 268 additions and 256 deletions
  1. 2 0
      core/tauri/src/app.rs
  2. 266 256
      core/tauri/src/window.rs

+ 2 - 0
core/tauri/src/app.rs

@@ -341,6 +341,7 @@ impl<R: Runtime> AppHandle<R> {
   }
 }
 
+/// APIs specific to the wry runtime.
 #[cfg(feature = "wry")]
 impl AppHandle<crate::Wry> {
   /// Create a new tao window using a callback. The event loop must be running at this point.
@@ -505,6 +506,7 @@ impl<R: Runtime> ManagerBase<R> for App<R> {
   }
 }
 
+/// APIs specific to the wry runtime.
 #[cfg(feature = "wry")]
 impl App<crate::Wry> {
   /// Adds a [`tauri_runtime_wry::Plugin`].

+ 266 - 256
core/tauri/src/window.rs

@@ -609,6 +609,7 @@ impl PlatformWebview {
   }
 }
 
+/// APIs specific to the wry runtime.
 #[cfg(feature = "wry")]
 impl Window<crate::Wry> {
   /// Executes the closure accessing the platform's webview handle.
@@ -667,6 +668,7 @@ impl Window<crate::Wry> {
   }
 }
 
+/// Base window functions.
 impl<R: Runtime> Window<R> {
   /// Create a new window that is attached to the manager.
   pub(crate) fn new(
@@ -710,125 +712,11 @@ impl<R: Runtime> Window<R> {
       .map_err(Into::into)
   }
 
-  /// How to handle this window receiving an [`InvokeMessage`].
-  pub fn on_message(self, payload: InvokePayload) -> crate::Result<()> {
-    let manager = self.manager.clone();
-    match payload.cmd.as_str() {
-      "__initialized" => {
-        let payload: PageLoadPayload = serde_json::from_value(payload.inner)?;
-        manager.run_on_page_load(self, payload);
-      }
-      _ => {
-        let message = InvokeMessage::new(
-          self.clone(),
-          manager.state(),
-          payload.cmd.to_string(),
-          payload.inner,
-        );
-        let resolver = InvokeResolver::new(self, payload.callback, payload.error);
-
-        let invoke = Invoke { message, resolver };
-        if let Some(module) = &payload.tauri_module {
-          crate::endpoints::handle(
-            module.to_string(),
-            invoke,
-            manager.config(),
-            manager.package_info(),
-          );
-        } else if payload.cmd.starts_with("plugin:") {
-          manager.extend_api(invoke);
-        } else {
-          manager.run_invoke_handler(invoke);
-        }
-      }
-    }
-
-    Ok(())
-  }
-
   /// The label of this window.
   pub fn label(&self) -> &str {
     &self.window.label
   }
 
-  /// Emits an event to both the JavaScript and the Rust listeners.
-  pub fn emit_and_trigger<S: Serialize + Clone>(
-    &self,
-    event: &str,
-    payload: S,
-  ) -> crate::Result<()> {
-    self.trigger(event, Some(serde_json::to_string(&payload)?));
-    self.emit(event, payload)
-  }
-
-  pub(crate) fn emit_internal<S: Serialize>(
-    &self,
-    event: &str,
-    source_window_label: Option<&str>,
-    payload: S,
-  ) -> crate::Result<()> {
-    self.eval(&format!(
-      "window['{}']({{event: {}, windowLabel: {}, payload: {}}})",
-      self.manager.event_emit_function_name(),
-      serde_json::to_string(event)?,
-      serde_json::to_string(&source_window_label)?,
-      serde_json::to_value(payload)?,
-    ))?;
-    Ok(())
-  }
-
-  /// Emits an event to the JavaScript listeners on the current window.
-  ///
-  /// The event is only delivered to listeners that used the `WebviewWindow#listen` method on the @tauri-apps/api `window` module.
-  pub fn emit<S: Serialize + Clone>(&self, event: &str, payload: S) -> crate::Result<()> {
-    self
-      .manager
-      .emit_filter(event, Some(self.label()), payload, |w| {
-        w.has_js_listener(None, event) || w.has_js_listener(Some(self.label().into()), event)
-      })?;
-    Ok(())
-  }
-
-  /// Listen to an event on this window.
-  ///
-  /// This listener only receives events that are triggered using the
-  /// [`trigger`](Window#method.trigger) and [`emit_and_trigger`](Window#method.emit_and_trigger) methods or
-  /// the `appWindow.emit` function from the @tauri-apps/api `window` module.
-  pub fn listen<F>(&self, event: impl Into<String>, handler: F) -> EventHandler
-  where
-    F: Fn(Event) + Send + 'static,
-  {
-    let label = self.window.label.clone();
-    self.manager.listen(event.into(), Some(label), handler)
-  }
-
-  /// Unlisten to an event on this window.
-  pub fn unlisten(&self, handler_id: EventHandler) {
-    self.manager.unlisten(handler_id)
-  }
-
-  /// Listen to an event on this window a single time.
-  pub fn once<F>(&self, event: impl Into<String>, handler: F) -> EventHandler
-  where
-    F: FnOnce(Event) + Send + 'static,
-  {
-    let label = self.window.label.clone();
-    self.manager.once(event.into(), Some(label), handler)
-  }
-
-  /// Triggers an event to the Rust listeners on this window.
-  ///
-  /// The event is only delivered to listeners that used the [`listen`](Window#method.listen) method.
-  pub fn trigger(&self, event: &str, data: Option<String>) {
-    let label = self.window.label.clone();
-    self.manager.trigger(event, Some(label), data)
-  }
-
-  /// Evaluates JavaScript on this window.
-  pub fn eval(&self, js: &str) -> crate::Result<()> {
-    self.window.dispatcher.eval_script(js).map_err(Into::into)
-  }
-
   /// Registers a window event listener.
   pub fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) {
     self
@@ -851,147 +739,10 @@ impl<R: Runtime> Window<R> {
       })
     })
   }
+}
 
-  pub(crate) fn register_js_listener(&self, window_label: Option<String>, event: String, id: u64) {
-    self
-      .window
-      .js_event_listeners
-      .lock()
-      .unwrap()
-      .entry(JsEventListenerKey {
-        window_label,
-        event,
-      })
-      .or_insert_with(Default::default)
-      .insert(id);
-  }
-
-  pub(crate) fn unregister_js_listener(&self, id: u64) {
-    let mut empty = None;
-    let mut js_listeners = self.window.js_event_listeners.lock().unwrap();
-    for (key, ids) in js_listeners.iter_mut() {
-      if ids.contains(&id) {
-        ids.remove(&id);
-        if ids.is_empty() {
-          empty.replace(key.clone());
-        }
-        break;
-      }
-    }
-
-    if let Some(key) = empty {
-      js_listeners.remove(&key);
-    }
-  }
-
-  /// Whether this window registered a listener to an event from the given window and event name.
-  pub(crate) fn has_js_listener(&self, window_label: Option<String>, event: &str) -> bool {
-    self
-      .window
-      .js_event_listeners
-      .lock()
-      .unwrap()
-      .contains_key(&JsEventListenerKey {
-        window_label,
-        event: event.into(),
-      })
-  }
-
-  /// Opens the developer tools window (Web Inspector).
-  /// The devtools is only enabled on debug builds or with the `devtools` feature flag.
-  ///
-  /// ## Platform-specific
-  ///
-  /// - **macOS:** This is a private API on macOS,
-  /// so you cannot use this if your application will be published on the App Store.
-  ///
-  /// # Examples
-  ///
-  /// ```rust,no_run
-  /// use tauri::Manager;
-  /// tauri::Builder::default()
-  ///   .setup(|app| {
-  ///     #[cfg(debug_assertions)]
-  ///     app.get_window("main").unwrap().open_devtools();
-  ///     Ok(())
-  ///   });
-  /// ```
-  #[cfg(any(debug_assertions, feature = "devtools"))]
-  #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))]
-  pub fn open_devtools(&self) {
-    self.window.dispatcher.open_devtools();
-  }
-
-  /// Closes the developer tools window (Web Inspector).
-  /// The devtools is only enabled on debug builds or with the `devtools` feature flag.
-  ///
-  /// ## Platform-specific
-  ///
-  /// - **macOS:** This is a private API on macOS,
-  /// so you cannot use this if your application will be published on the App Store.
-  /// - **Windows:** Unsupported.
-  ///
-  /// # Examples
-  ///
-  /// ```rust,no_run
-  /// use tauri::Manager;
-  /// tauri::Builder::default()
-  ///   .setup(|app| {
-  ///     #[cfg(debug_assertions)]
-  ///     {
-  ///       let window = app.get_window("main").unwrap();
-  ///       window.open_devtools();
-  ///       std::thread::spawn(move || {
-  ///         std::thread::sleep(std::time::Duration::from_secs(10));
-  ///         window.close_devtools();
-  ///       });
-  ///     }
-  ///     Ok(())
-  ///   });
-  /// ```
-  #[cfg(any(debug_assertions, feature = "devtools"))]
-  #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))]
-  pub fn close_devtools(&self) {
-    self.window.dispatcher.close_devtools();
-  }
-
-  /// Checks if the developer tools window (Web Inspector) is opened.
-  /// The devtools is only enabled on debug builds or with the `devtools` feature flag.
-  ///
-  /// ## Platform-specific
-  ///
-  /// - **macOS:** This is a private API on macOS,
-  /// so you cannot use this if your application will be published on the App Store.
-  /// - **Windows:** Unsupported.
-  ///
-  /// # Examples
-  ///
-  /// ```rust,no_run
-  /// use tauri::Manager;
-  /// tauri::Builder::default()
-  ///   .setup(|app| {
-  ///     #[cfg(debug_assertions)]
-  ///     {
-  ///       let window = app.get_window("main").unwrap();
-  ///       if !window.is_devtools_open() {
-  ///         window.open_devtools();
-  ///       }
-  ///     }
-  ///     Ok(())
-  ///   });
-  /// ```
-  #[cfg(any(debug_assertions, feature = "devtools"))]
-  #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))]
-  pub fn is_devtools_open(&self) -> bool {
-    self
-      .window
-      .dispatcher
-      .is_devtools_open()
-      .unwrap_or_default()
-  }
-
-  // Getters
-
+/// Window getters.
+impl<R: Runtime> Window<R> {
   /// Gets a handle to the window menu.
   pub fn menu_handle(&self) -> MenuHandle<R> {
     MenuHandle {
@@ -1122,9 +873,10 @@ impl<R: Runtime> Window<R> {
   pub fn theme(&self) -> crate::Result<Theme> {
     self.window.dispatcher.theme().map_err(Into::into)
   }
+}
 
-  // Setters
-
+/// Window setters and actions.
+impl<R: Runtime> Window<R> {
   /// Centers the window.
   pub fn center(&self) -> crate::Result<()> {
     self.window.dispatcher.center().map_err(Into::into)
@@ -1364,6 +1116,264 @@ impl<R: Runtime> Window<R> {
   }
 }
 
+/// Webview APIs.
+impl<R: Runtime> Window<R> {
+  /// Handles this window receiving an [`InvokeMessage`].
+  pub fn on_message(self, payload: InvokePayload) -> crate::Result<()> {
+    let manager = self.manager.clone();
+    match payload.cmd.as_str() {
+      "__initialized" => {
+        let payload: PageLoadPayload = serde_json::from_value(payload.inner)?;
+        manager.run_on_page_load(self, payload);
+      }
+      _ => {
+        let message = InvokeMessage::new(
+          self.clone(),
+          manager.state(),
+          payload.cmd.to_string(),
+          payload.inner,
+        );
+        let resolver = InvokeResolver::new(self, payload.callback, payload.error);
+
+        let invoke = Invoke { message, resolver };
+        if let Some(module) = &payload.tauri_module {
+          crate::endpoints::handle(
+            module.to_string(),
+            invoke,
+            manager.config(),
+            manager.package_info(),
+          );
+        } else if payload.cmd.starts_with("plugin:") {
+          manager.extend_api(invoke);
+        } else {
+          manager.run_invoke_handler(invoke);
+        }
+      }
+    }
+
+    Ok(())
+  }
+
+  /// Evaluates JavaScript on this window.
+  pub fn eval(&self, js: &str) -> crate::Result<()> {
+    self.window.dispatcher.eval_script(js).map_err(Into::into)
+  }
+
+  pub(crate) fn register_js_listener(&self, window_label: Option<String>, event: String, id: u64) {
+    self
+      .window
+      .js_event_listeners
+      .lock()
+      .unwrap()
+      .entry(JsEventListenerKey {
+        window_label,
+        event,
+      })
+      .or_insert_with(Default::default)
+      .insert(id);
+  }
+
+  pub(crate) fn unregister_js_listener(&self, id: u64) {
+    let mut empty = None;
+    let mut js_listeners = self.window.js_event_listeners.lock().unwrap();
+    for (key, ids) in js_listeners.iter_mut() {
+      if ids.contains(&id) {
+        ids.remove(&id);
+        if ids.is_empty() {
+          empty.replace(key.clone());
+        }
+        break;
+      }
+    }
+
+    if let Some(key) = empty {
+      js_listeners.remove(&key);
+    }
+  }
+
+  /// Whether this window registered a listener to an event from the given window and event name.
+  pub(crate) fn has_js_listener(&self, window_label: Option<String>, event: &str) -> bool {
+    self
+      .window
+      .js_event_listeners
+      .lock()
+      .unwrap()
+      .contains_key(&JsEventListenerKey {
+        window_label,
+        event: event.into(),
+      })
+  }
+
+  /// Opens the developer tools window (Web Inspector).
+  /// The devtools is only enabled on debug builds or with the `devtools` feature flag.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **macOS:** This is a private API on macOS,
+  /// so you cannot use this if your application will be published on the App Store.
+  ///
+  /// # Examples
+  ///
+  /// ```rust,no_run
+  /// use tauri::Manager;
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     #[cfg(debug_assertions)]
+  ///     app.get_window("main").unwrap().open_devtools();
+  ///     Ok(())
+  ///   });
+  /// ```
+  #[cfg(any(debug_assertions, feature = "devtools"))]
+  #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))]
+  pub fn open_devtools(&self) {
+    self.window.dispatcher.open_devtools();
+  }
+
+  /// Closes the developer tools window (Web Inspector).
+  /// The devtools is only enabled on debug builds or with the `devtools` feature flag.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **macOS:** This is a private API on macOS,
+  /// so you cannot use this if your application will be published on the App Store.
+  /// - **Windows:** Unsupported.
+  ///
+  /// # Examples
+  ///
+  /// ```rust,no_run
+  /// use tauri::Manager;
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     #[cfg(debug_assertions)]
+  ///     {
+  ///       let window = app.get_window("main").unwrap();
+  ///       window.open_devtools();
+  ///       std::thread::spawn(move || {
+  ///         std::thread::sleep(std::time::Duration::from_secs(10));
+  ///         window.close_devtools();
+  ///       });
+  ///     }
+  ///     Ok(())
+  ///   });
+  /// ```
+  #[cfg(any(debug_assertions, feature = "devtools"))]
+  #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))]
+  pub fn close_devtools(&self) {
+    self.window.dispatcher.close_devtools();
+  }
+
+  /// Checks if the developer tools window (Web Inspector) is opened.
+  /// The devtools is only enabled on debug builds or with the `devtools` feature flag.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **macOS:** This is a private API on macOS,
+  /// so you cannot use this if your application will be published on the App Store.
+  /// - **Windows:** Unsupported.
+  ///
+  /// # Examples
+  ///
+  /// ```rust,no_run
+  /// use tauri::Manager;
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     #[cfg(debug_assertions)]
+  ///     {
+  ///       let window = app.get_window("main").unwrap();
+  ///       if !window.is_devtools_open() {
+  ///         window.open_devtools();
+  ///       }
+  ///     }
+  ///     Ok(())
+  ///   });
+  /// ```
+  #[cfg(any(debug_assertions, feature = "devtools"))]
+  #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))]
+  pub fn is_devtools_open(&self) -> bool {
+    self
+      .window
+      .dispatcher
+      .is_devtools_open()
+      .unwrap_or_default()
+  }
+}
+
+/// Event system APIs.
+impl<R: Runtime> Window<R> {
+  /// Emits an event to both the JavaScript and the Rust listeners.
+  pub fn emit_and_trigger<S: Serialize + Clone>(
+    &self,
+    event: &str,
+    payload: S,
+  ) -> crate::Result<()> {
+    self.trigger(event, Some(serde_json::to_string(&payload)?));
+    self.emit(event, payload)
+  }
+
+  pub(crate) fn emit_internal<S: Serialize>(
+    &self,
+    event: &str,
+    source_window_label: Option<&str>,
+    payload: S,
+  ) -> crate::Result<()> {
+    self.eval(&format!(
+      "window['{}']({{event: {}, windowLabel: {}, payload: {}}})",
+      self.manager.event_emit_function_name(),
+      serde_json::to_string(event)?,
+      serde_json::to_string(&source_window_label)?,
+      serde_json::to_value(payload)?,
+    ))?;
+    Ok(())
+  }
+
+  /// Emits an event to the JavaScript listeners on the current window.
+  ///
+  /// The event is only delivered to listeners that used the `WebviewWindow#listen` method on the @tauri-apps/api `window` module.
+  pub fn emit<S: Serialize + Clone>(&self, event: &str, payload: S) -> crate::Result<()> {
+    self
+      .manager
+      .emit_filter(event, Some(self.label()), payload, |w| {
+        w.has_js_listener(None, event) || w.has_js_listener(Some(self.label().into()), event)
+      })?;
+    Ok(())
+  }
+
+  /// Listen to an event on this window.
+  ///
+  /// This listener only receives events that are triggered using the
+  /// [`trigger`](Window#method.trigger) and [`emit_and_trigger`](Window#method.emit_and_trigger) methods or
+  /// the `appWindow.emit` function from the @tauri-apps/api `window` module.
+  pub fn listen<F>(&self, event: impl Into<String>, handler: F) -> EventHandler
+  where
+    F: Fn(Event) + Send + 'static,
+  {
+    let label = self.window.label.clone();
+    self.manager.listen(event.into(), Some(label), handler)
+  }
+
+  /// Unlisten to an event on this window.
+  pub fn unlisten(&self, handler_id: EventHandler) {
+    self.manager.unlisten(handler_id)
+  }
+
+  /// Listen to an event on this window a single time.
+  pub fn once<F>(&self, event: impl Into<String>, handler: F) -> EventHandler
+  where
+    F: FnOnce(Event) + Send + 'static,
+  {
+    let label = self.window.label.clone();
+    self.manager.once(event.into(), Some(label), handler)
+  }
+
+  /// Triggers an event to the Rust listeners on this window.
+  ///
+  /// The event is only delivered to listeners that used the [`listen`](Window#method.listen) method.
+  pub fn trigger(&self, event: &str, data: Option<String>) {
+    let label = self.window.label.clone();
+    self.manager.trigger(event, Some(label), data)
+  }
+}
+
 #[cfg(test)]
 mod tests {
   #[test]