Skip to main content

Mountain/Environment/
WebviewProvider.rs

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