Rewild Your Web
web
browser
dweb
1--- original
2+++ modified
3@@ -63,7 +63,7 @@
4 use script::{JSEngineSetup, ServiceWorkerManager};
5 use servo_config::opts::Opts;
6 use servo_config::prefs::{PrefValue, Preferences};
7-use servo_config::{opts, pref, prefs};
8+use servo_config::{embedder_prefs, opts, pref, prefs};
9 use servo_geometry::{
10 DeviceIndependentIntRect, convert_rect_to_css_pixel, convert_size_to_css_pixel,
11 };
12@@ -206,9 +206,7 @@
13 }
14
15 if self.constellation_proxy.disconnected() {
16- self.delegate
17- .borrow()
18- .notify_error(ServoError::LostConnectionWithBackend);
19+ self.raise_error(ServoError::LostConnectionWithBackend);
20 }
21
22 self.paint.borrow_mut().perform_updates();
23@@ -260,10 +258,39 @@
24
25 fn handle_delegate_errors(&self) {
26 while let Some(error) = self.servo_errors.try_recv() {
27- self.delegate.borrow().notify_error(error);
28+ self.raise_error(error);
29 }
30 }
31
32+ /// Notify the delegate about an error and also broadcast to all script threads
33+ /// so they can dispatch `servoerror` events to `navigator.embedder` instances.
34+ fn raise_error(&self, error: ServoError) {
35+ // Convert to ServoErrorType and message for script threads
36+ let (error_type, message) = match &error {
37+ ServoError::LostConnectionWithBackend => (
38+ ServoErrorType::LostConnectionWithBackend,
39+ "Lost connection with the web engine backend".to_owned(),
40+ ),
41+ ServoError::DevtoolsFailedToStart => (
42+ ServoErrorType::DevtoolsFailedToStart,
43+ "The devtools server failed to start".to_owned(),
44+ ),
45+ ServoError::ResponseFailedToSend(e) => (
46+ ServoErrorType::ResponseFailedToSend,
47+ format!("Failed to send response: {:?}", e),
48+ ),
49+ };
50+
51+ // Broadcast to all script threads via constellation
52+ self.constellation_proxy
53+ .send(EmbedderToConstellationMessage::NotifyServoError(
54+ error_type, message,
55+ ));
56+
57+ // Notify the delegate
58+ self.delegate.borrow().notify_error(error);
59+ }
60+
61 fn clean_up_destroyed_webview_handles(&self) {
62 // Remove any webview handles that have been destroyed and would not be upgradable.
63 // Note that `retain` is O(capacity) because it visits empty buckets, so it may be worth
64@@ -421,6 +448,11 @@
65 webview.request_create_new(response_sender);
66 }
67 },
68+ EmbedderMsg::AllowOpeningEmbeddedWebView(webview_id, response_sender) => {
69+ if let Some(webview) = self.get_webview_handle(webview_id) {
70+ webview.request_create_embedded(response_sender);
71+ }
72+ },
73 EmbedderMsg::WebViewClosed(webview_id) => {
74 if let Some(webview) = self.get_webview_handle(webview_id) {
75 webview.delegate().notify_closed(webview);
76@@ -566,10 +598,7 @@
77 .delegate
78 .borrow()
79 .notify_devtools_server_started(port, token),
80- Err(()) => self
81- .delegate
82- .borrow()
83- .notify_error(ServoError::DevtoolsFailedToStart),
84+ Err(()) => self.raise_error(ServoError::DevtoolsFailedToStart),
85 },
86 EmbedderMsg::RequestDevtoolsConnection(response_sender) => {
87 self.delegate
88@@ -694,6 +723,47 @@
89 .notify_accessibility_tree_update(webview, tree_update);
90 }
91 },
92+ EmbedderMsg::EmbeddedWebViewCreated(
93+ parent_webview_id,
94+ new_webview_id,
95+ new_browsing_context_id,
96+ new_pipeline_id,
97+ url,
98+ ) => {
99+ if let Some(webview) = self.get_webview_handle(parent_webview_id) {
100+ webview.delegate().notify_embedded_webview_created(
101+ webview,
102+ new_webview_id,
103+ new_browsing_context_id,
104+ new_pipeline_id,
105+ url.into_url(),
106+ );
107+ }
108+ },
109+ EmbedderMsg::OpenNewOSWindow(params) => {
110+ self.delegate
111+ .borrow()
112+ .request_open_new_os_window(params.url.into_url(), ¶ms.features);
113+ },
114+ EmbedderMsg::CloseCurrentOSWindow => {
115+ self.delegate.borrow().request_close_current_os_window()
116+ },
117+ EmbedderMsg::ExitApplication => self.delegate.borrow().request_exit_application(),
118+ EmbedderMsg::StartWindowDrag(webview_id) => {
119+ self.delegate.borrow().request_start_window_drag(webview_id)
120+ },
121+ EmbedderMsg::StartWindowResize(webview_id) => self
122+ .delegate
123+ .borrow()
124+ .request_start_window_resize(webview_id),
125+ EmbedderMsg::EmbedderPreferenceChanged(name, value) => {
126+ // This message is sent from the constellation when a namespaced (embedder)
127+ // preference is changed from a content process. We invoke the registered
128+ // setter callback here in the main process to persist the preference.
129+ // This ensures that only the embedder process writes to the prefs file,
130+ // avoiding sandbox issues and race conditions.
131+ embedder_prefs::set_embedder_pref_from_script(&name, value);
132+ },
133 }
134 }
135 }
136@@ -928,6 +998,14 @@
137 self.0.site_data_manager.borrow()
138 }
139
140+ pub fn spawn_task<F>(task: F)
141+ where
142+ F: Future + 'static + std::marker::Send,
143+ F::Output: Send + 'static,
144+ {
145+ net::async_runtime::spawn_task(task)
146+ }
147+
148 pub(crate) fn paint<'a>(&'a self) -> Ref<'a, Paint> {
149 self.0.paint.borrow()
150 }