diff options
Diffstat (limited to 'components/shared')
-rw-r--r-- | components/shared/constellation/from_script_message.rs | 9 | ||||
-rw-r--r-- | components/shared/constellation/lib.rs | 7 | ||||
-rw-r--r-- | components/shared/embedder/lib.rs | 64 | ||||
-rw-r--r-- | components/shared/script/lib.rs | 7 |
4 files changed, 81 insertions, 6 deletions
diff --git a/components/shared/constellation/from_script_message.rs b/components/shared/constellation/from_script_message.rs index 21665c24e57..3856def660e 100644 --- a/components/shared/constellation/from_script_message.rs +++ b/components/shared/constellation/from_script_message.rs @@ -15,8 +15,8 @@ use base::id::{ use canvas_traits::canvas::{CanvasId, CanvasMsg}; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId}; use embedder_traits::{ - AnimationState, EmbedderMsg, FocusSequenceNumber, MediaSessionEvent, TouchEventResult, - ViewportDetails, + AnimationState, EmbedderMsg, FocusSequenceNumber, JSValue, JavaScriptEvaluationError, + JavaScriptEvaluationId, MediaSessionEvent, TouchEventResult, ViewportDetails, }; use euclid::default::Size2D as UntypedSize2D; use http::{HeaderMap, Method}; @@ -644,6 +644,11 @@ pub enum ScriptToConstellationMessage { IFrameSizes(Vec<IFrameSizeMsg>), /// Request results from the memory reporter. ReportMemory(IpcSender<MemoryReportResult>), + /// Return the result of the evaluated JavaScript with the given [`JavaScriptEvaluationId`]. + FinishJavaScriptEvaluation( + JavaScriptEvaluationId, + Result<JSValue, JavaScriptEvaluationError>, + ), } impl fmt::Debug for ScriptToConstellationMessage { diff --git a/components/shared/constellation/lib.rs b/components/shared/constellation/lib.rs index 134eed6c1d9..d85fbe31bdf 100644 --- a/components/shared/constellation/lib.rs +++ b/components/shared/constellation/lib.rs @@ -19,8 +19,8 @@ use base::Epoch; use base::cross_process_instant::CrossProcessInstant; use base::id::{MessagePortId, PipelineId, WebViewId}; use embedder_traits::{ - CompositorHitTestResult, Cursor, InputEvent, MediaSessionActionType, Theme, ViewportDetails, - WebDriverCommandMsg, + CompositorHitTestResult, Cursor, InputEvent, JavaScriptEvaluationId, MediaSessionActionType, + Theme, ViewportDetails, WebDriverCommandMsg, }; use euclid::Vector2D; pub use from_script_message::*; @@ -92,6 +92,9 @@ pub enum EmbedderToConstellationMessage { SetScrollStates(PipelineId, Vec<ScrollState>), /// Notify the constellation that a particular paint metric event has happened for the given pipeline. PaintMetric(PipelineId, PaintMetricEvent), + /// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an + /// error is encountered, a correpsonding message will be sent to the embedding layer. + EvaluateJavaScript(WebViewId, JavaScriptEvaluationId, String), } /// A description of a paint metric that is sent from the Servo renderer to the diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs index c87fa9019ef..e9427fcc719 100644 --- a/components/shared/embedder/lib.rs +++ b/components/shared/embedder/lib.rs @@ -13,8 +13,10 @@ pub mod resources; pub mod user_content_manager; mod webdriver; +use std::collections::HashMap; use std::ffi::c_void; use std::fmt::{Debug, Display, Error, Formatter}; +use std::hash::Hash; use std::path::PathBuf; use std::sync::Arc; @@ -372,6 +374,12 @@ pub enum EmbedderMsg { DeviceIntRect, IpcSender<Option<usize>>, ), + /// Inform the embedding layer that a JavaScript evaluation has + /// finished with the given result. + FinishJavaScriptEvaluation( + JavaScriptEvaluationId, + Result<JSValue, JavaScriptEvaluationError>, + ), } impl Debug for EmbedderMsg { @@ -857,3 +865,59 @@ impl Display for FocusSequenceNumber { Display::fmt(&self.0, f) } } + +/// An identifier for a particular JavaScript evaluation that is used to track the +/// evaluation from the embedding layer to the script layer and then back. +#[derive(Clone, Copy, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct JavaScriptEvaluationId(pub usize); + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub enum JSValue { + Undefined, + Null, + Boolean(bool), + Number(f64), + String(String), + Element(String), + Frame(String), + Window(String), + Array(Vec<JSValue>), + Object(HashMap<String, JSValue>), +} + +impl From<&WebDriverJSValue> for JSValue { + fn from(value: &WebDriverJSValue) -> Self { + match value { + WebDriverJSValue::Undefined => Self::Undefined, + WebDriverJSValue::Null => Self::Null, + WebDriverJSValue::Boolean(value) => Self::Boolean(*value), + WebDriverJSValue::Int(value) => Self::Number(*value as f64), + WebDriverJSValue::Number(value) => Self::Number(*value), + WebDriverJSValue::String(value) => Self::String(value.clone()), + WebDriverJSValue::Element(web_element) => Self::Element(web_element.0.clone()), + WebDriverJSValue::Frame(web_frame) => Self::Frame(web_frame.0.clone()), + WebDriverJSValue::Window(web_window) => Self::Window(web_window.0.clone()), + WebDriverJSValue::ArrayLike(vector) => { + Self::Array(vector.iter().map(Into::into).collect()) + }, + WebDriverJSValue::Object(map) => Self::Object( + map.iter() + .map(|(key, value)| (key.clone(), value.into())) + .collect(), + ), + } + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub enum JavaScriptEvaluationError { + /// An internal Servo error prevented the JavaSript evaluation from completing properly. + /// This indicates a bug in Servo. + InternalError, + /// The `WebView` on which this evaluation request was triggered is not ready. This might + /// happen if the `WebView`'s `Document` is changing due to ongoing load events, for instance. + WebViewNotReady, + /// The script executed successfully, but Servo could not serialize the JavaScript return + /// value into a [`JSValue`]. + SerializationError, +} diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs index 748c42400a8..29acc51765c 100644 --- a/components/shared/script/lib.rs +++ b/components/shared/script/lib.rs @@ -27,8 +27,8 @@ use crossbeam_channel::{RecvTimeoutError, Sender}; use devtools_traits::ScriptToDevtoolsControlMsg; use embedder_traits::user_content_manager::UserContentManager; use embedder_traits::{ - CompositorHitTestResult, FocusSequenceNumber, InputEvent, MediaSessionActionType, Theme, - ViewportDetails, WebDriverScriptCommand, + CompositorHitTestResult, FocusSequenceNumber, InputEvent, JavaScriptEvaluationId, + MediaSessionActionType, Theme, ViewportDetails, WebDriverScriptCommand, }; use euclid::{Rect, Scale, Size2D, UnknownUnit}; use ipc_channel::ipc::{IpcReceiver, IpcSender}; @@ -245,6 +245,9 @@ pub enum ScriptThreadMessage { /// The compositor scrolled and is updating the scroll states of the nodes in the given /// pipeline via the Constellation. SetScrollStates(PipelineId, Vec<ScrollState>), + /// Evaluate the given JavaScript and return a result via a corresponding message + /// to the Constellation. + EvaluateJavaScript(PipelineId, JavaScriptEvaluationId, String), } impl fmt::Debug for ScriptThreadMessage { |