Mountain/Environment/WebviewProvider.rs
1//! # WebviewProvider (Environment)
2//!
3//! Implements the `WebviewProvider` trait for `MountainEnvironment`, providing
4//! the core logic for creating, managing, and securing Webview panels - the
5//! embedded browser-based UI components that power many extension features.
6//!
7//! ## RESPONSIBILITIES
8//!
9//! ### 1. Webview Panel Creation
10//! - Create webview windows with proper configuration
11//! - Set up webview content (HTML, CSS, JavaScript)
12//! - Configure webview security (CSP, sandbox, permissions)
13//! - Initialize webview lifecycle and event handlers
14//!
15//! ### 2. Webview Management
16//! - Track active webview instances in `ApplicationState.Feature.Webviews`
17//! - Handle webview focus and visibility changes
18//! - Support webview window positioning and sizing
19//! - Manage webview disposal and cleanup
20//!
21//! ### 3. Secure Message Passing
22//! - Establish bidirectional IPC between host and webview
23//! - Validate and route messages between webview and extension sidecar
24//! - Implement message authentication and authorization
25//! - Prevent cross-origin security vulnerabilities
26//!
27//! ### 4. State Persistence
28//! - Save webview state (position, size, content) to `ApplicationState`
29//! - Restore webview state when reopening
30//! - Persist webview settings across sessions
31//! - Handle webview state serialization/deserialization
32//!
33//! ### 5. Content Security
34//! - Enforce content security policy (CSP)
35//! - Sandbox webview content to prevent escape
36//! - Validate webview URLs and origins
37//! - Protect against XSS and injection attacks
38//!
39//! ## ARCHITECTURAL ROLE
40//!
41//! WebviewProvider is the **webview lifecycle manager**:
42//!
43//! ```text
44//! Extension ──► CreateWebview ──► WebviewProvider ──► Tauri WebviewWindow
45//! │ │
46//! └─► IPC ──► Cocoon ◄───────────┘
47//! ```
48//!
49//! ### Position in Mountain
50//! - `Environment` module: Web content capability provider
51//! - Implements `CommonLibrary::Webview::WebviewProvider` trait
52//! - Accessible via `Environment.Require<dyn WebviewProvider>()`
53//!
54//! ### Webview Types
55//! - **Panel**: Sidebar or panel webview (non-floating)
56//! - **Editor**: Webview as custom editor (full editor area)
57//! - **Modal**: Modal dialog webview (centered, blocks interaction)
58//! - **Widget**: Small embedded webview (e.g., diff viewer)
59//!
60//! ### Webview Lifecycle
61//! 1. **Create**: Extension calls `CreateWebview` with options
62//! 2. **Initialize**: Provider builds webview window, sets up event handlers
63//! 3. **Load Content**: HTML loaded, scripts execute
64//! 4. **Ready**: `onDidBecomeVisible` / `onDidBecomeHidden` events
65//! 5. **Dispose**: When closed, cleanup state and resources
66//!
67//! ### Dependencies
68//! - `Tauri`: `WebviewWindowBuilder` for webview creation
69//! - `ApplicationState`: Webview state tracking
70//! - `IPCProvider`: For extension-side communication
71//! - `Log`: Webview lifecycle logging
72//!
73//! ### Dependents
74//! - Extensions: Create webviews via `registerWebviewPanelProvider`
75//! - `Binary::Main`: Webview window creation during startup
76//! - `DispatchLogic::MountainWebviewPostMessageFromGuest`: Webview → host
77//! messages
78//! - UI components: Webview panel management
79//!
80//! ## WEBVIEW OPTIONS
81//!
82//! `WebviewContentOptionsDTO` controls webview behavior:
83//! - `Handle`: Unique UUID for this webview
84//! - `ViewType`: Extension-defined type identifier
85//! - `Title`: Panel title
86//! - `ContentOptions`: HTML, base URL, scripts, styles
87//! - `PanelOptions`: Size, position, enable/disable features
88//! - `SideCarIdentifier`: Host extension sidecar
89//! - `ExtensionIdentifier`: Owning extension ID
90//! - `IsActive`, `IsVisible`: State flags
91//!
92//! ## SECURITY CONSIDERATIONS
93//!
94//! - **Content Security Policy**: Default CSP restricts external resources
95//! - **Sandbox**: Webview runs in sandboxed process (no Node.js)
96//! - **Message Validation**: All postMessage() calls validated
97//! - **Origin Checking**: Verify message source matches expected webview
98//! - **Permission Management**: Granular permissions for APIs (geolocation,
99//! etc.)
100//!
101//! ## MESSAGE FLOW
102//!
103//! 1. Extension → Host: `webview.postMessage({ command: "..." })`
104//! 2. Provider receives via `MountainWebviewPostMessageFromGuest` command
105//! 3. Provider forwards to extension via IPC (`SendNotificationToSideCar`)
106//! 4. Extension processes and responds
107//! 5. Host → Extension: `ipc.postMessage({ command: "..." })`
108//! 6. Extension receives via `onDidReceiveMessage` event
109//!
110//! ## PERFORMANCE
111//!
112//! - Webview creation is relatively expensive (new browser context)
113//! - Reuse webviews when possible instead of creating new ones
114//! - Consider lazy loading for rarely used webviews
115//! - Memory usage: ~50-100MB per webview (depending on content)
116//! - Use `Dispose` promptly when webview no longer needed
117//!
118//! ## ERROR HANDLING
119//!
120//! - Webview creation failure: `CommonError::WebviewCreationFailed`
121//! - IPC communication failure: `CommonError::IPCError`
122//! - Invalid webview options: `CommonError::InvalidArgument`
123//! - Webview already exists: `CommonError::DuplicateWebview`
124//!
125//! ## VS CODE REFERENCE
126//!
127//! Patterns from VS Code:
128//! - `vs/workbench/contrib/webview/browser/webviewService.ts` - Webview service
129//! - `vs/workbench/contrib/webview/common/webview.ts` - Webview data model
130//! - `vs/workbench/api/browser/mainThreadWebview.ts` - Extension API
131//!
132//! ## TODO
133//!
134//! - [ ] Implement webview content caching for faster reloads
135//! - [ ] Add webview theming support (dark/light mode auto)
136//! - [ ] Support webview extensions/plugins (custom protocols)
137//! - [ ] Implement webview screenshot and thumbnail generation
138//! - [ ] Add webview performance monitoring (CPU, memory)
139//! - [ ] Support webview clustering for related views
140//! - [ ] Implement webview state snapshots for debugging
141//! - [ ] Add webview accessibility audit and reporting
142//! - [ ] Support webview pausing (suspend when not visible)
143//! - [ ] Implement webview resource preloading strategies
144//! - [ ] Add webview telemetry for usage and performance
145//! - [ ] Support webview offline mode with service workers
146//! - [ ] Implement webview migration across sessions
147//! - [ ] Add webview debugging tools integration
148//!
149//! ## MODULE STRUCTURE
150//!
151//! - [`lifecycle.rs`](lifecycle.rs) - Webview creation, disposal, reveal
152//! - [`configuration.rs`](configuration.rs) - Options and HTML setting
153//! - [`messaging.rs`](messaging.rs) - Message passing and listeners
154
155use std::collections::HashMap;
156
157use CommonLibrary::{Error::CommonError::CommonError, Webview::WebviewProvider::WebviewProvider};
158use async_trait::async_trait;
159use log::{debug, info, warn};
160use serde::{Deserialize, Serialize};
161use serde_json::{Value, json};
162use tauri::{Emitter, Manager, WebviewWindow};
163use uuid::Uuid;
164
165use super::{MountainEnvironment::MountainEnvironment, Utility};
166use crate::ApplicationState::DTO::WebviewStateDTO::WebviewStateDTO;
167
168/// Represents a Webview message
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct WebviewMessage {
171 pub MessageIdentifier:String,
172 pub MessageType:String,
173 pub Payload:Value,
174 pub Source:Option<String>,
175}
176
177/// Webview lifecycle state
178#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
179pub enum WebviewLifecycleState {
180 Unloaded,
181 Loading,
182 Loaded,
183 Visible,
184 Hidden,
185 Disposed,
186}
187
188/// Webview message handler context
189struct WebviewMessageContext {
190 Handle:String,
191 SideCarIdentifier:Option<String>,
192 PendingResponses:HashMap<String, tokio::sync::oneshot::Sender<Value>>,
193}
194
195// Private submodules containing the actual implementation
196#[path = "WebviewProvider/lifecycle.rs"]
197mod lifecycle;
198#[path = "WebviewProvider/configuration.rs"]
199mod configuration;
200#[path = "WebviewProvider/messaging.rs"]
201mod messaging;
202
203#[async_trait]
204impl WebviewProvider for MountainEnvironment {
205 /// Creates a new Webview panel with proper security isolation.
206 async fn CreateWebviewPanel(
207 &self,
208 extension_data_value:Value,
209 view_type:String,
210 title:String,
211 _show_options_value:Value,
212 panel_options_value:Value,
213 content_options_value:Value,
214 ) -> Result<String, CommonError> {
215 lifecycle::create_webview_panel_impl(
216 self,
217 extension_data_value,
218 view_type,
219 title,
220 _show_options_value,
221 panel_options_value,
222 content_options_value,
223 )
224 .await
225 }
226
227 /// Disposes a Webview panel and cleans up all associated resources.
228 async fn DisposeWebviewPanel(&self, handle:String) -> Result<(), CommonError> {
229 lifecycle::dispose_webview_panel_impl(self, handle).await
230 }
231
232 /// Reveals (shows and focuses) a Webview panel.
233 async fn RevealWebviewPanel(&self, handle:String, _show_options_value:Value) -> Result<(), CommonError> {
234 lifecycle::reveal_webview_panel_impl(self, handle, _show_options_value).await
235 }
236
237 /// Sets Webview options (title, icon, etc.).
238 async fn SetWebviewOptions(&self, handle:String, options_value:Value) -> Result<(), CommonError> {
239 configuration::set_webview_options_impl(self, handle, options_value).await
240 }
241
242 /// Sets the HTML content of a Webview.
243 async fn SetWebviewHTML(&self, handle:String, html:String) -> Result<(), CommonError> {
244 configuration::set_webview_html_impl(self, handle, html).await
245 }
246
247 /// Posts a message to a Webview with proper error handling.
248 async fn PostMessageToWebview(&self, handle:String, message:Value) -> Result<bool, CommonError> {
249 messaging::post_message_to_webview_impl(self, handle, message).await
250 }
251}