Rewild Your Web
web browser dweb
at main 150 lines 6.1 kB view raw
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(), &params.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 }