diff options
70 files changed, 808 insertions, 752 deletions
diff --git a/Cargo.lock b/Cargo.lock index 70e95180aec..200c3d86bec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,6 +503,7 @@ dependencies = [ name = "bluetooth" version = "0.0.1" dependencies = [ + "base", "bitflags 2.8.0", "bluetooth_traits", "blurdroid", @@ -521,6 +522,7 @@ dependencies = [ name = "bluetooth_traits" version = "0.0.1" dependencies = [ + "base", "embedder_traits", "ipc-channel", "regex", diff --git a/components/bluetooth/Cargo.toml b/components/bluetooth/Cargo.toml index f27e9a35529..8b22ccbd137 100644 --- a/components/bluetooth/Cargo.toml +++ b/components/bluetooth/Cargo.toml @@ -12,6 +12,7 @@ name = "bluetooth" path = "lib.rs" [dependencies] +base = { workspace = true } bitflags = { workspace = true } bluetooth_traits = { workspace = true } blurmock = { version = "0.1.2", optional = true } diff --git a/components/bluetooth/lib.rs b/components/bluetooth/lib.rs index eb380429d0d..3d82701d469 100644 --- a/components/bluetooth/lib.rs +++ b/components/bluetooth/lib.rs @@ -19,6 +19,7 @@ use std::string::String; use std::thread; use std::time::Duration; +use base::id::WebViewId; use bitflags::bitflags; use bluetooth_traits::blocklist::{uuid_is_blocklisted, Blocklist}; use bluetooth_traits::scanfilter::{ @@ -387,6 +388,7 @@ impl BluetoothManager { fn select_device( &mut self, + webview_id: WebViewId, devices: Vec<BluetoothDevice>, adapter: &BluetoothAdapter, ) -> Option<String> { @@ -408,11 +410,12 @@ impl BluetoothManager { } let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = ( - None, - EmbedderMsg::GetSelectedBluetoothDevice(dialog_rows, ipc_sender), - ); - self.embedder_proxy.send(msg); + self.embedder_proxy + .send(EmbedderMsg::GetSelectedBluetoothDevice( + webview_id, + dialog_rows, + ipc_sender, + )); match ipc_receiver.recv() { Ok(result) => result, @@ -628,7 +631,7 @@ impl BluetoothManager { } // Step 9. - if let Some(address) = self.select_device(matched_devices, &adapter) { + if let Some(address) = self.select_device(options.webview_id(), matched_devices, &adapter) { let device_id = match self.address_to_id.get(&address) { Some(id) => id.clone(), None => return Err(BluetoothError::NotFound), diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 6a6626040b9..45762929807 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -425,9 +425,21 @@ impl IOCompositor { Some(cursor) if cursor != self.cursor => cursor, _ => return, }; + let Some(webview_id) = self + .pipeline_details(result.pipeline_id) + .pipeline + .as_ref() + .map(|composition_pipeline| composition_pipeline.top_level_browsing_context_id) + else { + warn!( + "Updating cursor for not-yet-rendered pipeline: {}", + result.pipeline_id + ); + return; + }; self.cursor = cursor; - let msg = ConstellationMsg::SetCursor(cursor); + let msg = ConstellationMsg::SetCursor(webview_id, cursor); if let Err(e) = self.constellation_chan.send(msg) { warn!("Sending event to constellation failed ({:?}).", e); } diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 116dbe13b79..ef6553f1775 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -7,7 +7,7 @@ use std::fmt::{Debug, Error, Formatter}; use std::time::Duration; -use base::id::{PipelineId, TopLevelBrowsingContextId}; +use base::id::{PipelineId, TopLevelBrowsingContextId, WebViewId}; use embedder_traits::{ ClipboardEventType, EventLoopWaker, GamepadEvent, MediaSessionActionType, MouseButton, Theme, TouchEventType, TouchId, TraversalDirection, WheelDelta, @@ -83,7 +83,7 @@ pub enum EmbedderEvent { /// Sent when the user exits from fullscreen mode ExitFullScreen(TopLevelBrowsingContextId), /// Sent when a key input state changes - Keyboard(KeyboardEvent), + Keyboard(WebViewId, KeyboardEvent), /// Sent for IME composition updates IMEComposition(CompositionEvent), /// Sent when Ctr+R/Apple+R is called to reload the current page. diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index d25880efefc..2c27808ab0e 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -1232,9 +1232,9 @@ where )] fn handle_request_from_background_hang_monitor(&self, message: HangMonitorAlert) { match message { - HangMonitorAlert::Profile(bytes) => self - .embedder_proxy - .send((None, EmbedderMsg::ReportProfile(bytes))), + HangMonitorAlert::Profile(bytes) => { + self.embedder_proxy.send(EmbedderMsg::ReportProfile(bytes)) + }, HangMonitorAlert::Hang(hang) => { // TODO: In case of a permanent hang being reported, add a "kill script" workflow, // via the embedder? @@ -1271,8 +1271,8 @@ where FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => { let _ = resp_chan.send(self.webviews.focused_webview().map(|(id, _)| id)); }, - FromCompositorMsg::Keyboard(key_event) => { - self.handle_key_msg(key_event); + FromCompositorMsg::Keyboard(webview_id, key_event) => { + self.handle_key_msg(webview_id, key_event); }, FromCompositorMsg::IMECompositionEvent(ime_event) => { self.handle_ime_msg(ime_event); @@ -1391,11 +1391,8 @@ where // A top level browsing context is created and opened in both constellation and // compositor. FromCompositorMsg::WebViewOpened(top_level_browsing_context_id) => { - let msg = ( - Some(top_level_browsing_context_id), - EmbedderMsg::WebViewOpened(top_level_browsing_context_id), - ); - self.embedder_proxy.send(msg); + self.embedder_proxy + .send(EmbedderMsg::WebViewOpened(top_level_browsing_context_id)); }, // Close a top level browsing context. FromCompositorMsg::CloseWebView(top_level_browsing_context_id) => { @@ -1414,8 +1411,7 @@ where }, FromCompositorMsg::BlurWebView => { self.webviews.unfocus(); - self.embedder_proxy - .send((None, EmbedderMsg::WebViewBlurred)); + self.embedder_proxy.send(EmbedderMsg::WebViewBlurred); }, // Handle a forward or back request FromCompositorMsg::TraverseHistory(top_level_browsing_context_id, direction) => { @@ -1442,7 +1438,9 @@ where FromCompositorMsg::ForwardEvent(destination_pipeline_id, event) => { self.forward_event(destination_pipeline_id, event); }, - FromCompositorMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor), + FromCompositorMsg::SetCursor(webview_id, cursor) => { + self.handle_set_cursor_msg(webview_id, cursor) + }, FromCompositorMsg::ToggleProfiler(rate, max_duration) => { for background_monitor_control_sender in &self.background_monitor_control_senders { if let Err(e) = background_monitor_control_sender.send( @@ -1469,7 +1467,7 @@ where ) .entered(); self.embedder_proxy - .send((None, EmbedderMsg::ReadyToPresent(webview_ids))); + .send(EmbedderMsg::ReadyToPresent(webview_ids)); }, FromCompositorMsg::Gamepad(gamepad_event) => { self.handle_gamepad_msg(gamepad_event); @@ -1557,8 +1555,7 @@ where self.handle_schedule_broadcast(source_pipeline_id, router_id, message); }, FromScriptMsg::ForwardToEmbedder(embedder_msg) => { - self.embedder_proxy - .send((Some(source_top_ctx_id), embedder_msg)); + self.embedder_proxy.send(embedder_msg); }, FromScriptMsg::PipelineExited => { self.handle_pipeline_exited(source_pipeline_id); @@ -1756,10 +1753,8 @@ where }; } self.active_media_session = Some(pipeline_id); - self.embedder_proxy.send(( - Some(source_top_ctx_id), - EmbedderMsg::MediaSessionEvent(event), - )); + self.embedder_proxy + .send(EmbedderMsg::MediaSessionEvent(source_top_ctx_id, event)); }, #[cfg(feature = "webgpu")] FromScriptMsg::RequestAdapter(response_sender, options, ids) => self @@ -2793,9 +2788,10 @@ where let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); - self.embedder_proxy.send(( - Some(top_level_browsing_context_id), - EmbedderMsg::Panic(reason.clone(), backtrace.clone()), + self.embedder_proxy.send(EmbedderMsg::Panic( + top_level_browsing_context_id, + reason.clone(), + backtrace.clone(), )); let browsing_context = match self.browsing_contexts.get(&browsing_context_id) { @@ -2874,10 +2870,8 @@ where return warn!("{top_level_browsing_context_id}: FocusWebView on unknown top-level browsing context"); } self.webviews.focus(top_level_browsing_context_id); - self.embedder_proxy.send(( - Some(top_level_browsing_context_id), - EmbedderMsg::WebViewFocused(top_level_browsing_context_id), - )); + self.embedder_proxy + .send(EmbedderMsg::WebViewFocused(top_level_browsing_context_id)); } #[cfg_attr( @@ -2950,9 +2944,9 @@ where Some(pipeline) => pipeline, }; - self.embedder_proxy.send(( - Some(pipeline.top_level_browsing_context_id), - EmbedderMsg::EventDelivered((&event).into()), + self.embedder_proxy.send(EmbedderMsg::EventDelivered( + pipeline.top_level_browsing_context_id, + (&event).into(), )); if let Err(e) = pipeline.event_loop.send(ConstellationControlMsg::SendEvent( @@ -3052,16 +3046,13 @@ where self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal); if self.webviews.focused_webview().map(|(id, _)| id) == Some(top_level_browsing_context_id) { - self.embedder_proxy - .send((None, EmbedderMsg::WebViewBlurred)); + self.embedder_proxy.send(EmbedderMsg::WebViewBlurred); } self.webviews.remove(top_level_browsing_context_id); self.compositor_proxy .send(CompositorMsg::RemoveWebView(top_level_browsing_context_id)); - self.embedder_proxy.send(( - Some(top_level_browsing_context_id), - EmbedderMsg::WebViewClosed(top_level_browsing_context_id), - )); + self.embedder_proxy + .send(EmbedderMsg::WebViewClosed(top_level_browsing_context_id)); let Some(browsing_context) = browsing_context else { return; @@ -3431,9 +3422,9 @@ where feature = "tracing", tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace") )] - fn handle_set_cursor_msg(&mut self, cursor: Cursor) { + fn handle_set_cursor_msg(&mut self, webview_id: WebViewId, cursor: Cursor) { self.embedder_proxy - .send((None, EmbedderMsg::SetCursor(cursor))) + .send(EmbedderMsg::SetCursor(webview_id, cursor)); } #[cfg_attr( @@ -3499,11 +3490,12 @@ where }, }; // Allow the embedder to handle the url itself - let msg = ( - Some(top_level_browsing_context_id), - EmbedderMsg::AllowNavigationRequest(source_id, load_data.url.clone()), - ); - self.embedder_proxy.send(msg); + self.embedder_proxy + .send(EmbedderMsg::AllowNavigationRequest( + top_level_browsing_context_id, + source_id, + load_data.url.clone(), + )); } #[cfg_attr( @@ -4215,41 +4207,33 @@ where feature = "tracing", tracing::instrument(skip_all, fields(servo_profiling = true)) )] - fn handle_key_msg(&mut self, event: KeyboardEvent) { + fn handle_key_msg(&mut self, webview_id: WebViewId, event: KeyboardEvent) { // Send to the focused browsing contexts' current pipeline. If it // doesn't exist, fall back to sending to the compositor. - let focused_browsing_context_id = self - .webviews - .focused_webview() - .map(|(_, webview)| webview.focused_browsing_context_id); - match focused_browsing_context_id { - Some(browsing_context_id) => { - let event = CompositorEvent::KeyboardEvent(event); - let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { - Some(ctx) => ctx.pipeline_id, - None => { - return warn!( - "{}: Got key event for nonexistent browsing context", - browsing_context_id, - ); - }, - }; - let msg = ConstellationControlMsg::SendEvent(pipeline_id, event); - let result = match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.event_loop.send(msg), - None => { - return debug!("{}: Got key event after closure", pipeline_id); - }, - }; - if let Err(e) = result { - self.handle_send_error(pipeline_id, e); - } + let Some(webview) = self.webviews.get(webview_id) else { + warn!("Handling keyboard event for unknown webview: {webview_id}"); + return; + }; + let browsing_context_id = webview.focused_browsing_context_id; + let event = CompositorEvent::KeyboardEvent(event); + let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { + Some(ctx) => ctx.pipeline_id, + None => { + return warn!( + "{}: Got key event for nonexistent browsing context", + browsing_context_id, + ); }, + }; + let msg = ConstellationControlMsg::SendEvent(pipeline_id, event); + let result = match self.pipelines.get(&pipeline_id) { + Some(pipeline) => pipeline.event_loop.send(msg), None => { - warn!("No focused browsing context! Falling back to sending key to compositor"); - let event = (None, EmbedderMsg::Keyboard(event)); - self.embedder_proxy.send(event); + return debug!("{}: Got key event after closure", pipeline_id); }, + }; + if let Err(e) = result { + self.handle_send_error(pipeline_id, e); } } @@ -4410,10 +4394,8 @@ where // Focus the top-level browsing context. self.webviews.focus(top_level_browsing_context_id); - self.embedder_proxy.send(( - Some(top_level_browsing_context_id), - EmbedderMsg::WebViewFocused(top_level_browsing_context_id), - )); + self.embedder_proxy + .send(EmbedderMsg::WebViewFocused(top_level_browsing_context_id)); // Update the webview’s focused browsing context. match self.webviews.get_mut(top_level_browsing_context_id) { @@ -4557,13 +4539,13 @@ where WebDriverCommandMsg::CloseWebView(top_level_browsing_context_id) => { self.handle_close_top_level_browsing_context(top_level_browsing_context_id); }, - WebDriverCommandMsg::NewWebView(sender, load_sender) => { + WebDriverCommandMsg::NewWebView(webview_id, sender, load_sender) => { let (chan, port) = match ipc::channel() { Ok(result) => result, Err(error) => return warn!("Failed to create channel: {error:?}"), }; self.embedder_proxy - .send((None, EmbedderMsg::AllowOpeningWebView(chan))); + .send(EmbedderMsg::AllowOpeningWebView(webview_id, chan)); let webview_id = match port.recv() { Ok(Some(webview_id)) => webview_id, Ok(None) => return warn!("Embedder refused to allow opening webview"), @@ -4588,10 +4570,8 @@ where response_sender, ) => { self.webdriver.resize_channel = Some(response_sender); - self.embedder_proxy.send(( - Some(top_level_browsing_context_id), - EmbedderMsg::ResizeTo(size), - )); + self.embedder_proxy + .send(EmbedderMsg::ResizeTo(top_level_browsing_context_id, size)); }, WebDriverCommandMsg::LoadUrl( top_level_browsing_context_id, @@ -4833,11 +4813,11 @@ where .rev() .scan(current_url, &resolve_url_future), ); - let msg = ( - Some(top_level_browsing_context_id), - EmbedderMsg::HistoryChanged(entries, current_index), - ); - self.embedder_proxy.send(msg); + self.embedder_proxy.send(EmbedderMsg::HistoryChanged( + top_level_browsing_context_id, + entries, + current_index, + )); } #[cfg_attr( diff --git a/components/constellation/tracing.rs b/components/constellation/tracing.rs index f0f988d163b..562c499cef4 100644 --- a/components/constellation/tracing.rs +++ b/components/constellation/tracing.rs @@ -217,16 +217,16 @@ mod from_script { Self::WebResourceRequested(..) => target_variant!("WebResourceRequested"), Self::AllowUnload(..) => target_variant!("AllowUnload"), Self::Keyboard(..) => target_variant!("Keyboard"), - Self::ClearClipboardContents => target_variant!("ClearClipboardContents"), + Self::ClearClipboardContents(..) => target_variant!("ClearClipboardContents"), Self::GetClipboardContents(..) => target_variant!("GetClipboardContents"), Self::SetClipboardContents(..) => target_variant!("SetClipboardContents"), Self::SetCursor(..) => target_variant!("SetCursor"), Self::NewFavicon(..) => target_variant!("NewFavicon"), - Self::HeadParsed => target_variant!("HeadParsed"), + Self::HeadParsed(..) => target_variant!("HeadParsed"), Self::HistoryChanged(..) => target_variant!("HistoryChanged"), Self::SetFullscreenState(..) => target_variant!("SetFullscreenState"), - Self::LoadStart => target_variant!("LoadStart"), - Self::LoadComplete => target_variant!("LoadComplete"), + Self::LoadStart(..) => target_variant!("LoadStart"), + Self::LoadComplete(..) => target_variant!("LoadComplete"), Self::Panic(..) => target_variant!("Panic"), Self::GetSelectedBluetoothDevice(..) => { target_variant!("GetSelectedBluetoothDevice") @@ -234,11 +234,12 @@ mod from_script { Self::SelectFiles(..) => target_variant!("SelectFiles"), Self::PromptPermission(..) => target_variant!("PromptPermission"), Self::ShowIME(..) => target_variant!("ShowIME"), - Self::HideIME => target_variant!("HideIME"), + Self::HideIME(..) => target_variant!("HideIME"), Self::Shutdown => target_variant!("Shutdown"), Self::ReportProfile(..) => target_variant!("ReportProfile"), Self::MediaSessionEvent(..) => target_variant!("MediaSessionEvent"), Self::OnDevtoolsStarted(..) => target_variant!("OnDevtoolsStarted"), + Self::RequestDevtoolsConnection(..) => target_variant!("RequestDevtoolsConnection"), Self::ReadyToPresent(..) => target_variant!("ReadyToPresent"), Self::EventDelivered(..) => target_variant!("EventDelivered"), Self::PlayGamepadHapticEffect(..) => target_variant!("PlayGamepadHapticEffect"), diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 09881b64423..07cf2757777 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -26,7 +26,7 @@ use devtools_traits::{ DevtoolsControlMsg, DevtoolsPageInfo, LogLevel, NavigationState, NetworkEvent, PageError, ScriptToDevtoolsControlMsg, WorkerId, }; -use embedder_traits::{EmbedderMsg, EmbedderProxy, PromptDefinition, PromptOrigin, PromptResult}; +use embedder_traits::{EmbedderMsg, EmbedderProxy}; use ipc_channel::ipc::{self, IpcSender}; use log::{debug, trace, warn}; use serde::Serialize; @@ -154,7 +154,7 @@ fn run_server( let token = format!("{:X}", servo_rand::ServoRng::default().next_u32()); let port = bound.as_ref().map(|(_, port)| *port).ok_or(()); - embedder.send((None, EmbedderMsg::OnDevtoolsStarted(port, token.clone()))); + embedder.send(EmbedderMsg::OnDevtoolsStarted(port, token.clone())); let listener = match bound { Some((l, _)) => l, @@ -762,10 +762,7 @@ fn allow_devtools_client(stream: &mut TcpStream, embedder: &EmbedderProxy, token }; // No token found. Prompt user - let (embedder_sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let message = "Accept incoming devtools connection?".to_owned(); - let prompt = PromptDefinition::YesNo(message, embedder_sender); - let msg = EmbedderMsg::Prompt(prompt, PromptOrigin::Trusted); - embedder.send((None, msg)); - receiver.recv().unwrap() == PromptResult::Primary + let (request_sender, request_receiver) = ipc::channel().expect("Failed to create IPC channel!"); + embedder.send(EmbedderMsg::RequestDevtoolsConnection(request_sender)); + request_receiver.recv().unwrap() } diff --git a/components/fonts/font_context.rs b/components/fonts/font_context.rs index 1ebe26a20b1..908d0aba298 100644 --- a/components/fonts/font_context.rs +++ b/components/fonts/font_context.rs @@ -9,6 +9,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use app_units::Au; +use base::id::WebViewId; use fnv::FnvHasher; use fonts_traits::WebFontLoadFinishedCallback; use log::{debug, trace}; @@ -358,6 +359,7 @@ impl FontContext { #[derive(Clone)] pub(crate) struct WebFontDownloadState { + webview_id: WebViewId, pub(crate) css_font_face_descriptors: Arc<CSSFontFaceDescriptors>, remaining_sources: Vec<Source>, finished_callback: WebFontLoadFinishedCallback, @@ -369,6 +371,7 @@ pub(crate) struct WebFontDownloadState { pub trait FontContextWebFontMethods { fn add_all_web_fonts_from_stylesheet( &self, + webview_id: WebViewId, stylesheet: &DocumentStyleSheet, guard: &SharedRwLockReadGuard, device: &Device, @@ -382,6 +385,7 @@ pub trait FontContextWebFontMethods { impl FontContextWebFontMethods for Arc<FontContext> { fn add_all_web_fonts_from_stylesheet( &self, + webview_id: WebViewId, stylesheet: &DocumentStyleSheet, guard: &SharedRwLockReadGuard, device: &Device, @@ -441,6 +445,7 @@ impl FontContextWebFontMethods for Arc<FontContext> { .handle_web_font_load_started_for_stylesheet(stylesheet); self.process_next_web_font_source(WebFontDownloadState { + webview_id, css_font_face_descriptors: Arc::new(rule.into()), remaining_sources: sources, finished_callback: finished_callback.clone(), @@ -623,8 +628,12 @@ impl RemoteWebFontDownloader { }; // FIXME: This shouldn't use NoReferrer, but the current documents url - let request = RequestBuilder::new(url.clone().into(), Referrer::NoReferrer) - .destination(Destination::Font); + let request = RequestBuilder::new( + Some(state.webview_id), + url.clone().into(), + Referrer::NoReferrer, + ) + .destination(Destination::Font); debug!("Loading @font-face {} from {}", web_font_family_name, url); let downloader = Self { diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 6a4635e05e0..41a9df98e5e 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -15,7 +15,7 @@ use std::sync::{Arc, LazyLock, Mutex}; use app_units::Au; use base::cross_process_instant::CrossProcessInstant; -use base::id::PipelineId; +use base::id::{PipelineId, WebViewId}; use base::Epoch; use embedder_traits::resources::{self, Resource}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D}; @@ -119,6 +119,9 @@ pub struct LayoutThread { /// The ID of the pipeline that we belong to. id: PipelineId, + /// The webview that contains the pipeline we belong to. + webview_id: WebViewId, + /// The URL of the pipeline that we belong to. url: ServoUrl, @@ -195,18 +198,7 @@ pub struct LayoutFactoryImpl(); impl LayoutFactory for LayoutFactoryImpl { fn create(&self, config: LayoutConfig) -> Box<dyn Layout> { - Box::new(LayoutThread::new( - config.id, - config.url, - config.is_iframe, - config.script_chan, - config.image_cache, - config.font_context, - config.time_profiler_chan, - config.compositor_api, - config.paint_time_metrics, - config.window_size, - )) + Box::new(LayoutThread::new(config)) } } @@ -503,21 +495,11 @@ impl LayoutThread { self.root_flow.borrow().clone() } - #[allow(clippy::too_many_arguments)] - fn new( - id: PipelineId, - url: ServoUrl, - is_iframe: bool, - script_chan: IpcSender<ConstellationControlMsg>, - image_cache: Arc<dyn ImageCache>, - font_context: Arc<FontContext>, - time_profiler_chan: profile_time::ProfilerChan, - compositor_api: CrossProcessCompositorApi, - paint_time_metrics: PaintTimeMetrics, - window_size: WindowSizeData, - ) -> LayoutThread { + fn new(config: LayoutConfig) -> LayoutThread { // Let webrender know about this pipeline by sending an empty display list. - compositor_api.send_initial_transaction(id.into()); + config + .compositor_api + .send_initial_transaction(config.id.into()); let mut font = Font::initial_values(); let default_font_size = pref!(fonts_default_size); @@ -530,8 +512,8 @@ impl LayoutThread { let device = Device::new( MediaType::screen(), QuirksMode::NoQuirks, - window_size.initial_viewport, - Scale::new(window_size.device_pixel_ratio.get()), + config.window_size.initial_viewport, + Scale::new(config.window_size.device_pixel_ratio.get()), Box::new(LayoutFontMetricsProvider), ComputedValues::initial_values_with_font_override(font), // TODO: obtain preferred color scheme from embedder @@ -539,14 +521,15 @@ impl LayoutThread { ); LayoutThread { - id, - url, - is_iframe, - script_chan, - time_profiler_chan, + id: config.id, + webview_id: config.webview_id, + url: config.url, + is_iframe: config.is_iframe, + script_chan: config.script_chan, + time_profiler_chan: config.time_profiler_chan, registered_painters: RegisteredPaintersImpl(Default::default()), - image_cache, - font_context, + image_cache: config.image_cache, + font_context: config.font_context, first_reflow: Cell::new(true), parallel_flag: true, generation: Cell::new(0), @@ -554,16 +537,16 @@ impl LayoutThread { // Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR epoch: Cell::new(Epoch(1)), viewport_size: Size2D::new( - Au::from_f32_px(window_size.initial_viewport.width), - Au::from_f32_px(window_size.initial_viewport.height), + Au::from_f32_px(config.window_size.initial_viewport.width), + Au::from_f32_px(config.window_size.initial_viewport.height), ), - compositor_api, + compositor_api: config.compositor_api, stylist: Stylist::new(device, QuirksMode::NoQuirks), display_list: Default::default(), indexable_text: Default::default(), scroll_offsets: Default::default(), webrender_image_cache: Arc::new(RwLock::new(FnvHashMap::default())), - paint_time_metrics, + paint_time_metrics: config.paint_time_metrics, last_iframe_sizes: Default::default(), debug: opts::get().debug.clone(), nonincremental_layout: opts::get().nonincremental_layout, @@ -640,6 +623,7 @@ impl LayoutThread { }; self.font_context.add_all_web_fonts_from_stylesheet( + self.webview_id, stylesheet, guard, self.stylist.device(), diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 7c689ec7cc3..231ae8ca77f 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -16,7 +16,7 @@ use std::sync::{Arc, LazyLock}; use app_units::Au; use base::cross_process_instant::CrossProcessInstant; -use base::id::PipelineId; +use base::id::{PipelineId, WebViewId}; use base::Epoch; use embedder_traits::resources::{self, Resource}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D}; @@ -105,6 +105,9 @@ pub struct LayoutThread { /// The ID of the pipeline that we belong to. id: PipelineId, + /// The webview that contains the pipeline we belong to. + webview_id: WebViewId, + /// The URL of the pipeline that we belong to. url: ServoUrl, @@ -169,18 +172,7 @@ pub struct LayoutFactoryImpl(); impl LayoutFactory for LayoutFactoryImpl { fn create(&self, config: LayoutConfig) -> Box<dyn Layout> { - Box::new(LayoutThread::new( - config.id, - config.url, - config.is_iframe, - config.script_chan, - config.image_cache, - config.font_context, - config.time_profiler_chan, - config.compositor_api, - config.paint_time_metrics, - config.window_size, - )) + Box::new(LayoutThread::new(config)) } } @@ -476,23 +468,12 @@ impl Layout for LayoutThread { } } -#[allow(clippy::too_many_arguments)] impl LayoutThread { - #[allow(clippy::too_many_arguments)] - fn new( - id: PipelineId, - url: ServoUrl, - is_iframe: bool, - script_chan: IpcSender<ConstellationControlMsg>, - image_cache: Arc<dyn ImageCache>, - font_context: Arc<FontContext>, - time_profiler_chan: profile_time::ProfilerChan, - compositor_api: CrossProcessCompositorApi, - paint_time_metrics: PaintTimeMetrics, - window_size: WindowSizeData, - ) -> LayoutThread { + fn new(config: LayoutConfig) -> LayoutThread { // Let webrender know about this pipeline by sending an empty display list. - compositor_api.send_initial_transaction(id.into()); + config + .compositor_api + .send_initial_transaction(config.id.into()); let mut font = Font::initial_values(); let default_font_size = pref!(fonts_default_size); @@ -507,23 +488,24 @@ impl LayoutThread { let device = Device::new( MediaType::screen(), QuirksMode::NoQuirks, - window_size.initial_viewport, - Scale::new(window_size.device_pixel_ratio.get()), - Box::new(LayoutFontMetricsProvider(font_context.clone())), + config.window_size.initial_viewport, + Scale::new(config.window_size.device_pixel_ratio.get()), + Box::new(LayoutFontMetricsProvider(config.font_context.clone())), ComputedValues::initial_values_with_font_override(font), // TODO: obtain preferred color scheme from embedder PrefersColorScheme::Light, ); LayoutThread { - id, - url, - is_iframe, - script_chan: script_chan.clone(), - time_profiler_chan, + id: config.id, + webview_id: config.webview_id, + url: config.url, + is_iframe: config.is_iframe, + script_chan: config.script_chan.clone(), + time_profiler_chan: config.time_profiler_chan, registered_painters: RegisteredPaintersImpl(Default::default()), - image_cache, - font_context, + image_cache: config.image_cache, + font_context: config.font_context, first_reflow: Cell::new(true), generation: Cell::new(0), box_tree: Default::default(), @@ -531,14 +513,14 @@ impl LayoutThread { // Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR epoch: Cell::new(Epoch(1)), viewport_size: Size2D::new( - Au::from_f32_px(window_size.initial_viewport.width), - Au::from_f32_px(window_size.initial_viewport.height), + Au::from_f32_px(config.window_size.initial_viewport.width), + Au::from_f32_px(config.window_size.initial_viewport.height), ), - compositor_api, + compositor_api: config.compositor_api, scroll_offsets: Default::default(), stylist: Stylist::new(device, QuirksMode::NoQuirks), webrender_image_cache: Default::default(), - paint_time_metrics, + paint_time_metrics: config.paint_time_metrics, debug: opts::get().debug.clone(), } } @@ -619,6 +601,7 @@ impl LayoutThread { }; self.font_context.add_all_web_fonts_from_stylesheet( + self.webview_id, stylesheet, guard, self.stylist.device(), diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index cfaa22fc455..828d524b40f 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -195,18 +195,6 @@ pub fn should_request_be_blocked_by_csp( .unwrap_or(csp::CheckResult::Allowed) } -pub fn maybe_intercept_request( - request: &mut Request, - context: &FetchContext, - response: &mut Option<Response>, -) { - context - .request_intercepter - .lock() - .unwrap() - .intercept_request(request, response, context); -} - /// [Main fetch](https://fetch.spec.whatwg.org/#concept-main-fetch) pub async fn main_fetch( fetch_params: &mut FetchParams, @@ -314,7 +302,11 @@ pub async fn main_fetch( let current_scheme = current_url.scheme(); // Intercept the request and maybe override the response. - maybe_intercept_request(request, context, &mut response); + context + .request_intercepter + .lock() + .unwrap() + .intercept_request(request, &mut response, context); let mut response = match response { Some(res) => res, diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 65c3736bf24..007ebae78c4 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, RwLock, Weak}; +use base::id::WebViewId; use embedder_traits::{EmbedderMsg, EmbedderProxy, FilterPattern}; use headers::{ContentLength, ContentRange, ContentType, HeaderMap, HeaderMapExt, Range}; use http::header::{self, HeaderValue}; @@ -153,14 +154,14 @@ impl FileManager { /// Message handler pub fn handle(&self, msg: FileManagerThreadMsg) { match msg { - FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => { + FileManagerThreadMsg::SelectFile(webview_id, filter, sender, origin, opt_test_path) => { let store = self.store.clone(); let embedder = self.embedder_proxy.clone(); self.thread_pool .upgrade() .map(|pool| { pool.spawn(move || { - store.select_file(filter, sender, origin, opt_test_path, embedder); + store.select_file(webview_id, filter, sender, origin, opt_test_path, embedder); }); }) .unwrap_or_else(|| { @@ -169,14 +170,20 @@ impl FileManager { ); }); }, - FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => { + FileManagerThreadMsg::SelectFiles( + webview_id, + filter, + sender, + origin, + opt_test_paths, + ) => { let store = self.store.clone(); let embedder = self.embedder_proxy.clone(); self.thread_pool .upgrade() .map(|pool| { pool.spawn(move || { - store.select_files(filter, sender, origin, opt_test_paths, embedder); + store.select_files(webview_id, filter, sender, origin, opt_test_paths, embedder); }); }) .unwrap_or_else(|| { @@ -571,17 +578,18 @@ impl FileManagerStore { fn query_files_from_embedder( &self, + webview_id: WebViewId, patterns: Vec<FilterPattern>, multiple_files: bool, embedder_proxy: EmbedderProxy, ) -> Option<Vec<String>> { let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = ( - None, - EmbedderMsg::SelectFiles(patterns, multiple_files, ipc_sender), - ); - - embedder_proxy.send(msg); + embedder_proxy.send(EmbedderMsg::SelectFiles( + webview_id, + patterns, + multiple_files, + ipc_sender, + )); match ipc_receiver.recv() { Ok(result) => result, Err(e) => { @@ -593,6 +601,7 @@ impl FileManagerStore { fn select_file( &self, + webview_id: WebViewId, patterns: Vec<FilterPattern>, sender: IpcSender<FileManagerResult<SelectedFile>>, origin: FileOrigin, @@ -605,7 +614,7 @@ impl FileManagerStore { let opt_s = if pref!(dom_testing_html_input_element_select_files_enabled) { opt_test_path } else { - self.query_files_from_embedder(patterns, false, embedder_proxy) + self.query_files_from_embedder(webview_id, patterns, false, embedder_proxy) .and_then(|mut x| x.pop()) }; @@ -623,6 +632,7 @@ impl FileManagerStore { fn select_files( &self, + webview_id: WebViewId, patterns: Vec<FilterPattern>, sender: IpcSender<FileManagerResult<Vec<SelectedFile>>>, origin: FileOrigin, @@ -635,7 +645,7 @@ impl FileManagerStore { let opt_v = if pref!(dom_testing_html_input_element_select_files_enabled) { opt_test_paths } else { - self.query_files_from_embedder(patterns, true, embedder_proxy) + self.query_files_from_embedder(webview_id, patterns, true, embedder_proxy) }; match opt_v { diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index d6c4e80a609..89ec17adae3 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -9,7 +9,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use async_recursion::async_recursion; use base::cross_process_instant::CrossProcessInstant; -use base::id::{HistoryStateId, PipelineId, TopLevelBrowsingContextId}; +use base::id::{HistoryStateId, PipelineId, WebViewId}; use crossbeam_channel::Sender; use devtools_traits::{ ChromeToDevtoolsControlMsg, DevtoolsControlMsg, HttpRequest as DevtoolsHttpRequest, @@ -1583,10 +1583,12 @@ async fn http_network_or_cache_fetch( // Step 14.3 If request’s use-URL-credentials flag is unset or isAuthenticationFetch is true, then: if !http_request.use_url_credentials || authentication_fetch_flag { - let Some(credentials) = prompt_user_for_credentials( - &context.state.embedder_proxy, - http_request.target_browsing_context_id, - ) else { + let Some(webview_id) = http_request.target_webview_id else { + return response; + }; + let Some(credentials) = + prompt_user_for_credentials(&context.state.embedder_proxy, webview_id) + else { return response; }; let Some(username) = credentials.username else { @@ -1639,10 +1641,12 @@ async fn http_network_or_cache_fetch( // Step 15.4 Prompt the end user as appropriate in request’s window // window and store the result as a proxy-authentication entry. - let Some(credentials) = prompt_user_for_credentials( - &context.state.embedder_proxy, - http_request.target_browsing_context_id, - ) else { + let Some(webview_id) = http_request.target_webview_id else { + return response; + }; + let Some(credentials) = + prompt_user_for_credentials(&context.state.embedder_proxy, webview_id) + else { return response; }; let Some(user_name) = credentials.username else { @@ -1779,18 +1783,16 @@ impl Drop for ResponseEndTimer { fn prompt_user_for_credentials( embedder_proxy: &Mutex<EmbedderProxy>, - top_level_browsing_context_id: Option<TopLevelBrowsingContextId>, + webview_id: WebViewId, ) -> Option<PromptCredentialsInput> { let proxy = embedder_proxy.lock().unwrap(); let (ipc_sender, ipc_receiver) = ipc::channel().unwrap(); - proxy.send(( - top_level_browsing_context_id, - EmbedderMsg::Prompt( - PromptDefinition::Credentials(ipc_sender), - PromptOrigin::Trusted, - ), + proxy.send(EmbedderMsg::Prompt( + webview_id, + PromptDefinition::Credentials(ipc_sender), + PromptOrigin::Trusted, )); let Ok(credentials) = ipc_receiver.recv() else { @@ -2100,21 +2102,25 @@ async fn cors_preflight_fetch( context: &FetchContext, ) -> Response { // Step 1 - let mut preflight = RequestBuilder::new(request.current_url(), request.referrer.clone()) - .method(Method::OPTIONS) - .origin(match &request.origin { - Origin::Client => { - unreachable!("We shouldn't get Client origin in cors_preflight_fetch.") - }, - Origin::Origin(origin) => origin.clone(), - }) - .pipeline_id(request.pipeline_id) - .initiator(request.initiator) - .destination(request.destination) - .referrer_policy(request.referrer_policy) - .mode(RequestMode::CorsMode) - .response_tainting(ResponseTainting::CorsTainting) - .build(); + let mut preflight = RequestBuilder::new( + request.target_webview_id, + request.current_url(), + request.referrer.clone(), + ) + .method(Method::OPTIONS) + .origin(match &request.origin { + Origin::Client => { + unreachable!("We shouldn't get Client origin in cors_preflight_fetch.") + }, + Origin::Origin(origin) => origin.clone(), + }) + .pipeline_id(request.pipeline_id) + .initiator(request.initiator) + .destination(request.destination) + .referrer_policy(request.referrer_policy) + .mode(RequestMode::CorsMode) + .response_tainting(ResponseTainting::CorsTainting) + .build(); // Step 2 preflight diff --git a/components/net/request_intercepter.rs b/components/net/request_intercepter.rs index 8bb55bd2882..9ef07fe9f3a 100644 --- a/components/net/request_intercepter.rs +++ b/components/net/request_intercepter.rs @@ -40,9 +40,10 @@ impl RequestIntercepter { request.redirect_count > 0, ); - self.embedder_proxy.send(( - request.target_browsing_context_id, - EmbedderMsg::WebResourceRequested(req, tx), + self.embedder_proxy.send(EmbedderMsg::WebResourceRequested( + request.target_webview_id, + req, + tx, )); let mut response_received = false; diff --git a/components/net/tests/data_loader.rs b/components/net/tests/data_loader.rs index 25c50ba011d..b4082812229 100644 --- a/components/net/tests/data_loader.rs +++ b/components/net/tests/data_loader.rs @@ -24,7 +24,7 @@ fn assert_parse( use net_traits::request::RequestBuilder; let url = ServoUrl::parse(url).unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .pipeline_id(None) .build(); diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs index ea51fe5d757..b5af2b640d5 100644 --- a/components/net/tests/fetch.rs +++ b/components/net/tests/fetch.rs @@ -65,7 +65,7 @@ fn test_fetch_response_is_not_network_error() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -79,7 +79,7 @@ fn test_fetch_response_is_not_network_error() { #[test] fn test_fetch_on_bad_port_is_network_error() { let url = ServoUrl::parse("http://www.example.org:6667").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -101,7 +101,7 @@ fn test_fetch_response_body_matches_const_message() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -121,7 +121,7 @@ fn test_fetch_response_body_matches_const_message() { #[test] fn test_fetch_aboutblank() { let url = ServoUrl::parse("about:blank").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); @@ -186,7 +186,7 @@ fn test_fetch_blob() { ); let url = ServoUrl::parse(&format!("blob:{}{}", origin.as_str(), id.simple())).unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(origin.origin()) .build(); @@ -228,7 +228,7 @@ fn test_file() { .unwrap(); let url = ServoUrl::from_file_path(path.clone()).unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); @@ -271,7 +271,7 @@ fn test_file() { #[test] fn test_fetch_ftp() { let url = ServoUrl::parse("ftp://not-supported").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -281,7 +281,7 @@ fn test_fetch_ftp() { #[test] fn test_fetch_bogus_scheme() { let url = ServoUrl::parse("bogus://whatever").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -330,7 +330,7 @@ fn test_cors_preflight_fetch() { let (server, url) = make_server(handler); let target_url = url.clone().join("a.html").unwrap(); - let mut request = RequestBuilder::new(url, Referrer::ReferrerUrl(target_url)).build(); + let mut request = RequestBuilder::new(None, url, Referrer::ReferrerUrl(target_url)).build(); request.referrer_policy = ReferrerPolicy::Origin; request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; @@ -383,7 +383,7 @@ fn test_cors_preflight_cache_fetch() { }; let (server, url) = make_server(handler); - let mut request = RequestBuilder::new(url, Referrer::NoReferrer).build(); + let mut request = RequestBuilder::new(None, url, Referrer::NoReferrer).build(); request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; let wrapped_request0 = request.clone(); @@ -448,7 +448,7 @@ fn test_cors_preflight_fetch_network_error() { }; let (server, url) = make_server(handler); - let mut request = RequestBuilder::new(url, Referrer::NoReferrer).build(); + let mut request = RequestBuilder::new(None, url, Referrer::NoReferrer).build(); request.method = Method::from_bytes(b"CHICKEN").unwrap(); request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; @@ -477,7 +477,7 @@ fn test_fetch_response_is_basic_filtered() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -542,7 +542,7 @@ fn test_fetch_response_is_cors_filtered() { let (server, url) = make_server(handler); // an origin mis-match will stop it from defaulting to a basic filtered response - let mut request = RequestBuilder::new(url, Referrer::NoReferrer).build(); + let mut request = RequestBuilder::new(None, url, Referrer::NoReferrer).build(); request.mode = RequestMode::CorsMode; let fetch_response = fetch(request, None); let _ = server.close(); @@ -576,7 +576,7 @@ fn test_fetch_response_is_opaque_filtered() { let (server, url) = make_server(handler); // an origin mis-match will fall through to an Opaque filtered response - let request = RequestBuilder::new(url, Referrer::NoReferrer).build(); + let request = RequestBuilder::new(None, url, Referrer::NoReferrer).build(); let fetch_response = fetch(request, None); let _ = server.close(); @@ -624,7 +624,7 @@ fn test_fetch_response_is_opaque_redirect_filtered() { let (server, url) = make_server(handler); - let mut request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let mut request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); request.redirect_mode = RedirectMode::Manual; @@ -660,7 +660,7 @@ fn test_fetch_with_local_urls_only() { let (server, server_url) = make_server(handler); let do_fetch = |url: ServoUrl| { - let mut request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let mut request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); @@ -728,7 +728,7 @@ fn test_fetch_with_hsts() { HstsEntry::new("localhost".to_owned(), IncludeSubdomains::NotIncluded, None).unwrap(), ); } - let mut request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let mut request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); // Set the flag. @@ -782,7 +782,7 @@ fn test_load_adds_host_to_hsts_list_when_url_is_https() { context.state.override_manager.add_override(certificate); } - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -838,7 +838,7 @@ fn test_fetch_self_signed() { protocols: Arc::new(ProtocolRegistry::default()), }; - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -859,7 +859,7 @@ fn test_fetch_self_signed() { context.state.override_manager.add_override(certificate); } - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -884,7 +884,7 @@ fn test_fetch_with_sri_network_error() { }; let (server, url) = make_server(handler); - let mut request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let mut request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); // To calulate hash use : @@ -910,7 +910,7 @@ fn test_fetch_with_sri_sucess() { }; let (server, url) = make_server(handler); - let mut request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let mut request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); // To calulate hash use : @@ -952,7 +952,7 @@ fn test_fetch_blocked_nosniff() { let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .destination(destination) .build(); @@ -999,7 +999,7 @@ fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -1089,7 +1089,7 @@ fn test_fetch_redirect_updates_method_runner( let (server, url) = crate::make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .method(method) .build(); @@ -1174,7 +1174,7 @@ fn test_fetch_async_returns_complete_response() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let fetch_response = fetch(request, None); @@ -1194,7 +1194,7 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() { let (server, url) = make_server(handler); // an origin mis-match will fall through to an Opaque filtered response - let request = RequestBuilder::new(url, Referrer::NoReferrer).build(); + let request = RequestBuilder::new(None, url, Referrer::NoReferrer).build(); let fetch_response = fetch(request, None); let _ = server.close(); @@ -1228,7 +1228,7 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .redirect_mode(RedirectMode::Manual) .build(); @@ -1253,7 +1253,7 @@ fn test_fetch_with_devtools() { let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .redirect_mode(RedirectMode::Manual) .pipeline_id(Some(TEST_PIPELINE_ID)) @@ -1341,12 +1341,13 @@ fn test_fetch_request_intercepted() { static HEADERVALUE: &str = "custom-value"; static STATUS_MESSAGE: &[u8] = b"custom status message"; - let (embedder_proxy, mut embedder_receiver) = create_embedder_proxy_and_receiver(); + let (embedder_proxy, embedder_receiver) = create_embedder_proxy_and_receiver(); std::thread::spawn(move || { - let (_browser_context_id, embedder_msg) = embedder_receiver.recv_embedder_msg(); + let embedder_msg = embedder_receiver.recv().unwrap(); match embedder_msg { embedder_traits::EmbedderMsg::WebResourceRequested( + _, web_resource_request, response_sender, ) => { @@ -1396,7 +1397,7 @@ fn test_fetch_request_intercepted() { }; let url = ServoUrl::parse("http://www.example.org").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .origin(url.origin()) .build(); let response = fetch_with_context(request, &mut context); diff --git a/components/net/tests/filemanager_thread.rs b/components/net/tests/filemanager_thread.rs index 0e3e8aeb91a..805f94d39ab 100644 --- a/components/net/tests/filemanager_thread.rs +++ b/components/net/tests/filemanager_thread.rs @@ -7,6 +7,7 @@ use std::io::Read; use std::path::PathBuf; use std::sync::Arc; +use base::id::TEST_WEBVIEW_ID; use embedder_traits::FilterPattern; use ipc_channel::ipc; use net::filemanager_thread::FileManager; @@ -44,6 +45,7 @@ fn test_filemanager() { // Try to select a dummy file "components/net/tests/test.jpeg" let (tx, rx) = ipc::channel().unwrap(); filemanager.handle(FileManagerThreadMsg::SelectFile( + TEST_WEBVIEW_ID, patterns.clone(), tx, origin.clone(), diff --git a/components/net/tests/http_cache.rs b/components/net/tests/http_cache.rs index 478e452213b..57d2d5f0dba 100644 --- a/components/net/tests/http_cache.rs +++ b/components/net/tests/http_cache.rs @@ -20,7 +20,7 @@ fn test_refreshing_resource_sets_done_chan_the_appropriate_value() { ResponseBody::Done(vec![]), ]; let url = ServoUrl::parse("https://servo.org").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .pipeline_id(Some(TEST_PIPELINE_ID)) .origin(url.origin()) .build(); diff --git a/components/net/tests/http_loader.rs b/components/net/tests/http_loader.rs index 17178f820aa..793a73826dd 100644 --- a/components/net/tests/http_loader.rs +++ b/components/net/tests/http_loader.rs @@ -10,7 +10,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, RwLock}; use std::time::Duration; -use base::id::TEST_PIPELINE_ID; +use base::id::{TEST_PIPELINE_ID, TEST_WEBVIEW_ID}; use cookie::Cookie as CookiePair; use crossbeam_channel::{unbounded, Receiver}; use devtools_traits::{ @@ -175,7 +175,7 @@ fn test_check_default_headers_loaded_in_every_request() { *expected_headers.lock().unwrap() = Some(headers.clone()); // Testing for method.GET - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(url.clone().origin()) @@ -201,7 +201,7 @@ fn test_check_default_headers_loaded_in_every_request() { HeaderValue::from_str(&url_str[..url_str.len() - 1]).unwrap(), ); *expected_headers.lock().unwrap() = Some(post_headers); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::POST) .destination(Destination::Document) .origin(url.clone().origin()) @@ -231,7 +231,7 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::POST) .body(None) .destination(Destination::Document) @@ -264,7 +264,7 @@ fn test_request_and_response_data_with_network_messages() { let mut request_headers = HeaderMap::new(); request_headers.typed_insert(Host::from("bar.foo".parse::<Authority>().unwrap())); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .headers(request_headers) .body(None) @@ -377,7 +377,7 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -417,7 +417,7 @@ fn test_redirected_request_to_devtools() { }; let (pre_server, pre_url) = make_server(pre_handler); - let request = RequestBuilder::new(pre_url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, pre_url.clone(), Referrer::NoReferrer) .method(Method::POST) .destination(Destination::Document) .pipeline_id(Some(TEST_PIPELINE_ID)) @@ -470,7 +470,7 @@ fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() { }; let (pre_server, pre_url) = make_server(pre_handler); - let request = RequestBuilder::new(pre_url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, pre_url.clone(), Referrer::NoReferrer) .method(Method::POST) .destination(Destination::Document) .origin(mock_origin()) @@ -502,7 +502,7 @@ fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_co }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -537,7 +537,7 @@ fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_conte }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -584,7 +584,7 @@ fn test_load_doesnt_send_request_body_on_any_redirect() { let content = b"Body on POST!"; let request_body = create_request_body_with_content(content.to_vec()); - let request = RequestBuilder::new(pre_url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, pre_url.clone(), Referrer::NoReferrer) .body(Some(request_body)) .method(Method::POST) .destination(Destination::Document) @@ -614,7 +614,7 @@ fn test_load_doesnt_add_host_to_hsts_list_when_url_is_http_even_if_hsts_headers_ }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -661,7 +661,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_ assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -714,7 +714,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re cookie_jar.push(cookie, &url, CookieSource::HTTP); } - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -761,7 +761,7 @@ fn test_load_sends_cookie_if_nonhttp() { cookie_jar.push(cookie, &url, CookieSource::HTTP); } - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -800,7 +800,7 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl( assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -849,7 +849,7 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() { assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -884,7 +884,7 @@ fn test_load_sets_content_length_to_length_of_request_body() { let request_body = create_request_body_with_content(content.to_vec()); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::POST) .body(Some(request_body)) .destination(Destination::Document) @@ -924,7 +924,7 @@ fn test_load_uses_explicit_accept_from_headers_in_load_data() { let mut accept_headers = HeaderMap::new(); accept_headers.insert(header::ACCEPT, HeaderValue::from_static("text/html")); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .headers(accept_headers) .destination(Destination::Document) @@ -962,7 +962,7 @@ fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1001,7 +1001,7 @@ fn test_load_uses_explicit_accept_encoding_from_load_data_headers() { let mut accept_encoding_headers = HeaderMap::new(); accept_encoding_headers.insert(header::ACCEPT_ENCODING, HeaderValue::from_static("chunked")); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .headers(accept_encoding_headers) .destination(Destination::Document) @@ -1039,7 +1039,7 @@ fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1095,7 +1095,7 @@ fn test_load_errors_when_there_a_redirect_loop() { *url_b_for_a.lock().unwrap() = Some(url_b.clone()); - let request = RequestBuilder::new(url_a.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url_a.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1155,7 +1155,7 @@ fn test_load_succeeds_with_a_redirect_loop() { *url_b_for_a.lock().unwrap() = Some(url_b.clone()); - let request = RequestBuilder::new(url_a.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url_a.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1198,7 +1198,7 @@ fn test_load_follows_a_redirect() { }; let (pre_server, pre_url) = make_server(pre_handler); - let request = RequestBuilder::new(pre_url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, pre_url.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1283,7 +1283,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() { cookie_jar.push(cookie_y, &url_y, CookieSource::HTTP); } - let request = RequestBuilder::new(url_x.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url_x.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1334,7 +1334,7 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() { let url = url.join("/initial/").unwrap(); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .destination(Destination::Document) .origin(mock_origin()) @@ -1367,7 +1367,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -1412,7 +1412,7 @@ fn test_auth_ui_needs_www_auth() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -1479,7 +1479,7 @@ fn test_fetch_compressed_response_update_count() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(None, url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -1565,7 +1565,7 @@ fn test_user_credentials_prompt_when_proxy_authentication_is_required() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(Some(TEST_WEBVIEW_ID), url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -1613,7 +1613,7 @@ fn test_prompt_credentials_when_client_receives_unauthorized_response() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(Some(TEST_WEBVIEW_ID), url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -1660,7 +1660,7 @@ fn test_prompt_credentials_user_cancels_dialog_input() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(Some(TEST_WEBVIEW_ID), url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) @@ -1703,7 +1703,7 @@ fn test_prompt_credentials_user_input_incorrect_credentials() { }; let (server, url) = make_server(handler); - let request = RequestBuilder::new(url.clone(), Referrer::NoReferrer) + let request = RequestBuilder::new(Some(TEST_WEBVIEW_ID), url.clone(), Referrer::NoReferrer) .method(Method::GET) .body(None) .destination(Destination::Document) diff --git a/components/net/tests/main.rs b/components/net/tests/main.rs index a897d5d5bfa..ef18bef2427 100644 --- a/components/net/tests/main.rs +++ b/components/net/tests/main.rs @@ -26,9 +26,9 @@ use std::net::TcpListener as StdTcpListener; use std::path::{Path, PathBuf}; use std::sync::{Arc, LazyLock, Mutex, RwLock, Weak}; -use crossbeam_channel::{unbounded, Sender}; +use crossbeam_channel::{unbounded, Receiver, Sender}; use devtools_traits::DevtoolsControlMsg; -use embedder_traits::{EmbedderProxy, EmbedderReceiver, EventLoopWaker}; +use embedder_traits::{EmbedderMsg, EmbedderProxy, EventLoopWaker}; use futures::future::ready; use http_body_util::combinators::BoxBody; use http_body_util::{BodyExt, Empty, Full}; @@ -96,7 +96,7 @@ fn create_embedder_proxy() -> EmbedderProxy { } } -fn create_embedder_proxy_and_receiver() -> (EmbedderProxy, EmbedderReceiver) { +fn create_embedder_proxy_and_receiver() -> (EmbedderProxy, Receiver<EmbedderMsg>) { let (sender, receiver) = unbounded(); let event_loop_waker = || { struct DummyEventLoopWaker {} @@ -120,19 +120,18 @@ fn create_embedder_proxy_and_receiver() -> (EmbedderProxy, EmbedderReceiver) { event_loop_waker: event_loop_waker(), }; - let embedder_receiver = EmbedderReceiver { receiver }; - (embedder_proxy, embedder_receiver) + (embedder_proxy, receiver) } fn receive_credential_prompt_msgs( - mut embedder_receiver: EmbedderReceiver, + embedder_receiver: Receiver<EmbedderMsg>, username: Option<String>, password: Option<String>, ) -> std::thread::JoinHandle<()> { std::thread::spawn(move || loop { - let (_browser_context_id, embedder_msg) = embedder_receiver.recv_embedder_msg(); + let embedder_msg = embedder_receiver.recv().unwrap(); match embedder_msg { - embedder_traits::EmbedderMsg::Prompt(prompt_definition, _prompt_origin) => { + embedder_traits::EmbedderMsg::Prompt(_, prompt_definition, _prompt_origin) => { match prompt_definition { embedder_traits::PromptDefinition::Credentials(ipc_sender) => { ipc_sender @@ -143,7 +142,7 @@ fn receive_credential_prompt_msgs( } break; }, - embedder_traits::EmbedderMsg::WebResourceRequested(_, _) => {}, + embedder_traits::EmbedderMsg::WebResourceRequested(..) => {}, _ => unreachable!(), } }) diff --git a/components/script/clipboard_provider.rs b/components/script/clipboard_provider.rs index 666bf74c825..32d80bb3f32 100644 --- a/components/script/clipboard_provider.rs +++ b/components/script/clipboard_provider.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use base::id::WebViewId; use embedder_traits::EmbedderMsg; use ipc_channel::ipc::channel; use script_traits::{ScriptMsg, ScriptToConstellationChan}; @@ -13,19 +14,26 @@ pub trait ClipboardProvider { fn set_clipboard_contents(&mut self, _: String); } -impl ClipboardProvider for ScriptToConstellationChan { +pub(crate) struct EmbedderClipboardProvider { + pub constellation_sender: ScriptToConstellationChan, + pub webview_id: WebViewId, +} + +impl ClipboardProvider for EmbedderClipboardProvider { fn clipboard_contents(&mut self) -> String { let (tx, rx) = channel().unwrap(); - self.send(ScriptMsg::ForwardToEmbedder( - EmbedderMsg::GetClipboardContents(tx), - )) - .unwrap(); + self.constellation_sender + .send(ScriptMsg::ForwardToEmbedder( + EmbedderMsg::GetClipboardContents(self.webview_id, tx), + )) + .unwrap(); rx.recv().unwrap() } fn set_clipboard_contents(&mut self, s: String) { - self.send(ScriptMsg::ForwardToEmbedder( - EmbedderMsg::SetClipboardContents(s), - )) - .unwrap(); + self.constellation_sender + .send(ScriptMsg::ForwardToEmbedder( + EmbedderMsg::SetClipboardContents(self.webview_id, s), + )) + .unwrap(); } } diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 42b18974b5f..9141ee17450 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -220,6 +220,7 @@ impl Bluetooth { } let option = RequestDeviceoptions::new( + self.global().as_window().webview_id(), BluetoothScanfilterSequence::new(uuid_filters), ServiceUUIDSequence::new(optional_services_uuids), ); diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 745b5dd9aeb..ba4ac308ad0 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -6,7 +6,7 @@ use std::sync::atomic::AtomicBool; use std::sync::Arc; use std::thread::{self, JoinHandle}; -use base::id::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; +use base::id::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId, WebViewId}; use crossbeam_channel::{unbounded, Receiver, Sender}; use devtools_traits::DevtoolScriptControlMsg; use dom_struct::dom_struct; @@ -236,6 +236,10 @@ impl WorkerEventLoopMethods for DedicatedWorkerGlobalScope { } impl DedicatedWorkerGlobalScope { + pub(crate) fn webview_id(&self) -> Option<WebViewId> { + WebViewId::installed() + } + #[allow(clippy::too_many_arguments)] fn new_inherited( init: WorkerGlobalScopeInit, @@ -361,15 +365,19 @@ impl DedicatedWorkerGlobalScope { let referrer = referrer_url.map(Referrer::ReferrerUrl).unwrap_or(referrer); - let request = RequestBuilder::new(worker_url.clone(), referrer) - .destination(Destination::Worker) - .mode(RequestMode::SameOrigin) - .credentials_mode(CredentialsMode::CredentialsSameOrigin) - .parser_metadata(ParserMetadata::NotParserInserted) - .use_url_credentials(true) - .pipeline_id(Some(pipeline_id)) - .referrer_policy(referrer_policy) - .origin(origin); + let request = RequestBuilder::new( + top_level_browsing_context_id, + worker_url.clone(), + referrer, + ) + .destination(Destination::Worker) + .mode(RequestMode::SameOrigin) + .credentials_mode(CredentialsMode::CredentialsSameOrigin) + .parser_metadata(ParserMetadata::NotParserInserted) + .use_url_credentials(true) + .pipeline_id(Some(pipeline_id)) + .referrer_policy(referrer_policy) + .origin(origin); let runtime = unsafe { let task_source = SendableTaskSource { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 689a848caed..f7bfc88de82 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -15,6 +15,7 @@ use std::sync::{LazyLock, Mutex}; use std::time::{Duration, Instant}; use base::cross_process_instant::CrossProcessInstant; +use base::id::WebViewId; use canvas_traits::webgl::{self, WebGLContextId, WebGLMsg}; use chrono::Local; use content_security_policy::{self as csp, CspList}; @@ -648,6 +649,10 @@ impl Document { } } + pub(crate) fn webview_id(&self) -> WebViewId { + self.window.webview_id() + } + #[inline] pub(crate) fn window(&self) -> &Window { &self.window @@ -1027,13 +1032,13 @@ impl Document { match state { DocumentReadyState::Loading => { if self.window().is_top_level() { - self.send_to_embedder(EmbedderMsg::LoadStart); - self.send_to_embedder(EmbedderMsg::Status(None)); + self.send_to_embedder(EmbedderMsg::LoadStart(self.webview_id())); + self.send_to_embedder(EmbedderMsg::Status(self.webview_id(), None)); } }, DocumentReadyState::Complete => { if self.window().is_top_level() { - self.send_to_embedder(EmbedderMsg::LoadComplete); + self.send_to_embedder(EmbedderMsg::LoadComplete(self.webview_id())); } update_with_current_instant(&self.dom_complete); }, @@ -1121,7 +1126,7 @@ impl Document { // Notify the embedder to hide the input method. if elem.input_method_type().is_some() { - self.send_to_embedder(EmbedderMsg::HideIME); + self.send_to_embedder(EmbedderMsg::HideIME(self.webview_id())); } } @@ -1165,6 +1170,7 @@ impl Document { (None, false) }; self.send_to_embedder(EmbedderMsg::ShowIME( + self.webview_id(), kind, text, multiline, @@ -1225,7 +1231,7 @@ impl Document { let window = self.window(); if window.is_top_level() { let title = self.title().map(String::from); - self.send_to_embedder(EmbedderMsg::ChangePageTitle(title)); + self.send_to_embedder(EmbedderMsg::ChangePageTitle(self.webview_id(), title)); } } @@ -1621,7 +1627,7 @@ impl Document { // Step 1 if drag_data_store.list_len() > 0 { // Step 1.1 Clear the clipboard. - self.send_to_embedder(EmbedderMsg::ClearClipboardContents); + self.send_to_embedder(EmbedderMsg::ClearClipboardContents(self.webview_id())); // Step 1.2 for item in drag_data_store.iter_item_list() { match item { @@ -1629,7 +1635,10 @@ impl Document { // Step 1.2.1.1 Ensure encoding is correct per OS and locale conventions // Step 1.2.1.2 Normalize line endings according to platform conventions // Step 1.2.1.3 - self.send_to_embedder(EmbedderMsg::SetClipboardContents(string.data())); + self.send_to_embedder(EmbedderMsg::SetClipboardContents( + self.webview_id(), + string.data(), + )); }, Kind::File(_) => { // Step 1.2.2 If data is of a type listed in the mandatory data types list, then @@ -1642,7 +1651,7 @@ impl Document { // Step 2.1 if drag_data_store.clear_was_called { // Step 2.1.1 If types-to-clear list is empty, clear the clipboard - self.send_to_embedder(EmbedderMsg::ClearClipboardContents); + self.send_to_embedder(EmbedderMsg::ClearClipboardContents(self.webview_id())); // Step 2.1.2 Else remove the types in the list from the clipboard // As of now this can't be done with Arboard, and it's possible that will be removed from the spec } @@ -2049,7 +2058,7 @@ impl Document { } if cancel_state == EventDefault::Allowed { - let msg = EmbedderMsg::Keyboard(keyboard_event.clone()); + let msg = EmbedderMsg::Keyboard(self.webview_id(), keyboard_event.clone()); self.send_to_embedder(msg); // This behavior is unspecced @@ -2455,7 +2464,7 @@ impl Document { .is_empty(); if default_prevented || return_value_not_empty { let (chan, port) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = EmbedderMsg::AllowUnload(chan); + let msg = EmbedderMsg::AllowUnload(self.webview_id(), chan); self.send_to_embedder(msg); can_unload = port.recv().unwrap(); } @@ -4049,7 +4058,7 @@ impl Document { let window = self.window(); // Step 6 if !error { - let event = EmbedderMsg::SetFullscreenState(true); + let event = EmbedderMsg::SetFullscreenState(self.webview_id(), true); self.send_to_embedder(event); } @@ -4091,7 +4100,7 @@ impl Document { let window = self.window(); // Step 8 - let event = EmbedderMsg::SetFullscreenState(false); + let event = EmbedderMsg::SetFullscreenState(self.webview_id(), false); self.send_to_embedder(event); // Step 9 diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 1d68817ace5..b75289497b8 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -554,6 +554,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource { // Step 8 // TODO: Step 9 set request's client settings let mut request = create_a_potential_cors_request( + global.webview_id(), url_record, Destination::None, Some(cors_attribute_state), diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs index d152f633c02..cd93f3421bc 100644 --- a/components/script/dom/gamepadhapticactuator.rs +++ b/components/script/dom/gamepadhapticactuator.rs @@ -235,6 +235,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato weak_magnitude: *params.weakMagnitude, }; let event = EmbedderMsg::PlayGamepadHapticEffect( + document.webview_id(), self.gamepad_index as usize, embedder_traits::GamepadHapticEffectType::DualRumble(params), effect_complete_sender, @@ -287,8 +288,11 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato }), ); - let event = - EmbedderMsg::StopGamepadHapticEffect(self.gamepad_index as usize, effect_stop_sender); + let event = EmbedderMsg::StopGamepadHapticEffect( + document.webview_id(), + self.gamepad_index as usize, + effect_stop_sender, + ); self.global().as_window().send_to_embedder(event); self.playing_effect_promise.borrow().clone().unwrap() @@ -356,7 +360,12 @@ impl GamepadHapticActuator { let (send, _rcv) = ipc::channel().expect("ipc channel failure"); - let event = EmbedderMsg::StopGamepadHapticEffect(self.gamepad_index as usize, send); + let document = self.global().as_window().Document(); + let event = EmbedderMsg::StopGamepadHapticEffect( + document.webview_id(), + self.gamepad_index as usize, + send, + ); self.global().as_window().send_to_embedder(event); } } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 62d9fee32bd..2a510c25668 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -16,7 +16,7 @@ use std::{mem, ptr}; use base::id::{ BlobId, BroadcastChannelRouterId, MessagePortId, MessagePortRouterId, PipelineId, - ServiceWorkerId, ServiceWorkerRegistrationId, + ServiceWorkerId, ServiceWorkerRegistrationId, WebViewId, }; use content_security_policy::{CheckResult, CspList, PolicyDisposition}; use crossbeam_channel::Sender; @@ -691,6 +691,20 @@ impl FileListener { } impl GlobalScope { + /// A sender to the event loop of this global scope. This either sends to the Worker event loop + /// or the ScriptThread event loop in the case of a `Window`. This can be `None` for dedicated + /// workers that are not currently handling a message. + pub(crate) fn webview_id(&self) -> Option<WebViewId> { + if let Some(window) = self.downcast::<Window>() { + Some(window.webview_id()) + } else if let Some(dedicated) = self.downcast::<DedicatedWorkerGlobalScope>() { + dedicated.webview_id() + } else { + // ServiceWorkerGlobalScope, PaintWorklet, or DissimilarOriginWindow + None + } + } + #[allow(clippy::too_many_arguments)] pub(crate) fn new_inherited( pipeline_id: PipelineId, diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index d3e540f562f..228e1490200 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -153,7 +153,7 @@ impl VirtualMethods for HTMLBodyElement { let window = self.owner_window(); window.prevent_layout_until_load_event(); if window.is_top_level() { - window.send_to_embedder(EmbedderMsg::HeadParsed); + window.send_to_embedder(EmbedderMsg::HeadParsed(window.webview_id())); } } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 36fa7b9ee67..8e563c16e54 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -10,7 +10,6 @@ use std::sync::Arc; use std::{char, mem}; use app_units::{Au, AU_PER_PX}; -use base::id::PipelineId; use cssparser::{Parser, ParserInput}; use dom_struct::dom_struct; use euclid::Point2D; @@ -23,16 +22,14 @@ use net_traits::image_cache::{ ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponder, ImageResponse, PendingImageId, UsePlaceholder, }; -use net_traits::request::{ - CorsSettings, Destination, Initiator, Referrer, RequestBuilder, RequestId, -}; +use net_traits::request::{Destination, Initiator, RequestId}; use net_traits::{ FetchMetadata, FetchResponseListener, FetchResponseMsg, NetworkError, ReferrerPolicy, ResourceFetchTiming, ResourceTimingType, }; use num_traits::ToPrimitive; use pixels::{CorsStatus, Image, ImageMetadata}; -use servo_url::origin::{ImmutableOrigin, MutableOrigin}; +use servo_url::origin::MutableOrigin; use servo_url::ServoUrl; use style::attr::{parse_integer, parse_length, AttrValue, LengthOrPercentageOrAuto}; use style::context::QuirksMode; @@ -318,34 +315,6 @@ impl PreInvoke for ImageContext { } } -#[derive(PartialEq)] -pub(crate) enum FromPictureOrSrcSet { - Yes, - No, -} - -// https://html.spec.whatwg.org/multipage/#update-the-image-data steps 17-20 -// This function is also used to prefetch an image in `script::dom::servoparser::prefetch`. -pub(crate) fn image_fetch_request( - img_url: ServoUrl, - origin: ImmutableOrigin, - referrer: Referrer, - pipeline_id: PipelineId, - cors_setting: Option<CorsSettings>, - referrer_policy: ReferrerPolicy, - from_picture_or_srcset: FromPictureOrSrcSet, -) -> RequestBuilder { - let mut request = - create_a_potential_cors_request(img_url, Destination::Image, cors_setting, None, referrer) - .origin(origin) - .pipeline_id(Some(pipeline_id)) - .referrer_policy(referrer_policy); - if from_picture_or_srcset == FromPictureOrSrcSet::Yes { - request = request.initiator(Initiator::ImageSet); - } - request -} - #[allow(non_snake_case)] impl HTMLImageElement { /// Update the current image with a valid URL. @@ -445,19 +414,23 @@ impl HTMLImageElement { url: img_url.clone(), }; - let request = image_fetch_request( + // https://html.spec.whatwg.org/multipage/#update-the-image-data steps 17-20 + // This function is also used to prefetch an image in `script::dom::servoparser::prefetch`. + let mut request = create_a_potential_cors_request( + Some(window.webview_id()), img_url.clone(), - document.origin().immutable().clone(), - document.global().get_referrer(), - document.global().pipeline_id(), + Destination::Image, cors_setting_for_element(self.upcast()), - referrer_policy_for_element(self.upcast()), - if Self::uses_srcset_or_picture(self.upcast()) { - FromPictureOrSrcSet::Yes - } else { - FromPictureOrSrcSet::No - }, - ); + None, + document.global().get_referrer(), + ) + .origin(document.origin().immutable().clone()) + .pipeline_id(Some(document.global().pipeline_id())) + .referrer_policy(referrer_policy_for_element(self.upcast())); + + if Self::uses_srcset_or_picture(self.upcast()) { + request = request.initiator(Initiator::ImageSet); + } // This is a background load because the load blocker already fulfills the // purpose of delaying the document's load event. diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index e8844084c68..e5c3270f27e 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -24,7 +24,6 @@ use net_traits::blob_url_store::get_blob_origin; use net_traits::filemanager_thread::FileManagerThreadMsg; use net_traits::{CoreResourceMsg, IpcSend}; use profile_traits::ipc; -use script_traits::ScriptToConstellationChan; use servo_atoms::Atom; use style::attr::AttrValue; use style::str::{split_commas, str_join}; @@ -34,6 +33,7 @@ use unicode_bidi::{bidi_class, BidiClass}; use url::Url; use super::bindings::str::{FromInputValueString, ToInputValueString}; +use crate::clipboard_provider::EmbedderClipboardProvider; use crate::dom::activation::Activatable; use crate::dom::attr::Attr; use crate::dom::bindings::cell::DomRefCell; @@ -299,7 +299,7 @@ pub(crate) struct HTMLInputElement { minlength: Cell<i32>, #[ignore_malloc_size_of = "TextInput contains an IPCSender which cannot be measured"] #[no_trace] - textinput: DomRefCell<TextInput<ScriptToConstellationChan>>, + textinput: DomRefCell<TextInput<EmbedderClipboardProvider>>, // https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag value_dirty: Cell<bool>, // not specified explicitly, but implied by the fact that sanitization can't @@ -334,7 +334,7 @@ impl HTMLInputElement { prefix: Option<Prefix>, document: &Document, ) -> HTMLInputElement { - let chan = document + let constellation_sender = document .window() .as_global_scope() .script_to_constellation_chan() @@ -355,7 +355,10 @@ impl HTMLInputElement { textinput: DomRefCell::new(TextInput::new( Single, DOMString::new(), - chan, + EmbedderClipboardProvider { + constellation_sender, + webview_id: document.webview_id(), + }, None, None, SelectionDirection::None, @@ -1897,6 +1900,7 @@ impl HTMLInputElement { let mut files: Vec<DomRoot<File>> = vec![]; let mut error = None; + let webview_id = window.webview_id(); let filter = filter_from_accept(&self.Accept()); let target = self.upcast::<EventTarget>(); @@ -1906,7 +1910,8 @@ impl HTMLInputElement { let (chan, recv) = ipc::channel(self.global().time_profiler_chan().clone()) .expect("Error initializing channel"); - let msg = FileManagerThreadMsg::SelectFiles(filter, chan, origin, opt_test_paths); + let msg = + FileManagerThreadMsg::SelectFiles(webview_id, filter, chan, origin, opt_test_paths); resource_threads .send(CoreResourceMsg::ToFileManager(msg)) .unwrap(); @@ -1933,7 +1938,8 @@ impl HTMLInputElement { let (chan, recv) = ipc::channel(self.global().time_profiler_chan().clone()) .expect("Error initializing channel"); - let msg = FileManagerThreadMsg::SelectFile(filter, chan, origin, opt_test_path); + let msg = + FileManagerThreadMsg::SelectFile(webview_id, filter, chan, origin, opt_test_path); resource_threads .send(CoreResourceMsg::ToFileManager(msg)) .unwrap(); diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 50d5e274c85..299be2d2156 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -6,6 +6,7 @@ use std::borrow::{Borrow, ToOwned}; use std::cell::Cell; use std::default::Default; +use base::id::WebViewId; use cssparser::{Parser as CssParser, ParserInput}; use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; @@ -366,7 +367,7 @@ impl HTMLLinkElement { // Step 4. Let request be the result of creating a link request given options. let url = options.base_url.clone(); - let Some(request) = options.create_link_request() else { + let Some(request) = options.create_link_request(self.owner_window().webview_id()) else { // Step 5. If request is null, then return. return; }; @@ -466,7 +467,7 @@ impl HTMLLinkElement { Ok(url) => { let window = document.window(); if window.is_top_level() { - let msg = EmbedderMsg::NewFavicon(url.clone()); + let msg = EmbedderMsg::NewFavicon(document.webview_id(), url.clone()); window.send_to_embedder(msg); } }, @@ -626,7 +627,7 @@ impl HTMLLinkElementMethods<crate::DomTypeHolder> for HTMLLinkElement { impl LinkProcessingOptions { /// <https://html.spec.whatwg.org/multipage/#create-a-link-request> - fn create_link_request(self) -> Option<RequestBuilder> { + fn create_link_request(self, webview_id: WebViewId) -> Option<RequestBuilder> { // Step 1. Assert: options's href is not the empty string. assert!(!self.href.is_empty()); @@ -651,6 +652,7 @@ impl LinkProcessingOptions { // FIXME: Step 11. Set request's priority to options's fetch priority. // FIXME: Use correct referrer let builder = create_a_potential_cors_request( + Some(webview_id), url, destination, self.cross_origin, diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index c7fd9462b21..b859f06007c 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -885,6 +885,7 @@ impl HTMLMediaElement { let cors_setting = cors_setting_for_element(self.upcast()); let request = create_a_potential_cors_request( + Some(document.webview_id()), url.clone(), destination, cors_setting, diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 1aaa0119760..ab00b5356f6 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -11,7 +11,7 @@ use std::ptr; use std::rc::Rc; use std::sync::{Arc, Mutex}; -use base::id::PipelineId; +use base::id::{PipelineId, WebViewId}; use content_security_policy as csp; use dom_struct::dom_struct; use encoding_rs::Encoding; @@ -542,6 +542,7 @@ impl PreInvoke for ClassicContext {} /// Steps 1-2 of <https://html.spec.whatwg.org/multipage/#fetch-a-classic-script> // This function is also used to prefetch a script in `script::dom::servoparser::prefetch`. pub(crate) fn script_fetch_request( + webview_id: WebViewId, url: ServoUrl, cors_setting: Option<CorsSettings>, origin: ImmutableOrigin, @@ -551,6 +552,7 @@ pub(crate) fn script_fetch_request( // We intentionally ignore options' credentials_mode member for classic scripts. // The mode is initialized by create_a_potential_cors_request. create_a_potential_cors_request( + Some(webview_id), url, Destination::Script, cors_setting, @@ -576,6 +578,7 @@ fn fetch_a_classic_script( // Step 1, 2. let doc = script.owner_document(); let request = script_fetch_request( + doc.webview_id(), url.clone(), cors_setting, doc.origin().immutable().clone(), diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index e660e3e4d93..c18f245eb87 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -9,10 +9,10 @@ use std::ops::Range; use dom_struct::dom_struct; use html5ever::{local_name, namespace_url, ns, LocalName, Prefix}; use js::rust::HandleObject; -use script_traits::ScriptToConstellationChan; use style::attr::AttrValue; use style_dom::ElementState; +use crate::clipboard_provider::EmbedderClipboardProvider; use crate::dom::attr::Attr; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods; @@ -52,7 +52,7 @@ pub(crate) struct HTMLTextAreaElement { htmlelement: HTMLElement, #[ignore_malloc_size_of = "TextInput contains an IPCSender which cannot be measured"] #[no_trace] - textinput: DomRefCell<TextInput<ScriptToConstellationChan>>, + textinput: DomRefCell<TextInput<EmbedderClipboardProvider>>, placeholder: DomRefCell<DOMString>, // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty value_dirty: Cell<bool>, @@ -142,7 +142,7 @@ impl HTMLTextAreaElement { prefix: Option<Prefix>, document: &Document, ) -> HTMLTextAreaElement { - let chan = document + let constellation_sender = document .window() .as_global_scope() .script_to_constellation_chan() @@ -158,7 +158,10 @@ impl HTMLTextAreaElement { textinput: DomRefCell::new(TextInput::new( Lines::Multiple, DOMString::new(), - chan, + EmbedderClipboardProvider { + constellation_sender, + webview_id: document.webview_id(), + }, None, None, SelectionDirection::None, diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index 974b50a3949..d21a317bd47 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -223,12 +223,16 @@ impl HTMLVideoElement { fn do_fetch_poster_frame(&self, poster_url: ServoUrl, id: PendingImageId, can_gc: CanGc) { // Continuation of step 4. let document = self.owner_document(); - let request = RequestBuilder::new(poster_url.clone(), document.global().get_referrer()) - .destination(Destination::Image) - .credentials_mode(CredentialsMode::Include) - .use_url_credentials(true) - .origin(document.origin().immutable().clone()) - .pipeline_id(Some(document.global().pipeline_id())); + let request = RequestBuilder::new( + Some(document.webview_id()), + poster_url.clone(), + document.global().get_referrer(), + ) + .destination(Destination::Image) + .credentials_mode(CredentialsMode::Include) + .use_url_credentials(true) + .origin(document.origin().immutable().clone()) + .pipeline_id(Some(document.global().pipeline_id())); // Step 5. // This delay must be independent from the ones created by HTMLMediaElement during diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs index 1d7c8e63698..bcdf42ac63e 100644 --- a/components/script/dom/permissions.rs +++ b/components/script/dom/permissions.rs @@ -362,8 +362,12 @@ fn allowed_in_nonsecure_contexts(permission_name: &PermissionName) -> bool { } fn prompt_user_from_embedder(prompt: PermissionPrompt, gs: &GlobalScope) -> PermissionState { + let Some(webview_id) = gs.webview_id() else { + warn!("Requesting permissions from non-webview-associated global scope"); + return PermissionState::Denied; + }; let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); - gs.send_to_embedder(EmbedderMsg::PromptPermission(prompt, sender)); + gs.send_to_embedder(EmbedderMsg::PromptPermission(webview_id, prompt, sender)); match receiver.recv() { Ok(PermissionRequest::Granted) => PermissionState::Granted, diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 6f672660db5..70fa7b212e5 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -108,7 +108,7 @@ impl Request { } fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequest { - RequestBuilder::new(url, global.get_referrer()) + RequestBuilder::new(global.webview_id(), url, global.get_referrer()) .origin(global.get_url().origin()) .pipeline_id(Some(global.pipeline_id())) .https_state(global.get_https_state()) diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index aa9184a3dc9..07c44cd11f7 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -334,7 +334,7 @@ impl ServiceWorkerGlobalScope { .map(Referrer::ReferrerUrl) .unwrap_or_else(|| global.upcast::<GlobalScope>().get_referrer()); - let request = RequestBuilder::new(script_url, referrer) + let request = RequestBuilder::new(None, script_url, referrer) .destination(Destination::ServiceWorker) .credentials_mode(CredentialsMode::Include) .parser_metadata(ParserMetadata::NotParserInserted) diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs index 5e394816f44..c67a90372dc 100644 --- a/components/script/dom/servoparser/prefetch.rs +++ b/components/script/dom/servoparser/prefetch.rs @@ -4,7 +4,8 @@ use std::cell::{Cell, RefCell}; -use base::id::PipelineId; +use base::id::{PipelineId, WebViewId}; +use content_security_policy::Destination; use html5ever::buffer_queue::BufferQueue; use html5ever::tokenizer::states::RawKind; use html5ever::tokenizer::{ @@ -19,10 +20,9 @@ use servo_url::{ImmutableOrigin, ServoUrl}; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::trace::{CustomTraceable, JSTraceable}; use crate::dom::document::{determine_policy_for_token, Document}; -use crate::dom::htmlimageelement::{image_fetch_request, FromPictureOrSrcSet}; use crate::dom::htmlscriptelement::script_fetch_request; +use crate::fetch::create_a_potential_cors_request; use crate::script_module::ScriptFetchOptions; -use crate::stylesheet_loader::stylesheet_fetch_request; #[derive(JSTraceable, MallocSizeOf)] #[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] @@ -43,6 +43,7 @@ impl Tokenizer { let sink = PrefetchSink { origin: document.origin().immutable().clone(), pipeline_id: document.global().pipeline_id(), + webview_id: document.webview_id(), base_url: RefCell::new(None), document_url: document.url(), referrer: document.global().get_referrer(), @@ -70,6 +71,8 @@ struct PrefetchSink { #[no_trace] pipeline_id: PipelineId, #[no_trace] + webview_id: WebViewId, + #[no_trace] document_url: ServoUrl, #[no_trace] base_url: RefCell<Option<ServoUrl>>, @@ -102,6 +105,7 @@ impl TokenSink for PrefetchSink { .map(|attr| String::from(&attr.value)) .unwrap_or_default(); let request = script_fetch_request( + self.webview_id, url, cors_setting, self.origin.clone(), @@ -124,15 +128,18 @@ impl TokenSink for PrefetchSink { (TagKind::StartTag, &local_name!("img")) if self.prefetching.get() => { if let Some(url) = self.get_url(tag, local_name!("src")) { debug!("Prefetch {} {}", tag.name, url); - let request = image_fetch_request( + let request = create_a_potential_cors_request( + Some(self.webview_id), url, - self.origin.clone(), - self.referrer.clone(), - self.pipeline_id, + Destination::Image, self.get_cors_settings(tag, local_name!("crossorigin")), - self.get_referrer_policy(tag, local_name!("referrerpolicy")), - FromPictureOrSrcSet::No, - ); + None, + self.referrer.clone(), + ) + .origin(self.origin.clone()) + .pipeline_id(Some(self.pipeline_id)) + .referrer_policy(self.get_referrer_policy(tag, local_name!("referrerpolicy"))); + let _ = self .resource_threads .send(CoreResourceMsg::Fetch(request, FetchChannels::Prefetch)); @@ -152,15 +159,21 @@ impl TokenSink for PrefetchSink { .get_attr(tag, local_name!("integrity")) .map(|attr| String::from(&attr.value)) .unwrap_or_default(); - let request = stylesheet_fetch_request( + + // https://html.spec.whatwg.org/multipage/#default-fetch-and-process-the-linked-resource + let request = create_a_potential_cors_request( + Some(self.webview_id), url, + Destination::Style, cors_setting, - self.origin.clone(), - self.pipeline_id, + None, self.referrer.clone(), - referrer_policy, - integrity_metadata, - ); + ) + .origin(self.origin.clone()) + .pipeline_id(Some(self.pipeline_id)) + .referrer_policy(referrer_policy) + .integrity_metadata(integrity_metadata); + let _ = self .resource_threads .send(CoreResourceMsg::Fetch(request, FetchChannels::Prefetch)); diff --git a/components/script/dom/textcontrol.rs b/components/script/dom/textcontrol.rs index 184138ab3c0..09f0365fed2 100644 --- a/components/script/dom/textcontrol.rs +++ b/components/script/dom/textcontrol.rs @@ -7,8 +7,7 @@ //! //! <https://html.spec.whatwg.org/multipage/#textFieldSelection> -use script_traits::ScriptToConstellationChan; - +use crate::clipboard_provider::EmbedderClipboardProvider; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::HTMLFormElementBinding::SelectionMode; use crate::dom::bindings::conversions::DerivedFrom; @@ -27,13 +26,13 @@ pub(crate) trait TextControlElement: DerivedFrom<EventTarget> + DerivedFrom<Node pub(crate) struct TextControlSelection<'a, E: TextControlElement> { element: &'a E, - textinput: &'a DomRefCell<TextInput<ScriptToConstellationChan>>, + textinput: &'a DomRefCell<TextInput<EmbedderClipboardProvider>>, } impl<'a, E: TextControlElement> TextControlSelection<'a, E> { pub(crate) fn new( element: &'a E, - textinput: &'a DomRefCell<TextInput<ScriptToConstellationChan>>, + textinput: &'a DomRefCell<TextInput<EmbedderClipboardProvider>>, ) -> Self { TextControlSelection { element, textinput } } diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index ab4303bf863..ad54f06d84d 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -255,7 +255,7 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket { let ws = WebSocket::new(global, proto, url_record.clone(), dom_action_sender, can_gc); let address = Trusted::new(&*ws); - let request = RequestBuilder::new(url_record, Referrer::NoReferrer) + let request = RequestBuilder::new(global.webview_id(), url_record, Referrer::NoReferrer) .origin(global.origin().immutable().clone()) .mode(RequestMode::WebSocket { protocols }); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index e8487f24b95..73ce02a40ab 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -17,7 +17,7 @@ use std::time::{Duration, Instant}; use app_units::Au; use backtrace::Backtrace; use base::cross_process_instant::CrossProcessInstant; -use base::id::{BrowsingContextId, PipelineId}; +use base::id::{BrowsingContextId, PipelineId, WebViewId}; use base64::Engine; use bluetooth_traits::BluetoothRequest; use canvas_traits::webgl::WebGLChan; @@ -209,6 +209,11 @@ impl LayoutBlocker { #[dom_struct] pub(crate) struct Window { globalscope: GlobalScope, + /// The webview that contains this [`Window`]. + /// + /// This may not be the top-level [`Window`], in the case of frames. + #[no_trace] + webview_id: WebViewId, script_chan: Sender<MainThreadScriptMsg>, #[no_trace] #[ignore_malloc_size_of = "TODO: Add MallocSizeOf support to layout"] @@ -391,6 +396,10 @@ pub(crate) struct Window { } impl Window { + pub(crate) fn webview_id(&self) -> WebViewId { + self.webview_id + } + pub(crate) fn as_global_scope(&self) -> &GlobalScope { self.upcast::<GlobalScope>() } @@ -726,7 +735,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window { let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); let prompt = PromptDefinition::Alert(s.to_string(), sender); - let msg = EmbedderMsg::Prompt(prompt, PromptOrigin::Untrusted); + let msg = EmbedderMsg::Prompt(self.webview_id(), prompt, PromptOrigin::Untrusted); self.send_to_embedder(msg); receiver.recv().unwrap(); } @@ -736,7 +745,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window { let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); let prompt = PromptDefinition::OkCancel(s.to_string(), sender); - let msg = EmbedderMsg::Prompt(prompt, PromptOrigin::Untrusted); + let msg = EmbedderMsg::Prompt(self.webview_id(), prompt, PromptOrigin::Untrusted); self.send_to_embedder(msg); receiver.recv().unwrap() == PromptResult::Primary } @@ -746,7 +755,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window { let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); let prompt = PromptDefinition::Input(message.to_string(), default.to_string(), sender); - let msg = EmbedderMsg::Prompt(prompt, PromptOrigin::Untrusted); + let msg = EmbedderMsg::Prompt(self.webview_id(), prompt, PromptOrigin::Untrusted); self.send_to_embedder(msg); receiver.recv().unwrap().map(|s| s.into()) } @@ -1322,7 +1331,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window { //TODO determine if this operation is allowed let dpr = self.device_pixel_ratio(); let size = Size2D::new(width, height).to_f32() * dpr; - self.send_to_embedder(EmbedderMsg::ResizeTo(size.to_i32())); + self.send_to_embedder(EmbedderMsg::ResizeTo(self.webview_id(), size.to_i32())); } // https://drafts.csswg.org/cssom-view/#dom-window-resizeby @@ -1341,7 +1350,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window { //TODO determine if this operation is allowed let dpr = self.device_pixel_ratio(); let point = Point2D::new(x, y).to_f32() * dpr; - let msg = EmbedderMsg::MoveTo(point.to_i32()); + let msg = EmbedderMsg::MoveTo(self.webview_id(), point.to_i32()); self.send_to_embedder(msg); } @@ -2738,6 +2747,7 @@ impl Window { #[allow(unsafe_code)] #[allow(clippy::too_many_arguments)] pub(crate) fn new( + webview_id: WebViewId, runtime: Rc<Runtime>, script_chan: Sender<MainThreadScriptMsg>, layout: Box<dyn Layout>, @@ -2786,6 +2796,7 @@ impl Window { )); let win = Box::new(Self { + webview_id, globalscope: GlobalScope::new_inherited( pipeline_id, devtools_chan, diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 5f113b5f068..f26180bfc66 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -292,7 +292,7 @@ impl WindowProxy { .and_then(ScriptThread::find_document) .map(|doc| DomRoot::from_ref(doc.window())) .unwrap(); - let msg = EmbedderMsg::AllowOpeningWebView(chan); + let msg = EmbedderMsg::AllowOpeningWebView(window.webview_id(), chan); window.send_to_embedder(msg); if let Some(new_top_level_browsing_context_id) = port.recv().unwrap() { let new_browsing_context_id = diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 7db2123e36e..94b709a4fa6 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -278,13 +278,17 @@ impl WorkerGlobalScopeMethods<crate::DomTypeHolder> for WorkerGlobalScope { rooted!(in(self.runtime.borrow().as_ref().unwrap().cx()) let mut rval = UndefinedValue()); for url in urls { let global_scope = self.upcast::<GlobalScope>(); - let request = NetRequestInit::new(url.clone(), global_scope.get_referrer()) - .destination(Destination::Script) - .credentials_mode(CredentialsMode::Include) - .parser_metadata(ParserMetadata::NotParserInserted) - .use_url_credentials(true) - .origin(global_scope.origin().immutable().clone()) - .pipeline_id(Some(self.upcast::<GlobalScope>().pipeline_id())); + let request = NetRequestInit::new( + global_scope.webview_id(), + url.clone(), + global_scope.get_referrer(), + ) + .destination(Destination::Script) + .credentials_mode(CredentialsMode::Include) + .parser_metadata(ParserMetadata::NotParserInserted) + .use_url_credentials(true) + .origin(global_scope.origin().immutable().clone()) + .pipeline_id(Some(self.upcast::<GlobalScope>().pipeline_id())); let (url, source) = match fetch::load_whole_resource( request, diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 752aa4e5e9e..527fc47f3ad 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -652,6 +652,7 @@ impl WorkletThread { // TODO: Caching. let resource_fetcher = self.global_init.resource_threads.sender(); let request = RequestBuilder::new( + None, script_url, global_scope.upcast::<GlobalScope>().get_referrer(), ) diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index e0eca131d65..5e2bb5abc27 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -673,6 +673,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest { }; let mut request = RequestBuilder::new( + self.global().webview_id(), self.request_url.borrow().clone().unwrap(), self.referrer.clone(), ) diff --git a/components/script/fetch.rs b/components/script/fetch.rs index e7236e6319f..da49d12c841 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use std::sync::{Arc, Mutex}; +use base::id::WebViewId; use ipc_channel::ipc; use net_traits::policy_container::RequestPolicyContainer; use net_traits::request::{ @@ -113,7 +114,7 @@ fn request_init_from_request(request: NetTraitsRequest) -> RequestBuilder { referrer: request.referrer.clone(), referrer_policy: request.referrer_policy, pipeline_id: request.pipeline_id, - target_browsing_context_id: request.target_browsing_context_id, + target_webview_id: request.target_webview_id, redirect_mode: request.redirect_mode, integrity_metadata: request.integrity_metadata.clone(), url_list: vec![], @@ -366,13 +367,14 @@ pub(crate) fn load_whole_resource( /// <https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request> pub(crate) fn create_a_potential_cors_request( + webview_id: Option<WebViewId>, url: ServoUrl, destination: Destination, cors_setting: Option<CorsSettings>, same_origin_fallback: Option<bool>, referrer: Referrer, ) -> RequestBuilder { - RequestBuilder::new(url, referrer) + RequestBuilder::new(webview_id, url, referrer) // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request // Step 1 .mode(match cors_setting { diff --git a/components/script/layout_image.rs b/components/script/layout_image.rs index cbfc68943ab..0696b400224 100644 --- a/components/script/layout_image.rs +++ b/components/script/layout_image.rs @@ -106,10 +106,14 @@ pub(crate) fn fetch_image_for_layout( url: url.clone(), }; - let request = FetchRequestInit::new(url, document.global().get_referrer()) - .origin(document.origin().immutable().clone()) - .destination(Destination::Image) - .pipeline_id(Some(document.global().pipeline_id())); + let request = FetchRequestInit::new( + Some(document.webview_id()), + url, + document.global().get_referrer(), + ) + .origin(document.origin().immutable().clone()) + .destination(Destination::Image) + .pipeline_id(Some(document.global().pipeline_id())); // Layout image loads do not delay the document load event. document.fetch_background(request, context); diff --git a/components/script/navigation.rs b/components/script/navigation.rs index 1ec54ad397e..0ed58ba609f 100644 --- a/components/script/navigation.rs +++ b/components/script/navigation.rs @@ -192,21 +192,23 @@ impl InProgressLoad { pub(crate) fn request_builder(&mut self) -> RequestBuilder { let id = self.pipeline_id; let top_level_browsing_context_id = self.top_level_browsing_context_id; - let mut request_builder = - RequestBuilder::new(self.load_data.url.clone(), self.load_data.referrer.clone()) - .method(self.load_data.method.clone()) - .destination(Destination::Document) - .mode(RequestMode::Navigate) - .credentials_mode(CredentialsMode::Include) - .use_url_credentials(true) - .pipeline_id(Some(id)) - .target_browsing_context_id(Some(top_level_browsing_context_id)) - .referrer_policy(self.load_data.referrer_policy) - .headers(self.load_data.headers.clone()) - .body(self.load_data.data.clone()) - .redirect_mode(RedirectMode::Manual) - .origin(self.origin.immutable().clone()) - .crash(self.load_data.crash.clone()); + let mut request_builder = RequestBuilder::new( + Some(top_level_browsing_context_id), + self.load_data.url.clone(), + self.load_data.referrer.clone(), + ) + .method(self.load_data.method.clone()) + .destination(Destination::Document) + .mode(RequestMode::Navigate) + .credentials_mode(CredentialsMode::Include) + .use_url_credentials(true) + .pipeline_id(Some(id)) + .referrer_policy(self.load_data.referrer_policy) + .headers(self.load_data.headers.clone()) + .body(self.load_data.data.clone()) + .redirect_mode(RedirectMode::Manual) + .origin(self.origin.immutable().clone()) + .crash(self.load_data.crash.clone()); request_builder.url_list = self.url_list.clone(); if !request_builder.headers.contains_key(header::ACCEPT) { diff --git a/components/script/script_module.rs b/components/script/script_module.rs index c6f18733bc1..b74dba2c65f 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -1745,9 +1745,10 @@ fn fetch_single_module_script( ModuleOwner::Worker(_) | ModuleOwner::DynamicModule(_) => None, ModuleOwner::Window(script) => Some(script.root().owner_document()), }; + let webview_id = document.as_ref().map(|document| document.webview_id()); // Step 7-8. - let request = RequestBuilder::new(url.clone(), global.get_referrer()) + let request = RequestBuilder::new(webview_id, url.clone(), global.get_referrer()) .destination(destination) .origin(global.origin().immutable().clone()) .parser_metadata(options.parser_metadata) diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 9e3b94e91af..e0c839588fb 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1052,7 +1052,7 @@ impl ScriptThread { let url = document.url(); url.join(&value).map(|url| url.to_string()).ok() }); - let event = EmbedderMsg::Status(status); + let event = EmbedderMsg::Status(window.webview_id(), status); window.send_to_embedder(event); state_already_changed = true; @@ -1069,7 +1069,7 @@ impl ScriptThread { .next() .is_some() { - let event = EmbedderMsg::Status(None); + let event = EmbedderMsg::Status(window.webview_id(), None); window.send_to_embedder(event); } } @@ -3101,9 +3101,9 @@ impl ScriptThread { let layout_config = LayoutConfig { id: incomplete.pipeline_id, + webview_id: incomplete.top_level_browsing_context_id, url: final_url.clone(), is_iframe: incomplete.parent_info.is_some(), - constellation_chan: self.senders.layout_to_constellation_ipc_sender.clone(), script_chan: self.senders.constellation_sender.clone(), image_cache: self.image_cache.clone(), font_context: font_context.clone(), @@ -3115,6 +3115,7 @@ impl ScriptThread { // Create the window and document objects. let window = Window::new( + incomplete.top_level_browsing_context_id, self.js_runtime.clone(), self.senders.self_sender.clone(), self.layout_factory.create(layout_config), diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 8f6f83390e3..2a61bb0d993 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -5,17 +5,16 @@ use std::io::{Read, Seek, Write}; use std::sync::atomic::AtomicBool; -use base::id::PipelineId; use cssparser::SourceLocation; use encoding_rs::UTF_8; use mime::{self, Mime}; -use net_traits::request::{CorsSettings, Destination, Referrer, RequestBuilder, RequestId}; +use net_traits::request::{CorsSettings, Destination, RequestId}; use net_traits::{ FetchMetadata, FetchResponseListener, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy, ResourceFetchTiming, ResourceTimingType, }; use servo_arc::Arc; -use servo_url::{ImmutableOrigin, ServoUrl}; +use servo_url::ServoUrl; use style::media_queries::MediaList; use style::parser::ParserContext; use style::shared_lock::{Locked, SharedRwLock}; @@ -343,39 +342,24 @@ impl StylesheetLoader<'_> { document.increment_script_blocking_stylesheet_count(); } - let request = stylesheet_fetch_request( + // https://html.spec.whatwg.org/multipage/#default-fetch-and-process-the-linked-resource + let request = create_a_potential_cors_request( + Some(document.webview_id()), url.clone(), + Destination::Style, cors_setting, - document.origin().immutable().clone(), - self.elem.global().pipeline_id(), + None, self.elem.global().get_referrer(), - referrer_policy, - integrity_metadata, - ); - let request = document.prepare_request(request); + ) + .origin(document.origin().immutable().clone()) + .pipeline_id(Some(self.elem.global().pipeline_id())) + .referrer_policy(referrer_policy) + .integrity_metadata(integrity_metadata); document.fetch(LoadType::Stylesheet(url), request, context); } } -// This function is also used to prefetch a stylesheet in `script::dom::servoparser::prefetch`. -// https://html.spec.whatwg.org/multipage/#default-fetch-and-process-the-linked-resource -pub(crate) fn stylesheet_fetch_request( - url: ServoUrl, - cors_setting: Option<CorsSettings>, - origin: ImmutableOrigin, - pipeline_id: PipelineId, - referrer: Referrer, - referrer_policy: ReferrerPolicy, - integrity_metadata: String, -) -> RequestBuilder { - create_a_potential_cors_request(url, Destination::Style, cors_setting, None, referrer) - .origin(origin) - .pipeline_id(Some(pipeline_id)) - .referrer_policy(referrer_policy) - .integrity_metadata(integrity_metadata) -} - impl StyleStylesheetLoader for StylesheetLoader<'_> { /// Request a stylesheet after parsing a given `@import` rule, and return /// the constructed `@import` rule. diff --git a/components/script/textinput.rs b/components/script/textinput.rs index d59cd5b6a5d..9cffd6dede1 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -10,10 +10,9 @@ use std::default::Default; use std::ops::{Add, AddAssign, Range}; use keyboard_types::{Key, KeyState, Modifiers, ShortcutMatcher}; -use script_traits::ScriptToConstellationChan; use unicode_segmentation::UnicodeSegmentation; -use crate::clipboard_provider::ClipboardProvider; +use crate::clipboard_provider::{ClipboardProvider, EmbedderClipboardProvider}; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::EventBinding::Event_Binding::EventMethods; use crate::dom::bindings::inheritance::Castable; @@ -1150,7 +1149,7 @@ impl<T: ClipboardProvider> TextInput<T> { /// <https://www.w3.org/TR/clipboard-apis/#clipboard-actions> step 3 pub(crate) fn handle_text_clipboard_action( owning_node: &impl NodeTraits, - textinput: &DomRefCell<TextInput<ScriptToConstellationChan>>, + textinput: &DomRefCell<TextInput<EmbedderClipboardProvider>>, event: &ClipboardEvent, can_gc: CanGc, ) -> bool { diff --git a/components/servo/examples/winit_minimal.rs b/components/servo/examples/winit_minimal.rs index 62114194ba9..95a4dfd9d23 100644 --- a/components/servo/examples/winit_minimal.rs +++ b/components/servo/examples/winit_minimal.rs @@ -128,7 +128,7 @@ impl ApplicationHandler<WakerEvent> for App { webviews, } = self { - for (_webview_id, message) in servo.get_events().collect::<Vec<_>>() { + for message in servo.get_events().collect::<Vec<_>>() { match message { // FIXME: rust-analyzer autocompletes this as top_level_browsing_context_id EmbedderMsg::WebViewOpened(webview_id) => { @@ -142,12 +142,12 @@ impl ApplicationHandler<WakerEvent> for App { webview.raise_to_top(true); } }, - EmbedderMsg::AllowOpeningWebView(webview_id_sender) => { + EmbedderMsg::AllowOpeningWebView(_, webview_id_sender) => { let webview = servo.new_auxiliary_webview(); let _ = webview_id_sender.send(Some(webview.id())); webviews.push(webview); }, - EmbedderMsg::AllowNavigationRequest(pipeline_id, _) => { + EmbedderMsg::AllowNavigationRequest(_, pipeline_id, _) => { servo.handle_events([EmbedderEvent::AllowNavigationResponse( pipeline_id, true, diff --git a/components/servo/lib.rs b/components/servo/lib.rs index cc0047aa817..aa64ed40f3f 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -53,7 +53,7 @@ use constellation::{ Constellation, FromCompositorLogger, FromScriptLogger, InitialConstellationState, UnprivilegedContent, }; -use crossbeam_channel::{unbounded, Sender}; +use crossbeam_channel::{unbounded, Receiver, Sender}; pub use embedder_traits::*; use env_logger::Builder as EnvLoggerBuilder; use euclid::Scale; @@ -187,8 +187,8 @@ mod media_platform { pub struct Servo { compositor: Rc<RefCell<IOCompositor>>, constellation_proxy: ConstellationProxy, - embedder_receiver: EmbedderReceiver, - messages_for_embedder: Vec<(Option<TopLevelBrowsingContextId>, EmbedderMsg)>, + embedder_receiver: Receiver<EmbedderMsg>, + messages_for_embedder: Vec<EmbedderMsg>, /// For single-process Servo instances, this field controls the initialization /// and deinitialization of the JS Engine. Multiprocess Servo instances have their /// own instance that exists in the content process instead. @@ -738,20 +738,17 @@ impl Servo { .on_pinch_zoom_window_event(zoom); }, - EmbedderEvent::Navigation(top_level_browsing_context_id, direction) => { - let msg = - ConstellationMsg::TraverseHistory(top_level_browsing_context_id, direction); + EmbedderEvent::Navigation(webview_id, direction) => { + let msg = ConstellationMsg::TraverseHistory(webview_id, direction); if let Err(e) = self.constellation_proxy.try_send(msg) { warn!("Sending navigation to constellation failed ({:?}).", e); } - self.messages_for_embedder.push(( - Some(top_level_browsing_context_id), - EmbedderMsg::Status(None), - )); + self.messages_for_embedder + .push(EmbedderMsg::Status(webview_id, None)); }, - EmbedderEvent::Keyboard(key_event) => { - let msg = ConstellationMsg::Keyboard(key_event); + EmbedderEvent::Keyboard(webview_id, key_event) => { + let msg = ConstellationMsg::Keyboard(webview_id, key_event); if let Err(e) = self.constellation_proxy.try_send(msg) { warn!("Sending keyboard event to constellation failed ({:?}).", e); } @@ -930,10 +927,8 @@ impl Servo { } fn receive_messages(&mut self) { - while let Some((top_level_browsing_context, msg)) = - self.embedder_receiver.try_recv_embedder_msg() - { - match (msg, self.compositor.borrow().shutdown_state) { + while let Ok(message) = self.embedder_receiver.try_recv() { + match (message, self.compositor.borrow().shutdown_state) { (_, ShutdownState::FinishedShuttingDown) => { error!( "embedder shouldn't be handling messages after compositor has shut down" @@ -942,20 +937,19 @@ impl Servo { (_, ShutdownState::ShuttingDown) => {}, - (EmbedderMsg::Keyboard(key_event), ShutdownState::NotShuttingDown) => { - let event = (top_level_browsing_context, EmbedderMsg::Keyboard(key_event)); - self.messages_for_embedder.push(event); + (EmbedderMsg::Keyboard(webview_id, key_event), ShutdownState::NotShuttingDown) => { + self.messages_for_embedder + .push(EmbedderMsg::Keyboard(webview_id, key_event)); }, - (msg, ShutdownState::NotShuttingDown) => { - self.messages_for_embedder - .push((top_level_browsing_context, msg)); + (message, ShutdownState::NotShuttingDown) => { + self.messages_for_embedder.push(message); }, } } } - pub fn get_events(&mut self) -> Drain<'_, (Option<TopLevelBrowsingContextId>, EmbedderMsg)> { + pub fn get_events(&mut self) -> Drain<'_, EmbedderMsg> { self.messages_for_embedder.drain(..) } @@ -971,8 +965,7 @@ impl Servo { if self.compositor.borrow().shutdown_state != ShutdownState::FinishedShuttingDown { self.compositor.borrow_mut().perform_updates(); } else { - self.messages_for_embedder - .push((None, EmbedderMsg::Shutdown)); + self.messages_for_embedder.push(EmbedderMsg::Shutdown); } need_resize } @@ -1038,14 +1031,14 @@ impl Servo { fn create_embedder_channel( event_loop_waker: Box<dyn EventLoopWaker>, -) -> (EmbedderProxy, EmbedderReceiver) { +) -> (EmbedderProxy, Receiver<EmbedderMsg>) { let (sender, receiver) = unbounded(); ( EmbedderProxy { sender, event_loop_waker, }, - EmbedderReceiver { receiver }, + receiver, ) } diff --git a/components/servo/webview.rs b/components/servo/webview.rs index 58a8ec43b07..a47ccaf04ff 100644 --- a/components/servo/webview.rs +++ b/components/servo/webview.rs @@ -202,7 +202,7 @@ impl WebView { pub fn notify_keyboard_event(&self, event: KeyboardEvent) { self.0 .constellation_proxy - .send(ConstellationMsg::Keyboard(event)) + .send(ConstellationMsg::Keyboard(self.id(), event)) } pub fn notify_ime_event(&self, event: CompositionEvent) { diff --git a/components/shared/base/id.rs b/components/shared/base/id.rs index a20e4d20889..071d7107b9c 100644 --- a/components/shared/base/id.rs +++ b/components/shared/base/id.rs @@ -443,3 +443,5 @@ pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId = BrowsingContextId { namespace_id: TEST_NAMESPACE, index: TEST_BROWSING_CONTEXT_INDEX, }; + +pub const TEST_WEBVIEW_ID: WebViewId = TopLevelBrowsingContextId(TEST_BROWSING_CONTEXT_ID); diff --git a/components/shared/bluetooth/Cargo.toml b/components/shared/bluetooth/Cargo.toml index f02f74a71d0..fed9d07891f 100644 --- a/components/shared/bluetooth/Cargo.toml +++ b/components/shared/bluetooth/Cargo.toml @@ -12,6 +12,7 @@ name = "bluetooth_traits" path = "lib.rs" [dependencies] +base = { workspace = true } embedder_traits = { workspace = true } ipc-channel = { workspace = true } regex = { workspace = true } diff --git a/components/shared/bluetooth/scanfilter.rs b/components/shared/bluetooth/scanfilter.rs index 659e34bc4dd..ba79f8f563b 100644 --- a/components/shared/bluetooth/scanfilter.rs +++ b/components/shared/bluetooth/scanfilter.rs @@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet}; use std::slice::Iter; +use base::id::WebViewId; use serde::{Deserialize, Serialize}; // A device name can never be longer than 29 bytes. An adv packet is at most @@ -114,21 +115,28 @@ impl BluetoothScanfilterSequence { #[derive(Debug, Deserialize, Serialize)] pub struct RequestDeviceoptions { + webview_id: WebViewId, filters: BluetoothScanfilterSequence, optional_services: ServiceUUIDSequence, } impl RequestDeviceoptions { pub fn new( + webview_id: WebViewId, filters: BluetoothScanfilterSequence, services: ServiceUUIDSequence, ) -> RequestDeviceoptions { RequestDeviceoptions { + webview_id, filters, optional_services: services, } } + pub fn webview_id(&self) -> WebViewId { + self.webview_id + } + pub fn get_filters(&self) -> &BluetoothScanfilterSequence { &self.filters } diff --git a/components/shared/compositing/constellation_msg.rs b/components/shared/compositing/constellation_msg.rs index 9f1d345f043..102a65dad19 100644 --- a/components/shared/compositing/constellation_msg.rs +++ b/components/shared/compositing/constellation_msg.rs @@ -35,7 +35,7 @@ pub enum ConstellationMsg { /// Query the constellation to see if the current compositor output is stable IsReadyToSaveImage(HashMap<PipelineId, Epoch>), /// Inform the constellation of a key event. - Keyboard(KeyboardEvent), + Keyboard(WebViewId, KeyboardEvent), /// Inform the constellation of a composition event (IME). IMECompositionEvent(CompositionEvent), /// Whether to allow script to navigate. @@ -73,7 +73,7 @@ pub enum ConstellationMsg { /// Forward an event to the script task of the given pipeline. ForwardEvent(PipelineId, CompositorEvent), /// Requesting a change to the onscreen cursor. - SetCursor(Cursor), + SetCursor(WebViewId, Cursor), /// Enable the sampling profiler, with a given sampling rate and max total sampling duration. ToggleProfiler(Duration, Duration), /// Request to exit from fullscreen mode diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs index b89a0516bc4..55043ae60d3 100644 --- a/components/shared/embedder/lib.rs +++ b/components/shared/embedder/lib.rs @@ -6,8 +6,8 @@ pub mod resources; use std::fmt::{Debug, Error, Formatter}; -use base::id::{PipelineId, TopLevelBrowsingContextId, WebViewId}; -use crossbeam_channel::{Receiver, Sender}; +use base::id::{PipelineId, WebViewId}; +use crossbeam_channel::Sender; use http::{HeaderMap, Method, StatusCode}; use ipc_channel::ipc::IpcSender; use keyboard_types::KeyboardEvent; @@ -77,14 +77,14 @@ impl Clone for Box<dyn EventLoopWaker> { /// Sends messages to the embedder. pub struct EmbedderProxy { - pub sender: Sender<(Option<TopLevelBrowsingContextId>, EmbedderMsg)>, + pub sender: Sender<EmbedderMsg>, pub event_loop_waker: Box<dyn EventLoopWaker>, } impl EmbedderProxy { - pub fn send(&self, msg: (Option<TopLevelBrowsingContextId>, EmbedderMsg)) { + pub fn send(&self, message: EmbedderMsg) { // Send a message and kick the OS event loop awake. - if let Err(err) = self.sender.send(msg) { + if let Err(err) = self.sender.send(message) { warn!("Failed to send response ({:?}).", err); } self.event_loop_waker.wake(); @@ -100,22 +100,6 @@ impl Clone for EmbedderProxy { } } -/// The port that the embedder receives messages on. -pub struct EmbedderReceiver { - pub receiver: Receiver<(Option<TopLevelBrowsingContextId>, EmbedderMsg)>, -} - -impl EmbedderReceiver { - pub fn try_recv_embedder_msg( - &mut self, - ) -> Option<(Option<TopLevelBrowsingContextId>, EmbedderMsg)> { - self.receiver.try_recv().ok() - } - pub fn recv_embedder_msg(&mut self) -> (Option<TopLevelBrowsingContextId>, EmbedderMsg) { - self.receiver.recv().unwrap() - } -} - #[derive(Deserialize, Serialize)] pub enum ContextMenuResult { Dismissed, @@ -167,86 +151,108 @@ pub enum PromptResult { #[derive(Deserialize, Serialize)] pub enum EmbedderMsg { /// A status message to be displayed by the browser chrome. - Status(Option<String>), + Status(WebViewId, Option<String>), /// Alerts the embedder that the current page has changed its title. - ChangePageTitle(Option<String>), + ChangePageTitle(WebViewId, Option<String>), /// Move the window to a point - MoveTo(DeviceIntPoint), + MoveTo(WebViewId, DeviceIntPoint), /// Resize the window to size - ResizeTo(DeviceIntSize), + ResizeTo(WebViewId, DeviceIntSize), /// Show dialog to user - Prompt(PromptDefinition, PromptOrigin), + Prompt(WebViewId, PromptDefinition, PromptOrigin), /// Show a context menu to the user - ShowContextMenu(IpcSender<ContextMenuResult>, Option<String>, Vec<String>), + ShowContextMenu( + WebViewId, + IpcSender<ContextMenuResult>, + Option<String>, + Vec<String>, + ), /// Whether or not to allow a pipeline to load a url. - AllowNavigationRequest(PipelineId, ServoUrl), + AllowNavigationRequest(WebViewId, PipelineId, ServoUrl), /// Whether or not to allow script to open a new tab/browser - AllowOpeningWebView(IpcSender<Option<WebViewId>>), + AllowOpeningWebView(WebViewId, IpcSender<Option<WebViewId>>), /// A webview was created. - WebViewOpened(TopLevelBrowsingContextId), + WebViewOpened(WebViewId), /// A webview was destroyed. - WebViewClosed(TopLevelBrowsingContextId), + WebViewClosed(WebViewId), /// A webview gained focus for keyboard events. - WebViewFocused(TopLevelBrowsingContextId), + WebViewFocused(WebViewId), /// All webviews lost focus for keyboard events. WebViewBlurred, /// Wether or not to unload a document - AllowUnload(IpcSender<bool>), + AllowUnload(WebViewId, IpcSender<bool>), /// Sends an unconsumed key event back to the embedder. - Keyboard(KeyboardEvent), + Keyboard(WebViewId, KeyboardEvent), /// Inform embedder to clear the clipboard - ClearClipboardContents, + ClearClipboardContents(WebViewId), /// Gets system clipboard contents - GetClipboardContents(IpcSender<String>), + GetClipboardContents(WebViewId, IpcSender<String>), /// Sets system clipboard contents - SetClipboardContents(String), + SetClipboardContents(WebViewId, String), /// Changes the cursor. - SetCursor(Cursor), + SetCursor(WebViewId, Cursor), /// A favicon was detected - NewFavicon(ServoUrl), + NewFavicon(WebViewId, ServoUrl), /// `<head>` tag finished parsing - HeadParsed, + HeadParsed(WebViewId), /// The history state has changed. - HistoryChanged(Vec<ServoUrl>, usize), + HistoryChanged(WebViewId, Vec<ServoUrl>, usize), /// Enter or exit fullscreen - SetFullscreenState(bool), + SetFullscreenState(WebViewId, bool), /// The load of a page has begun - LoadStart, + LoadStart(WebViewId), /// The load of a page has completed - LoadComplete, - WebResourceRequested(WebResourceRequest, IpcSender<WebResourceResponseMsg>), + LoadComplete(WebViewId), + WebResourceRequested( + Option<WebViewId>, + WebResourceRequest, + IpcSender<WebResourceResponseMsg>, + ), /// A pipeline panicked. First string is the reason, second one is the backtrace. - Panic(String, Option<String>), + Panic(WebViewId, String, Option<String>), /// Open dialog to select bluetooth device. - GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>), + GetSelectedBluetoothDevice(WebViewId, Vec<String>, IpcSender<Option<String>>), /// Open file dialog to select files. Set boolean flag to true allows to select multiple files. - SelectFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>), + SelectFiles( + WebViewId, + Vec<FilterPattern>, + bool, + IpcSender<Option<Vec<String>>>, + ), /// Open interface to request permission specified by prompt. - PromptPermission(PermissionPrompt, IpcSender<PermissionRequest>), + PromptPermission(WebViewId, PermissionPrompt, IpcSender<PermissionRequest>), /// Request to present an IME to the user when an editable element is focused. /// If the input is text, the second parameter defines the pre-existing string /// text content and the zero-based index into the string locating the insertion point. /// bool is true for multi-line and false otherwise. - ShowIME(InputMethodType, Option<(String, i32)>, bool, DeviceIntRect), + ShowIME( + WebViewId, + InputMethodType, + Option<(String, i32)>, + bool, + DeviceIntRect, + ), /// Request to hide the IME when the editable element is blurred. - HideIME, + HideIME(WebViewId), /// Servo has shut down Shutdown, /// Report a complete sampled profile ReportProfile(Vec<u8>), /// Notifies the embedder about media session events /// (i.e. when there is metadata for the active media session, playback state changes...). - MediaSessionEvent(MediaSessionEvent), + MediaSessionEvent(WebViewId, MediaSessionEvent), /// Report the status of Devtools Server with a token that can be used to bypass the permission prompt. OnDevtoolsStarted(Result<u16, ()>, String), + /// Ask the user to allow a devtools client to connect. + RequestDevtoolsConnection(IpcSender<bool>), /// Notify the embedder that it needs to present a new frame. ReadyToPresent(Vec<WebViewId>), /// The given event was delivered to a pipeline in the given browser. - EventDelivered(CompositorEventVariant), + EventDelivered(WebViewId, CompositorEventVariant), /// Request to play a haptic effect on a connected gamepad. - PlayGamepadHapticEffect(usize, GamepadHapticEffectType, IpcSender<bool>), + PlayGamepadHapticEffect(WebViewId, usize, GamepadHapticEffectType, IpcSender<bool>), /// Request to stop a haptic effect on a connected gamepad. - StopGamepadHapticEffect(usize, IpcSender<bool>), + StopGamepadHapticEffect(WebViewId, usize, IpcSender<bool>), } /// The variant of CompositorEvent that was delivered to a pipeline. @@ -275,23 +281,23 @@ impl Debug for EmbedderMsg { EmbedderMsg::AllowUnload(..) => write!(f, "AllowUnload"), EmbedderMsg::AllowNavigationRequest(..) => write!(f, "AllowNavigationRequest"), EmbedderMsg::Keyboard(..) => write!(f, "Keyboard"), - EmbedderMsg::ClearClipboardContents => write!(f, "ClearClipboardContents"), + EmbedderMsg::ClearClipboardContents(..) => write!(f, "ClearClipboardContents"), EmbedderMsg::GetClipboardContents(..) => write!(f, "GetClipboardContents"), EmbedderMsg::SetClipboardContents(..) => write!(f, "SetClipboardContents"), EmbedderMsg::SetCursor(..) => write!(f, "SetCursor"), EmbedderMsg::NewFavicon(..) => write!(f, "NewFavicon"), - EmbedderMsg::HeadParsed => write!(f, "HeadParsed"), + EmbedderMsg::HeadParsed(..) => write!(f, "HeadParsed"), EmbedderMsg::HistoryChanged(..) => write!(f, "HistoryChanged"), EmbedderMsg::SetFullscreenState(..) => write!(f, "SetFullscreenState"), - EmbedderMsg::LoadStart => write!(f, "LoadStart"), - EmbedderMsg::LoadComplete => write!(f, "LoadComplete"), + EmbedderMsg::LoadStart(..) => write!(f, "LoadStart"), + EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"), EmbedderMsg::WebResourceRequested(..) => write!(f, "WebResourceRequested"), EmbedderMsg::Panic(..) => write!(f, "Panic"), EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"), EmbedderMsg::SelectFiles(..) => write!(f, "SelectFiles"), EmbedderMsg::PromptPermission(..) => write!(f, "PromptPermission"), EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"), - EmbedderMsg::HideIME => write!(f, "HideIME"), + EmbedderMsg::HideIME(..) => write!(f, "HideIME"), EmbedderMsg::Shutdown => write!(f, "Shutdown"), EmbedderMsg::AllowOpeningWebView(..) => write!(f, "AllowOpeningWebView"), EmbedderMsg::WebViewOpened(..) => write!(f, "WebViewOpened"), @@ -301,6 +307,7 @@ impl Debug for EmbedderMsg { EmbedderMsg::ReportProfile(..) => write!(f, "ReportProfile"), EmbedderMsg::MediaSessionEvent(..) => write!(f, "MediaSessionEvent"), EmbedderMsg::OnDevtoolsStarted(..) => write!(f, "OnDevtoolsStarted"), + EmbedderMsg::RequestDevtoolsConnection(..) => write!(f, "RequestDevtoolsConnection"), EmbedderMsg::ShowContextMenu(..) => write!(f, "ShowContextMenu"), EmbedderMsg::ReadyToPresent(..) => write!(f, "ReadyToPresent"), EmbedderMsg::EventDelivered(..) => write!(f, "HitTestedEvent"), diff --git a/components/shared/net/filemanager_thread.rs b/components/shared/net/filemanager_thread.rs index 5167ab1b4de..71fdfe50f0a 100644 --- a/components/shared/net/filemanager_thread.rs +++ b/components/shared/net/filemanager_thread.rs @@ -7,6 +7,7 @@ use std::ops::Range; use std::path::PathBuf; use std::time::SystemTime; +use base::id::WebViewId; use embedder_traits::FilterPattern; use ipc_channel::ipc::IpcSender; use malloc_size_of_derive::MallocSizeOf; @@ -136,6 +137,7 @@ pub struct SelectedFile { pub enum FileManagerThreadMsg { /// Select a single file. Last field is pre-selected file path for testing SelectFile( + WebViewId, Vec<FilterPattern>, IpcSender<FileManagerResult<SelectedFile>>, FileOrigin, @@ -144,6 +146,7 @@ pub enum FileManagerThreadMsg { /// Select multiple files. Last field is pre-selected file paths for testing SelectFiles( + WebViewId, Vec<FilterPattern>, IpcSender<FileManagerResult<Vec<SelectedFile>>>, FileOrigin, diff --git a/components/shared/net/request.rs b/components/shared/net/request.rs index a6c31c57104..8bedd5de35a 100644 --- a/components/shared/net/request.rs +++ b/components/shared/net/request.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex}; -use base::id::{PipelineId, TopLevelBrowsingContextId}; +use base::id::{PipelineId, WebViewId}; use content_security_policy::{self as csp}; use http::header::{HeaderName, AUTHORIZATION}; use http::{HeaderMap, Method}; @@ -266,7 +266,7 @@ pub struct RequestBuilder { pub referrer: Referrer, pub referrer_policy: ReferrerPolicy, pub pipeline_id: Option<PipelineId>, - pub target_browsing_context_id: Option<TopLevelBrowsingContextId>, + pub target_webview_id: Option<WebViewId>, pub redirect_mode: RedirectMode, pub integrity_metadata: String, // to keep track of redirects @@ -280,7 +280,7 @@ pub struct RequestBuilder { } impl RequestBuilder { - pub fn new(url: ServoUrl, referrer: Referrer) -> RequestBuilder { + pub fn new(webview_id: Option<WebViewId>, url: ServoUrl, referrer: Referrer) -> RequestBuilder { RequestBuilder { id: RequestId::default(), method: Method::GET, @@ -301,7 +301,7 @@ impl RequestBuilder { referrer, referrer_policy: ReferrerPolicy::EmptyString, pipeline_id: None, - target_browsing_context_id: None, + target_webview_id: webview_id, redirect_mode: RedirectMode::Follow, integrity_metadata: "".to_owned(), url_list: vec![], @@ -383,14 +383,6 @@ impl RequestBuilder { self } - pub fn target_browsing_context_id( - mut self, - target_browsing_context_id: Option<TopLevelBrowsingContextId>, - ) -> RequestBuilder { - self.target_browsing_context_id = target_browsing_context_id; - self - } - pub fn redirect_mode(mut self, redirect_mode: RedirectMode) -> RequestBuilder { self.redirect_mode = redirect_mode; self @@ -433,6 +425,7 @@ impl RequestBuilder { Some(Origin::Origin(self.origin)), self.referrer, self.pipeline_id, + self.target_webview_id, self.https_state, ); request.initiator = self.initiator; @@ -461,7 +454,6 @@ impl RequestBuilder { request.response_tainting = self.response_tainting; request.crash = self.crash; request.policy_container = self.policy_container; - request.target_browsing_context_id = self.target_browsing_context_id; request } } @@ -488,7 +480,7 @@ pub struct Request { pub body: Option<RequestBody>, // TODO: client object pub window: Window, - pub target_browsing_context_id: Option<TopLevelBrowsingContextId>, + pub target_webview_id: Option<WebViewId>, /// <https://fetch.spec.whatwg.org/#request-keepalive-flag> pub keep_alive: bool, /// <https://fetch.spec.whatwg.org/#request-service-workers-mode> @@ -545,6 +537,7 @@ impl Request { origin: Option<Origin>, referrer: Referrer, pipeline_id: Option<PipelineId>, + webview_id: Option<WebViewId>, https_state: HttpsState, ) -> Request { Request { @@ -563,7 +556,7 @@ impl Request { referrer, referrer_policy: ReferrerPolicy::EmptyString, pipeline_id, - target_browsing_context_id: None, + target_webview_id: webview_id, synchronous: false, mode: RequestMode::NoCors, use_cors_preflight: false, diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs index 622b7b8cade..9e43a1aa29f 100644 --- a/components/shared/script/lib.rs +++ b/components/shared/script/lib.rs @@ -23,7 +23,7 @@ use background_hang_monitor_api::BackgroundHangMonitorRegister; use base::cross_process_instant::CrossProcessInstant; use base::id::{ BlobId, BrowsingContextId, HistoryStateId, MessagePortId, PipelineId, PipelineNamespaceId, - TopLevelBrowsingContextId, + TopLevelBrowsingContextId, WebViewId, }; use base::Epoch; use bitflags::bitflags; @@ -732,7 +732,11 @@ pub enum WebDriverCommandMsg { /// the provided channels to return the top level browsing context id /// associated with the new webview, and a notification when the initial /// load is complete. - NewWebView(IpcSender<TopLevelBrowsingContextId>, IpcSender<LoadStatus>), + NewWebView( + WebViewId, + IpcSender<TopLevelBrowsingContextId>, + IpcSender<LoadStatus>, + ), /// Close the webview associated with the provided id. CloseWebView(TopLevelBrowsingContextId), /// Focus the webview associated with the provided id. diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index d1b31da003f..4d57a44070f 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use app_units::Au; use atomic_refcell::AtomicRefCell; use base::cross_process_instant::CrossProcessInstant; -use base::id::{BrowsingContextId, PipelineId}; +use base::id::{BrowsingContextId, PipelineId, WebViewId}; use base::Epoch; use canvas_traits::canvas::{CanvasId, CanvasMsg}; use euclid::default::{Point2D, Rect}; @@ -33,7 +33,7 @@ use net_traits::image_cache::{ImageCache, PendingImageId}; use profile_traits::mem::Report; use profile_traits::time; use script_traits::{ - ConstellationControlMsg, InitialScriptState, LayoutMsg, LoadData, Painter, ScrollState, + ConstellationControlMsg, InitialScriptState, LoadData, Painter, ScrollState, UntrustedNodeAddress, WindowSizeData, }; use serde::{Deserialize, Serialize}; @@ -182,9 +182,9 @@ pub struct HTMLMediaData { pub struct LayoutConfig { pub id: PipelineId, + pub webview_id: WebViewId, pub url: ServoUrl, pub is_iframe: bool, - pub constellation_chan: IpcSender<LayoutMsg>, pub script_chan: IpcSender<ConstellationControlMsg>, pub image_cache: Arc<dyn ImageCache>, pub font_context: Arc<FontContext>, diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index a3eb7e48ce1..9dcec9d6b7d 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -947,7 +947,12 @@ impl Handler { ) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); - let cmd_msg = WebDriverCommandMsg::NewWebView(sender, self.load_status_sender.clone()); + let session = self.session().unwrap(); + let cmd_msg = WebDriverCommandMsg::NewWebView( + session.top_level_browsing_context_id, + sender, + self.load_status_sender.clone(), + ); self.constellation_chan .send(ConstellationMsg::WebDriverCommand(cmd_msg)) .unwrap(); diff --git a/ports/servoshell/desktop/tracing.rs b/ports/servoshell/desktop/tracing.rs index cee0752658a..243fc02f05a 100644 --- a/ports/servoshell/desktop/tracing.rs +++ b/ports/servoshell/desktop/tracing.rs @@ -143,26 +143,27 @@ mod from_servo { Self::WebResourceRequested(..) => target!("WebResourceRequested"), Self::AllowUnload(..) => target!("AllowUnload"), Self::Keyboard(..) => target!("Keyboard"), - Self::ClearClipboardContents => target!("ClearClipboardContents"), + Self::ClearClipboardContents(..) => target!("ClearClipboardContents"), Self::GetClipboardContents(..) => target!("GetClipboardContents"), Self::SetClipboardContents(..) => target!("SetClipboardContents"), Self::SetCursor(..) => target!("SetCursor"), Self::NewFavicon(..) => target!("NewFavicon"), - Self::HeadParsed => target!("HeadParsed"), + Self::HeadParsed(..) => target!("HeadParsed"), Self::HistoryChanged(..) => target!("HistoryChanged"), Self::SetFullscreenState(..) => target!("SetFullscreenState"), - Self::LoadStart => target!("LoadStart"), - Self::LoadComplete => target!("LoadComplete"), + Self::LoadStart(..) => target!("LoadStart"), + Self::LoadComplete(..) => target!("LoadComplete"), Self::Panic(..) => target!("Panic"), Self::GetSelectedBluetoothDevice(..) => target!("GetSelectedBluetoothDevice"), Self::SelectFiles(..) => target!("SelectFiles"), Self::PromptPermission(..) => target!("PromptPermission"), Self::ShowIME(..) => target!("ShowIME"), - Self::HideIME => target!("HideIME"), + Self::HideIME(..) => target!("HideIME"), Self::Shutdown => target!("Shutdown"), Self::ReportProfile(..) => target!("ReportProfile"), Self::MediaSessionEvent(..) => target!("MediaSessionEvent"), Self::OnDevtoolsStarted(..) => target!("OnDevtoolsStarted"), + Self::RequestDevtoolsConnection(..) => target!("RequestDevtoolsConnection"), Self::ReadyToPresent(..) => target!("ReadyToPresent"), Self::EventDelivered(..) => target!("EventDelivered"), Self::PlayGamepadHapticEffect(..) => target!("PlayGamepadHapticEffect"), diff --git a/ports/servoshell/desktop/webview.rs b/ports/servoshell/desktop/webview.rs index 375e1c55cd0..33326803082 100644 --- a/ports/servoshell/desktop/webview.rs +++ b/ports/servoshell/desktop/webview.rs @@ -404,8 +404,8 @@ impl WebViewManager { .position(|webview| webview.0 == focused_id) } - fn send_error(&self, webview_id: Option<WebViewId>, error: String) { - let Some(webview) = webview_id.and_then(|id| self.get(id)) else { + fn send_error(&self, webview_id: WebViewId, error: String) { + let Some(webview) = self.get(webview_id) else { return warn!("{error}"); }; webview.servo_webview.send_error(error); @@ -417,55 +417,47 @@ impl WebViewManager { servo: &mut Servo, clipboard: &mut Option<Clipboard>, opts: &Opts, - events: Vec<(Option<WebViewId>, EmbedderMsg)>, + messages: Vec<EmbedderMsg>, ) -> ServoEventResponse { let mut need_present = self.load_status() != LoadStatus::LoadComplete; let mut need_update = false; - for (webview_id, msg) in events { - if let Some(webview_id) = webview_id { - trace_embedder_msg!(msg, "{webview_id} {msg:?}"); - } else { - trace_embedder_msg!(msg, "{msg:?}"); - } + for message in messages { + trace_embedder_msg!(message, "{message:?}"); - match msg { - EmbedderMsg::Status(status) => { + match message { + EmbedderMsg::Status(_, status) => { self.status_text = status; need_update = true; }, - EmbedderMsg::ChangePageTitle(title) => { + EmbedderMsg::ChangePageTitle(webview_id, title) => { // Set the title to the target webview, and update the OS window title // if this is the currently focused one. - if let Some(webview_id) = webview_id { - if let Some(webview) = self.get_mut(webview_id) { - webview.title = title.clone(); - if webview.focused { - self.window.set_title(&format!( - "{} - Servo", - title.clone().unwrap_or_default() - )); - } - need_update = true; + if let Some(webview) = self.get_mut(webview_id) { + webview.title = title.clone(); + if webview.focused { + self.window.set_title(&format!( + "{} - Servo", + title.clone().unwrap_or_default() + )); } + need_update = true; } }, - EmbedderMsg::MoveTo(point) => { + EmbedderMsg::MoveTo(_, point) => { self.window.set_position(point); }, - EmbedderMsg::ResizeTo(inner_size) => { - if let Some(webview_id) = webview_id { - if let Some(webview) = self.get_mut(webview_id) { - if webview.rect.size() != inner_size.to_f32() { - webview.rect.set_size(inner_size.to_f32()); - webview.servo_webview.move_resize(webview.rect); - } - }; - if let Some(webview) = self.get(webview_id) { - self.window.request_resize(webview, inner_size); + EmbedderMsg::ResizeTo(webview_id, inner_size) => { + if let Some(webview) = self.get_mut(webview_id) { + if webview.rect.size() != inner_size.to_f32() { + webview.rect.set_size(inner_size.to_f32()); + webview.servo_webview.move_resize(webview.rect); } + }; + if let Some(webview) = self.get(webview_id) { + self.window.request_resize(webview, inner_size); } }, - EmbedderMsg::Prompt(definition, origin) => { + EmbedderMsg::Prompt(webview_id, definition, origin) => { let res = if opts.headless { match definition { PromptDefinition::Alert(_message, sender) => sender.send(()), @@ -553,7 +545,7 @@ impl WebViewManager { self.send_error(webview_id, format!("Failed to send Prompt response: {e}")) } }, - EmbedderMsg::AllowUnload(sender) => { + EmbedderMsg::AllowUnload(webview_id, sender) => { // Always allow unload for now. if let Err(e) = sender.send(true) { self.send_error( @@ -562,12 +554,10 @@ impl WebViewManager { ) } }, - EmbedderMsg::AllowNavigationRequest(pipeline_id, _url) => { - if let Some(_webview_id) = webview_id { - servo.allow_navigation_response(pipeline_id, true); - } + EmbedderMsg::AllowNavigationRequest(_, pipeline_id, _url) => { + servo.allow_navigation_response(pipeline_id, true); }, - EmbedderMsg::AllowOpeningWebView(response_chan) => { + EmbedderMsg::AllowOpeningWebView(_, response_chan) => { let webview = servo.new_auxiliary_webview(); match response_chan.send(Some(webview.id())) { Ok(()) => self.add(webview), @@ -614,15 +604,15 @@ impl WebViewManager { } self.focused_webview_id = None; }, - EmbedderMsg::Keyboard(key_event) => { + EmbedderMsg::Keyboard(webview_id, key_event) => { self.handle_overridable_key_bindings(webview_id, key_event); }, - EmbedderMsg::ClearClipboardContents => { + EmbedderMsg::ClearClipboardContents(_) => { clipboard .as_mut() .and_then(|clipboard| clipboard.clear().ok()); }, - EmbedderMsg::GetClipboardContents(sender) => { + EmbedderMsg::GetClipboardContents(_, sender) => { let contents = clipboard .as_mut() .and_then(|clipboard| clipboard.get_text().ok()) @@ -631,52 +621,52 @@ impl WebViewManager { warn!("Failed to send clipboard ({})", e); } }, - EmbedderMsg::SetClipboardContents(text) => { + EmbedderMsg::SetClipboardContents(_, text) => { if let Some(clipboard) = clipboard.as_mut() { if let Err(e) = clipboard.set_text(text) { warn!("Error setting clipboard contents ({})", e); } } }, - EmbedderMsg::SetCursor(cursor) => { + EmbedderMsg::SetCursor(_, cursor) => { self.window.set_cursor(cursor); }, - EmbedderMsg::NewFavicon(_url) => { + EmbedderMsg::NewFavicon(_, _url) => { // FIXME: show favicons in the UI somehow }, - EmbedderMsg::HeadParsed => { - if let Some(webview) = webview_id.and_then(|id| self.get_mut(id)) { + EmbedderMsg::HeadParsed(webview_id) => { + if let Some(webview) = self.get_mut(webview_id) { webview.load_status = LoadStatus::HeadParsed; need_update = true; }; }, - EmbedderMsg::HistoryChanged(urls, current) => { - if let Some(webview) = webview_id.and_then(|id| self.get_mut(id)) { + EmbedderMsg::HistoryChanged(webview_id, urls, current) => { + if let Some(webview) = self.get_mut(webview_id) { webview.url = Some(urls[current].clone()); need_update = true; }; }, - EmbedderMsg::SetFullscreenState(state) => { + EmbedderMsg::SetFullscreenState(_, state) => { self.window.set_fullscreen(state); }, - EmbedderMsg::LoadStart => { - if let Some(webview) = webview_id.and_then(|id| self.get_mut(id)) { + EmbedderMsg::LoadStart(webview_id) => { + if let Some(webview) = self.get_mut(webview_id) { webview.load_status = LoadStatus::LoadStart; need_update = true; }; }, - EmbedderMsg::LoadComplete => { - if let Some(webview) = webview_id.and_then(|id| self.get_mut(id)) { + EmbedderMsg::LoadComplete(webview_id) => { + if let Some(webview) = self.get_mut(webview_id) { webview.load_status = LoadStatus::LoadComplete; need_update = true; }; }, - EmbedderMsg::WebResourceRequested(_web_resource_request, _response_sender) => {}, + EmbedderMsg::WebResourceRequested(_, _web_resource_request, _response_sender) => {}, EmbedderMsg::Shutdown => { self.shutdown_requested = true; }, - EmbedderMsg::Panic(_reason, _backtrace) => {}, - EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => { + EmbedderMsg::Panic(_, _reason, _backtrace) => {}, + EmbedderMsg::GetSelectedBluetoothDevice(webview_id, devices, sender) => { let selected = platform_get_selected_devices(devices); if let Err(e) = sender.send(selected) { self.send_error( @@ -685,7 +675,7 @@ impl WebViewManager { ); }; }, - EmbedderMsg::SelectFiles(patterns, multiple_files, sender) => { + EmbedderMsg::SelectFiles(webview_id, patterns, multiple_files, sender) => { let result = match (opts.headless, get_selected_files(patterns, multiple_files)) { (true, _) | (false, None) => sender.send(None), @@ -698,16 +688,16 @@ impl WebViewManager { ); }; }, - EmbedderMsg::PromptPermission(prompt, sender) => { + EmbedderMsg::PromptPermission(_, prompt, sender) => { let _ = sender.send(match opts.headless { true => PermissionRequest::Denied, false => prompt_user(prompt), }); }, - EmbedderMsg::ShowIME(_kind, _text, _multiline, _rect) => { + EmbedderMsg::ShowIME(_webview_id, _kind, _text, _multiline, _rect) => { debug!("ShowIME received"); }, - EmbedderMsg::HideIME => { + EmbedderMsg::HideIME(_webview_id) => { debug!("HideIME received"); }, EmbedderMsg::ReportProfile(bytes) => { @@ -717,7 +707,7 @@ impl WebViewManager { error!("Failed to store profile: {}", e); } }, - EmbedderMsg::MediaSessionEvent(_) => { + EmbedderMsg::MediaSessionEvent(..) => { debug!("MediaSessionEvent received"); // TODO(ferjm): MediaSession support for winit based browsers. }, @@ -725,28 +715,31 @@ impl WebViewManager { Ok(p) => info!("Devtools Server running on port {}", p), Err(()) => error!("Error running devtools server"), }, - EmbedderMsg::ShowContextMenu(sender, ..) => { + EmbedderMsg::RequestDevtoolsConnection(response_sender) => { + let _ = response_sender.send(true); + }, + EmbedderMsg::ShowContextMenu(_, sender, ..) => { let _ = sender.send(ContextMenuResult::Ignored); }, EmbedderMsg::ReadyToPresent(_webview_ids) => { need_present = true; }, - EmbedderMsg::EventDelivered(event) => { - if let Some(webview) = webview_id.and_then(|id| self.get_mut(id)) { + EmbedderMsg::EventDelivered(webview_id, event) => { + if let Some(webview) = self.get_mut(webview_id) { if let CompositorEventVariant::MouseButtonEvent = event { webview.servo_webview.raise_to_top(true); webview.servo_webview.focus(); } }; }, - EmbedderMsg::PlayGamepadHapticEffect(index, effect, effect_complete_sender) => { + EmbedderMsg::PlayGamepadHapticEffect(_, index, effect, effect_complete_sender) => { match effect { GamepadHapticEffectType::DualRumble(params) => { self.play_haptic_effect(index, params, effect_complete_sender); }, } }, - EmbedderMsg::StopGamepadHapticEffect(index, haptic_stop_sender) => { + EmbedderMsg::StopGamepadHapticEffect(_, index, haptic_stop_sender) => { let stopped_successfully = self.stop_haptic_effect(index); haptic_stop_sender .send(stopped_successfully) @@ -762,12 +755,8 @@ impl WebViewManager { } /// Handle servoshell key bindings that may have been prevented by the page in the focused webview. - fn handle_overridable_key_bindings( - &mut self, - webview_id: Option<WebViewId>, - event: KeyboardEvent, - ) { - let Some(webview) = webview_id.and_then(|id| self.get(id)) else { + fn handle_overridable_key_bindings(&mut self, webview_id: WebViewId, event: KeyboardEvent) { + let Some(webview) = self.get(webview_id) else { return; }; diff --git a/ports/servoshell/egl/servo_glue.rs b/ports/servoshell/egl/servo_glue.rs index f485ed56b9c..8bb38e5fc3d 100644 --- a/ports/servoshell/egl/servo_glue.rs +++ b/ports/servoshell/egl/servo_glue.rs @@ -455,23 +455,21 @@ impl ServoGlue { fn handle_servo_events(&mut self) -> Result<(), &'static str> { let mut need_update = false; - let events: Vec<_> = self.servo.get_events().collect(); - for (browser_id, event) in events { - match event { - EmbedderMsg::ChangePageTitle(title) => { + let messages: Vec<_> = self.servo.get_events().collect(); + for message in messages { + match message { + EmbedderMsg::ChangePageTitle(_, title) => { self.callbacks.host_callbacks.on_title_changed(title); }, - EmbedderMsg::AllowNavigationRequest(pipeline_id, url) => { - if let Some(_browser_id) = browser_id { - let data: bool = self - .callbacks - .host_callbacks - .on_allow_navigation(url.to_string()); - self.servo.allow_navigation_response(pipeline_id, data); - need_update = true; - } + EmbedderMsg::AllowNavigationRequest(_, pipeline_id, url) => { + let data: bool = self + .callbacks + .host_callbacks + .on_allow_navigation(url.to_string()); + self.servo.allow_navigation_response(pipeline_id, data); + need_update = true; }, - EmbedderMsg::HistoryChanged(entries, current) => { + EmbedderMsg::HistoryChanged(_, entries, current) => { let can_go_back = current > 0; let can_go_forward = current < entries.len() - 1; self.callbacks @@ -481,19 +479,19 @@ impl ServoGlue { .host_callbacks .on_url_changed(entries[current].clone().to_string()); }, - EmbedderMsg::LoadStart => { + EmbedderMsg::LoadStart(_) => { self.callbacks.host_callbacks.on_load_started(); }, - EmbedderMsg::LoadComplete => { + EmbedderMsg::LoadComplete(_) => { self.callbacks.host_callbacks.on_load_ended(); }, - EmbedderMsg::GetSelectedBluetoothDevice(_, sender) => { + EmbedderMsg::GetSelectedBluetoothDevice(_, _, sender) => { let _ = sender.send(None); }, - EmbedderMsg::AllowUnload(sender) => { + EmbedderMsg::AllowUnload(_, sender) => { let _ = sender.send(true); }, - EmbedderMsg::ShowContextMenu(sender, title, items) => { + EmbedderMsg::ShowContextMenu(_, sender, title, items) => { if self.context_menu_sender.is_some() { warn!( "Trying to show a context menu when a context menu is already active" @@ -506,7 +504,7 @@ impl ServoGlue { .show_context_menu(title, items); } }, - EmbedderMsg::Prompt(definition, origin) => { + EmbedderMsg::Prompt(_, definition, origin) => { let cb = &self.callbacks.host_callbacks; let trusted = origin == PromptOrigin::Trusted; let res = match definition { @@ -533,7 +531,7 @@ impl ServoGlue { .send_error(format!("Failed to send Prompt response: {e}")); } }, - EmbedderMsg::AllowOpeningWebView(response_chan) => { + EmbedderMsg::AllowOpeningWebView(_, response_chan) => { let new_webview = self.servo.new_auxiliary_webview(); let new_webview_id = new_webview.id(); self.webviews.insert(new_webview_id, new_webview); @@ -568,17 +566,17 @@ impl ServoGlue { EmbedderMsg::WebViewBlurred => { self.focused_webview_id = None; }, - EmbedderMsg::GetClipboardContents(sender) => { + EmbedderMsg::GetClipboardContents(_, sender) => { let contents = self.callbacks.host_callbacks.get_clipboard_contents(); let _ = sender.send(contents.unwrap_or("".to_owned())); }, - EmbedderMsg::SetClipboardContents(text) => { + EmbedderMsg::SetClipboardContents(_, text) => { self.callbacks.host_callbacks.set_clipboard_contents(text); }, EmbedderMsg::Shutdown => { self.callbacks.host_callbacks.on_shutdown_complete(); }, - EmbedderMsg::PromptPermission(prompt, sender) => { + EmbedderMsg::PromptPermission(_, prompt, sender) => { let message = match prompt { PermissionPrompt::Request(permission_name) => { format!("Do you want to grant permission for {:?}?", permission_name) @@ -601,15 +599,15 @@ impl ServoGlue { let _ = sender.send(result); }, - EmbedderMsg::ShowIME(kind, text, multiline, bounds) => { + EmbedderMsg::ShowIME(_, kind, text, multiline, bounds) => { self.callbacks .host_callbacks .on_ime_show(kind, text, multiline, bounds); }, - EmbedderMsg::HideIME => { + EmbedderMsg::HideIME(_) => { self.callbacks.host_callbacks.on_ime_hide(); }, - EmbedderMsg::MediaSessionEvent(event) => { + EmbedderMsg::MediaSessionEvent(_, event) => { match event { MediaSessionEvent::SetMetadata(metadata) => { self.callbacks.host_callbacks.on_media_session_metadata( @@ -637,30 +635,31 @@ impl ServoGlue { .host_callbacks .on_devtools_started(port, token); }, - EmbedderMsg::Panic(reason, backtrace) => { + EmbedderMsg::RequestDevtoolsConnection(result_sender) => { + result_sender.send(true); + }, + EmbedderMsg::Panic(_, reason, backtrace) => { self.callbacks.host_callbacks.on_panic(reason, backtrace); }, EmbedderMsg::ReadyToPresent(_webview_ids) => { self.need_present = true; }, - EmbedderMsg::Keyboard(..) => { - error!("Received unexpected keyboard event"); - }, - EmbedderMsg::ResizeTo(size) => { - error!("Received resize event (to {size:?}). Currently only the user can resize windows"); + EmbedderMsg::ResizeTo(_, size) => { + warn!("Received resize event (to {size:?}). Currently only the user can resize windows"); }, + EmbedderMsg::Keyboard(..) | EmbedderMsg::Status(..) | EmbedderMsg::SelectFiles(..) | EmbedderMsg::MoveTo(..) | EmbedderMsg::SetCursor(..) | EmbedderMsg::NewFavicon(..) | - EmbedderMsg::HeadParsed | + EmbedderMsg::HeadParsed(..) | EmbedderMsg::SetFullscreenState(..) | EmbedderMsg::ReportProfile(..) | EmbedderMsg::EventDelivered(..) | EmbedderMsg::PlayGamepadHapticEffect(..) | EmbedderMsg::StopGamepadHapticEffect(..) | - EmbedderMsg::ClearClipboardContents | + EmbedderMsg::ClearClipboardContents(..) | EmbedderMsg::WebResourceRequested(..) => {}, } } |