forked from
me.webbeef.org/browser.html
Rewild Your Web
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+}