Rewild Your Web
at main 227 lines 8.4 kB view raw
1--- original 2+++ modified 3@@ -32,7 +32,8 @@ 4 use servo_base::generic_channel::{ 5 GenericCallback, GenericSender, GenericSharedMemory, SendResult, 6 }; 7-use servo_base::id::{PipelineId, WebViewId}; 8+use servo_base::id::{BrowsingContextId, PipelineId, WebViewId}; 9+use servo_config::pref_util::PrefValue; 10 use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize}; 11 use servo_url::ServoUrl; 12 use strum::{EnumMessage, IntoStaticStr}; 13@@ -67,6 +68,31 @@ 14 Self::Page(point) => *point * scale, 15 } 16 } 17+ 18+ /// Scale the point by the given factor (divides coordinates by scale). 19+ /// Used for converting coordinates to account for page zoom. 20+ pub fn scale_by(&self, scale: f32) -> Self { 21+ match self { 22+ Self::Device(point) => Self::Device(DevicePoint::new(point.x / scale, point.y / scale)), 23+ Self::Page(point) => Self::Page(Point2D::new(point.x / scale, point.y / scale)), 24+ } 25+ } 26+ 27+ /// Get the x coordinate regardless of coordinate space. 28+ pub fn x(&self) -> f32 { 29+ match self { 30+ Self::Device(point) => point.x, 31+ Self::Page(point) => point.x, 32+ } 33+ } 34+ 35+ /// Get the y coordinate regardless of coordinate space. 36+ pub fn y(&self) -> f32 { 37+ match self { 38+ Self::Device(point) => point.y, 39+ Self::Page(point) => point.y, 40+ } 41+ } 42 } 43 44 impl From<DevicePoint> for WebViewPoint { 45@@ -319,9 +345,16 @@ 46 /// The size of the layout viewport. 47 pub size: Size2D<f32, CSSPixel>, 48 49- /// The scale factor to use to account for HiDPI scaling. This does not take into account 50- /// any page or pinch zoom applied by `Paint` to the contents. 51+ /// The scale factor to use to account for HiDPI scaling. For top-level webviews, this 52+ /// includes the page zoom factor. For embedded webviews, this is just the device HiDPI 53+ /// and page zoom is passed separately via `page_zoom_for_rendering`. 54 pub hidpi_scale_factor: Scale<f32, CSSPixel, DevicePixel>, 55+ 56+ /// Page zoom to apply during display list building (for embedded webviews only). 57+ /// For top-level webviews this is `None` because zoom is applied externally in the 58+ /// painter as a WebRender reference frame transform. For embedded webviews, the zoom 59+ /// must be applied inside the webview's own display list. 60+ pub page_zoom_for_rendering: Option<f32>, 61 } 62 63 impl ViewportDetails { 64@@ -341,7 +374,7 @@ 65 } 66 67 /// An opaque identifier for a single history traversal operation. 68-#[derive(Clone, Deserialize, Eq, Hash, PartialEq, Serialize)] 69+#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] 70 pub struct TraversalId(String); 71 72 impl TraversalId { 73@@ -351,6 +384,12 @@ 74 } 75 } 76 77+impl std::fmt::Display for TraversalId { 78+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 79+ write!(f, "{}", self.0) 80+ } 81+} 82+ 83 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, MallocSizeOf)] 84 pub enum PixelFormat { 85 /// Luminance channel only 86@@ -424,6 +463,12 @@ 87 } 88 } 89 90+#[derive(Deserialize, Serialize)] 91+pub struct NewOSWindowParams { 92+ pub url: ServoUrl, 93+ pub features: String, 94+} 95+ 96 /// Messages towards the embedder. 97 #[derive(Deserialize, IntoStaticStr, Serialize)] 98 pub enum EmbedderMsg { 99@@ -449,6 +494,21 @@ 100 ), 101 /// Whether or not to allow script to open a new tab/browser 102 AllowOpeningWebView(WebViewId, GenericSender<Option<NewWebViewDetails>>), 103+ /// Whether or not to allow an iframe with "embed" attribute to create an embedded webview. 104+ AllowOpeningEmbeddedWebView(WebViewId, GenericSender<Option<NewWebViewDetails>>), 105+ /// An embedded webview has opened a new embedded webview via `window.open()`. 106+ /// The constellation has already created the new webview and pipeline. 107+ /// The parent webview (browserhtml shell) should create an `<iframe embed>` that 108+ /// adopts the pre-created webview using the provided IDs. 109+ /// 110+ /// Fields: (parent_webview_id, new_webview_id, new_browsing_context_id, new_pipeline_id, target_url) 111+ EmbeddedWebViewCreated( 112+ WebViewId, 113+ WebViewId, 114+ BrowsingContextId, 115+ PipelineId, 116+ ServoUrl, 117+ ), 118 /// A webview was destroyed. 119 WebViewClosed(WebViewId), 120 /// A webview potentially gained focus for keyboard events. 121@@ -530,6 +590,24 @@ 122 InputEventsHandled(WebViewId, Vec<InputEventOutcome>), 123 /// Send the embedder an accessibility tree update. 124 AccessibilityTreeUpdate(WebViewId, accesskit::TreeUpdate), 125+ /// Request from web content (via `navigator.embedder.openNewOSWindow()`) to open a new 126+ /// OS-level window with the given URL and features. 127+ OpenNewOSWindow(NewOSWindowParams), 128+ /// Request the embedder to close the currently focused OS window. 129+ CloseCurrentOSWindow, 130+ /// Request the embedder to start a window drag operation. 131+ /// The WebViewId is used to identify which window to drag. 132+ StartWindowDrag(WebViewId), 133+ /// Request the embedder to start a window resize operation. 134+ /// The WebViewId is used to identify which window to resize. 135+ StartWindowResize(WebViewId), 136+ /// Notify the embedder that an embedder preference (namespaced, e.g., "browserhtml.theme") 137+ /// was changed from a content process. The embedder should invoke the registered setter 138+ /// callback to persist the preference. This ensures preference saves only happen in the 139+ /// main process, avoiding sandbox and race condition issues. 140+ EmbedderPreferenceChanged(String, PrefValue), 141+ /// Request the embedder to exit the application. 142+ ExitApplication, 143 } 144 145 impl Debug for EmbedderMsg { 146@@ -1086,6 +1164,54 @@ 147 WebViewDoesNotExist, 148 } 149 150+/// Image format for screenshot encoding. 151+#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] 152+pub enum ScreenshotImageType { 153+ Png, 154+ Jpeg, 155+ Webp, 156+} 157+ 158+impl ScreenshotImageType { 159+ pub fn mime_type(&self) -> &'static str { 160+ match self { 161+ Self::Png => "image/png", 162+ Self::Jpeg => "image/jpeg", 163+ Self::Webp => "image/webp", 164+ } 165+ } 166+} 167+ 168+/// Request parameters for taking a screenshot of an embedded webview. 169+#[derive(Clone, Debug, Deserialize, Serialize)] 170+pub struct EmbeddedWebViewScreenshotRequest { 171+ pub image_type: ScreenshotImageType, 172+ /// Quality setting (0.0 to 1.0), used for JPEG/WebP compression. 173+ pub quality: f64, 174+} 175+ 176+/// Result of a successful screenshot operation. 177+#[derive(Clone, Debug, Deserialize, Serialize)] 178+pub struct EmbeddedWebViewScreenshotResult { 179+ /// The encoded image bytes. 180+ pub bytes: Vec<u8>, 181+ /// The MIME type of the encoded image (e.g., "image/png"). 182+ pub mime_type: String, 183+} 184+ 185+/// Error that can occur during embedded webview screenshot capture. 186+#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] 187+pub enum EmbeddedWebViewScreenshotError { 188+ /// The iframe is not an embedded webview. 189+ NotEmbeddedWebView, 190+ /// The webview does not exist. 191+ WebViewDoesNotExist, 192+ /// Failed to capture the screenshot. 193+ CaptureFailed, 194+ /// Failed to encode the image. 195+ EncodingFailed, 196+} 197+ 198 #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 199 pub struct RgbColor { 200 pub red: u8, 201@@ -1132,3 +1258,26 @@ 202 pub viewport_details: ViewportDetails, 203 pub user_content_manager_id: Option<UserContentManagerId>, 204 } 205+ 206+/// Types of errors that can be reported via `navigator.embedder.onservoerror`. 207+/// This is a Servo-specific, non-standard API. 208+#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] 209+pub enum ServoErrorType { 210+ /// Lost connection with the web engine backend. 211+ LostConnectionWithBackend, 212+ /// The devtools server failed to start. 213+ DevtoolsFailedToStart, 214+ /// Failed to send a response. 215+ ResponseFailedToSend, 216+} 217+ 218+impl ServoErrorType { 219+ /// Get the error type as a string for the JavaScript event detail. 220+ pub fn as_str(&self) -> &'static str { 221+ match self { 222+ ServoErrorType::LostConnectionWithBackend => "LostConnectionWithBackend", 223+ ServoErrorType::DevtoolsFailedToStart => "DevtoolsFailedToStart", 224+ ServoErrorType::ResponseFailedToSend => "ResponseFailedToSend", 225+ } 226+ } 227+}