Skip to main content

Mountain/Environment/
WebviewProvider.rs

1
2//! # WebviewProvider (Environment)
3//!
4//! Implements the `WebviewProvider` trait for `MountainEnvironment`, providing
5//! the core logic for creating, managing, and securing Webview panels.
6//!
7//! ## Architecture
8//!
9//! ```text
10//! Extension → CreateWebviewPanel → WebviewProvider → Tauri WebviewWindow
11//!                     │                              │
12//!                     └→ IPC → Cocoon ◄───────────┘
13//! ```
14//!
15//! ## Webview types
16//!
17//! - **Panel** - sidebar or panel webview (non-floating)
18//! - **Editor** - webview as custom editor (full editor area)
19//! - **Modal** - modal dialog webview (blocks interaction)
20//! - **Widget** - small embedded webview (e.g., diff viewer)
21//!
22//! ## Lifecycle
23//!
24//! 1. `CreateWebviewPanel` - build Tauri `WebviewWindow`, set up event
25//!    handlers, record in `ApplicationState.Feature.Webviews`.
26//! 2. `SetWebviewHTML` / `SetWebviewOptions` - configure content and title.
27//! 3. `RevealWebviewPanel` - show and focus.
28//! 4. `PostMessageToWebview` - bidirectional IPC between host and webview.
29//! 5. `DisposeWebviewPanel` - close window and clean up state.
30//!
31//! ## Security
32//!
33//! Webview runs in a sandboxed process (no Node.js). All `postMessage` calls
34//! are validated; origins are checked to prevent XSS.
35//! Memory footprint is ~50-100 MB per webview - reuse panels when possible.
36//!
37//! ## VS Code reference
38//!
39//! - `vs/workbench/contrib/webview/browser/webviewService.ts`
40//! - `vs/workbench/api/browser/mainThreadWebview.ts`
41
42use std::collections::HashMap;
43
44use CommonLibrary::{Error::CommonError::CommonError, Webview::WebviewProvider::WebviewProvider};
45use async_trait::async_trait;
46use serde_json::Value;
47
48use super::MountainEnvironment::MountainEnvironment;
49
50// Atomic public DTOs (one export per file).
51pub mod WebviewLifecycleState;
52
53pub mod WebviewMessage;
54
55// Private submodules - implementation only, accessed through the
56// trait impl below.
57#[path = "WebviewProvider/Configuration.rs"]
58mod Configuration;
59
60#[path = "WebviewProvider/Lifecycle.rs"]
61mod Lifecycle;
62
63#[path = "WebviewProvider/Messaging.rs"]
64mod Messaging;
65
66// TODO: content caching for faster reloads, theming (dark/light auto),
67// custom protocols, screenshot/thumbnail generation, performance monitoring
68// (CPU/memory), webview clustering, state snapshots for debugging,
69// accessibility audit, pause-when-hidden, resource preloading, telemetry,
70// offline mode (service workers), session migration, debugging tools.
71
72/// Webview message handler context. Private - only the dispatch
73/// machinery in `Messaging.rs` consumes it.
74#[allow(dead_code)]
75struct WebviewMessageContext {
76	Handle:String,
77
78	SideCarIdentifier:Option<String>,
79
80	PendingResponses:HashMap<String, tokio::sync::oneshot::Sender<Value>>,
81}
82
83#[async_trait]
84impl WebviewProvider for MountainEnvironment {
85	/// Creates a new Webview panel with proper security isolation.
86	async fn CreateWebviewPanel(
87		&self,
88
89		extension_data_value:Value,
90
91		view_type:String,
92
93		title:String,
94
95		_show_options_value:Value,
96
97		panel_options_value:Value,
98
99		content_options_value:Value,
100	) -> Result<String, CommonError> {
101		Lifecycle::create_webview_panel_impl(
102			self,
103			extension_data_value,
104			view_type,
105			title,
106			_show_options_value,
107			panel_options_value,
108			content_options_value,
109		)
110		.await
111	}
112
113	/// Disposes a Webview panel and cleans up all associated resources.
114	async fn DisposeWebviewPanel(&self, handle:String) -> Result<(), CommonError> {
115		Lifecycle::dispose_webview_panel_impl(self, handle).await
116	}
117
118	/// Reveals (shows and focuses) a Webview panel.
119	async fn RevealWebviewPanel(&self, handle:String, _show_options_value:Value) -> Result<(), CommonError> {
120		Lifecycle::reveal_webview_panel_impl(self, handle, _show_options_value).await
121	}
122
123	/// Sets Webview options (title, icon, etc.).
124	async fn SetWebviewOptions(&self, handle:String, options_value:Value) -> Result<(), CommonError> {
125		Configuration::set_webview_options_impl(self, handle, options_value).await
126	}
127
128	/// Sets the HTML content of a Webview.
129	async fn SetWebviewHTML(&self, handle:String, html:String) -> Result<(), CommonError> {
130		Configuration::set_webview_html_impl(self, handle, html).await
131	}
132
133	/// Posts a message to a Webview with proper error handling.
134	async fn PostMessageToWebview(&self, handle:String, message:Value) -> Result<bool, CommonError> {
135		Messaging::post_message_to_webview_impl(self, handle, message).await
136	}
137}