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