constellation_traits/
from_script_message.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Messages send from the ScriptThread to the Constellation.
6
7use std::collections::HashMap;
8use std::fmt;
9
10use base::Epoch;
11use base::generic_channel::{GenericSender, SendResult};
12use base::id::{
13    BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId,
14    MessagePortRouterId, PipelineId, ServiceWorkerId, ServiceWorkerRegistrationId, WebViewId,
15};
16use canvas_traits::canvas::{CanvasId, CanvasMsg};
17use compositing_traits::CrossProcessCompositorApi;
18use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
19use embedder_traits::{
20    AnimationState, EmbedderMsg, FocusSequenceNumber, JSValue, JavaScriptEvaluationError,
21    JavaScriptEvaluationId, MediaSessionEvent, Theme, TouchEventResult, ViewportDetails,
22    WebDriverMessageId,
23};
24use euclid::default::Size2D as UntypedSize2D;
25use fonts_traits::SystemFontServiceProxySender;
26use http::{HeaderMap, Method};
27use ipc_channel::ipc::{IpcReceiver, IpcSender};
28use malloc_size_of_derive::MallocSizeOf;
29use net_traits::policy_container::PolicyContainer;
30use net_traits::request::{Destination, InsecureRequestsPolicy, Referrer, RequestBody};
31use net_traits::storage_thread::StorageType;
32use net_traits::{ReferrerPolicy, ResourceThreads};
33use profile_traits::mem::MemoryReportResult;
34use profile_traits::{mem, time as profile_time};
35use serde::{Deserialize, Serialize};
36use servo_url::{ImmutableOrigin, ServoUrl};
37use strum_macros::IntoStaticStr;
38#[cfg(feature = "webgpu")]
39use webgpu_traits::{WebGPU, WebGPUAdapterResponse};
40use webrender_api::ImageKey;
41
42use crate::structured_data::{BroadcastChannelMsg, StructuredSerializedData};
43use crate::{
44    LogEntry, MessagePortMsg, PortMessageTask, PortTransferInfo, TraversalDirection, WindowSizeType,
45};
46
47/// A Script to Constellation channel.
48#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
49pub struct ScriptToConstellationChan {
50    /// Sender for communicating with constellation thread.
51    pub sender: GenericSender<(PipelineId, ScriptToConstellationMessage)>,
52    /// Used to identify the origin of the message.
53    pub pipeline_id: PipelineId,
54}
55
56impl ScriptToConstellationChan {
57    /// Send ScriptMsg and attach the pipeline_id to the message.
58    pub fn send(&self, msg: ScriptToConstellationMessage) -> SendResult {
59        self.sender.send((self.pipeline_id, msg))
60    }
61}
62
63/// The origin where a given load was initiated.
64/// Useful for origin checks, for example before evaluation a JS URL.
65#[derive(Clone, Debug, Deserialize, Serialize)]
66pub enum LoadOrigin {
67    /// A load originating in the constellation.
68    Constellation,
69    /// A load originating in webdriver.
70    WebDriver,
71    /// A load originating in script.
72    Script(ImmutableOrigin),
73}
74
75/// can be passed to `LoadUrl` to load a page with GET/POST
76/// parameters or headers
77#[derive(Clone, Debug, Deserialize, Serialize)]
78pub struct LoadData {
79    /// The origin where the load started.
80    pub load_origin: LoadOrigin,
81    /// The URL.
82    pub url: ServoUrl,
83    /// The creator pipeline id if this is an about:blank load.
84    pub creator_pipeline_id: Option<PipelineId>,
85    /// The method.
86    #[serde(
87        deserialize_with = "::hyper_serde::deserialize",
88        serialize_with = "::hyper_serde::serialize"
89    )]
90    pub method: Method,
91    /// The headers.
92    #[serde(
93        deserialize_with = "::hyper_serde::deserialize",
94        serialize_with = "::hyper_serde::serialize"
95    )]
96    pub headers: HeaderMap,
97    /// The data that will be used as the body of the request.
98    pub data: Option<RequestBody>,
99    /// The result of evaluating a javascript scheme url.
100    pub js_eval_result: Option<JsEvalResult>,
101    /// The referrer.
102    pub referrer: Referrer,
103    /// The referrer policy.
104    pub referrer_policy: ReferrerPolicy,
105    /// The policy container.
106    pub policy_container: Option<PolicyContainer>,
107
108    /// The source to use instead of a network response for a srcdoc document.
109    pub srcdoc: String,
110    /// The inherited context is Secure, None if not inherited
111    pub inherited_secure_context: Option<bool>,
112    /// The inherited policy for upgrading insecure requests; None if not inherited.
113    pub inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
114    /// Whether the page's ancestors have potentially trustworthy origin
115    pub has_trustworthy_ancestor_origin: bool,
116    /// Servo internal: if crash details are present, trigger a crash error page with these details.
117    pub crash: Option<String>,
118    /// Destination, used for CSP checks
119    pub destination: Destination,
120}
121
122/// The result of evaluating a javascript scheme url.
123#[derive(Clone, Debug, Deserialize, Serialize)]
124pub enum JsEvalResult {
125    /// The js evaluation had a non-string result, 204 status code.
126    /// <https://html.spec.whatwg.org/multipage/#navigate> 12.11
127    NoContent,
128    /// The js evaluation had a string result.
129    Ok(Vec<u8>),
130}
131
132impl LoadData {
133    /// Create a new `LoadData` object.
134    #[allow(clippy::too_many_arguments)]
135    pub fn new(
136        load_origin: LoadOrigin,
137        url: ServoUrl,
138        creator_pipeline_id: Option<PipelineId>,
139        referrer: Referrer,
140        referrer_policy: ReferrerPolicy,
141        inherited_secure_context: Option<bool>,
142        inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
143        has_trustworthy_ancestor_origin: bool,
144    ) -> LoadData {
145        LoadData {
146            load_origin,
147            url,
148            creator_pipeline_id,
149            method: Method::GET,
150            headers: HeaderMap::new(),
151            data: None,
152            js_eval_result: None,
153            referrer,
154            referrer_policy,
155            policy_container: None,
156            srcdoc: "".to_string(),
157            inherited_secure_context,
158            crash: None,
159            inherited_insecure_requests_policy,
160            has_trustworthy_ancestor_origin,
161            destination: Destination::Document,
162        }
163    }
164}
165
166/// <https://html.spec.whatwg.org/multipage/#navigation-supporting-concepts:navigationhistorybehavior>
167#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
168pub enum NavigationHistoryBehavior {
169    /// The default value, which will be converted very early in the navigate algorithm into "push"
170    /// or "replace". Usually it becomes "push", but under certain circumstances it becomes
171    /// "replace" instead.
172    #[default]
173    Auto,
174    /// A regular navigation which adds a new session history entry, and will clear the forward
175    /// session history.
176    Push,
177    /// A navigation that will replace the active session history entry.
178    Replace,
179}
180
181/// Entities required to spawn service workers
182#[derive(Clone, Debug, Deserialize, Serialize)]
183pub struct ScopeThings {
184    /// script resource url
185    pub script_url: ServoUrl,
186    /// network load origin of the resource
187    pub worker_load_origin: WorkerScriptLoadOrigin,
188    /// base resources required to create worker global scopes
189    pub init: WorkerGlobalScopeInit,
190    /// the port to receive devtools message from
191    pub devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
192    /// service worker id
193    pub worker_id: WorkerId,
194}
195
196/// Message that gets passed to service worker scope on postMessage
197#[derive(Debug, Deserialize, Serialize)]
198pub struct DOMMessage {
199    /// The origin of the message
200    pub origin: ImmutableOrigin,
201    /// The payload of the message
202    pub data: StructuredSerializedData,
203}
204
205/// Channels to allow service worker manager to communicate with constellation and resource thread
206#[derive(Deserialize, Serialize)]
207pub struct SWManagerSenders {
208    /// Sender of messages to the constellation.
209    pub swmanager_sender: IpcSender<SWManagerMsg>,
210    /// [`ResourceThreads`] for initating fetches or using i/o.
211    pub resource_threads: ResourceThreads,
212    /// [`CrossProcessCompositorApi`] for communicating with the compositor.
213    pub compositor_api: CrossProcessCompositorApi,
214    /// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
215    pub system_font_service_sender: SystemFontServiceProxySender,
216    /// Sender of messages to the manager.
217    pub own_sender: IpcSender<ServiceWorkerMsg>,
218    /// Receiver of messages from the constellation.
219    pub receiver: IpcReceiver<ServiceWorkerMsg>,
220}
221
222/// Messages sent to Service Worker Manager thread
223#[derive(Debug, Deserialize, Serialize)]
224#[allow(clippy::large_enum_variant)]
225pub enum ServiceWorkerMsg {
226    /// Timeout message sent by active service workers
227    Timeout(ServoUrl),
228    /// Message sent by constellation to forward to a running service worker
229    ForwardDOMMessage(DOMMessage, ServoUrl),
230    /// <https://w3c.github.io/ServiceWorker/#schedule-job-algorithm>
231    ScheduleJob(Job),
232    /// Exit the service worker manager
233    Exit,
234}
235
236#[derive(Debug, Deserialize, PartialEq, Serialize)]
237/// <https://w3c.github.io/ServiceWorker/#dfn-job-type>
238pub enum JobType {
239    /// <https://w3c.github.io/ServiceWorker/#register>
240    Register,
241    /// <https://w3c.github.io/ServiceWorker/#unregister-algorithm>
242    Unregister,
243    /// <https://w3c.github.io/ServiceWorker/#update-algorithm>
244    Update,
245}
246
247#[derive(Debug, Deserialize, Serialize)]
248/// The kind of error the job promise should be rejected with.
249pub enum JobError {
250    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise>
251    TypeError,
252    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise>
253    SecurityError,
254}
255
256#[derive(Debug, Deserialize, Serialize)]
257#[allow(clippy::large_enum_variant)]
258/// Messages sent from Job algorithms steps running in the SW manager,
259/// in order to resolve or reject the job promise.
260pub enum JobResult {
261    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise>
262    RejectPromise(JobError),
263    /// <https://w3c.github.io/ServiceWorker/#resolve-job-promise>
264    ResolvePromise(Job, JobResultValue),
265}
266
267#[derive(Debug, Deserialize, Serialize)]
268/// Jobs are resolved with the help of various values.
269pub enum JobResultValue {
270    /// Data representing a serviceworker registration.
271    Registration {
272        /// The Id of the registration.
273        id: ServiceWorkerRegistrationId,
274        /// The installing worker, if any.
275        installing_worker: Option<ServiceWorkerId>,
276        /// The waiting worker, if any.
277        waiting_worker: Option<ServiceWorkerId>,
278        /// The active worker, if any.
279        active_worker: Option<ServiceWorkerId>,
280    },
281}
282
283#[derive(Debug, Deserialize, Serialize)]
284/// <https://w3c.github.io/ServiceWorker/#dfn-job>
285pub struct Job {
286    /// <https://w3c.github.io/ServiceWorker/#dfn-job-type>
287    pub job_type: JobType,
288    /// <https://w3c.github.io/ServiceWorker/#dfn-job-scope-url>
289    pub scope_url: ServoUrl,
290    /// <https://w3c.github.io/ServiceWorker/#dfn-job-script-url>
291    pub script_url: ServoUrl,
292    /// <https://w3c.github.io/ServiceWorker/#dfn-job-client>
293    pub client: IpcSender<JobResult>,
294    /// <https://w3c.github.io/ServiceWorker/#job-referrer>
295    pub referrer: ServoUrl,
296    /// Various data needed to process job.
297    pub scope_things: Option<ScopeThings>,
298}
299
300impl Job {
301    /// <https://w3c.github.io/ServiceWorker/#create-job-algorithm>
302    pub fn create_job(
303        job_type: JobType,
304        scope_url: ServoUrl,
305        script_url: ServoUrl,
306        client: IpcSender<JobResult>,
307        referrer: ServoUrl,
308        scope_things: Option<ScopeThings>,
309    ) -> Job {
310        Job {
311            job_type,
312            scope_url,
313            script_url,
314            client,
315            referrer,
316            scope_things,
317        }
318    }
319}
320
321impl PartialEq for Job {
322    /// Equality criteria as described in <https://w3c.github.io/ServiceWorker/#dfn-job-equivalent>
323    fn eq(&self, other: &Self) -> bool {
324        // TODO: match on job type, take worker type and `update_via_cache_mode` into account.
325        let same_job = self.job_type == other.job_type;
326        if same_job {
327            match self.job_type {
328                JobType::Register | JobType::Update => {
329                    self.scope_url == other.scope_url && self.script_url == other.script_url
330                },
331                JobType::Unregister => self.scope_url == other.scope_url,
332            }
333        } else {
334            false
335        }
336    }
337}
338
339/// Messages outgoing from the Service Worker Manager thread to constellation
340#[derive(Debug, Deserialize, Serialize)]
341pub enum SWManagerMsg {
342    /// Placeholder to keep the enum,
343    /// as it will be needed when implementing
344    /// <https://github.com/servo/servo/issues/24660>
345    PostMessageToClient,
346}
347
348/// Used to determine if a script has any pending asynchronous activity.
349#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
350pub enum DocumentState {
351    /// The document has been loaded and is idle.
352    Idle,
353    /// The document is either loading or waiting on an event.
354    Pending,
355}
356
357/// This trait allows creating a `ServiceWorkerManager` without depending on the `script`
358/// crate.
359pub trait ServiceWorkerManagerFactory {
360    /// Create a `ServiceWorkerManager`.
361    fn create(sw_senders: SWManagerSenders, origin: ImmutableOrigin);
362}
363
364/// Whether the sandbox attribute is present for an iframe element
365#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
366pub enum IFrameSandboxState {
367    /// Sandbox attribute is present
368    IFrameSandboxed,
369    /// Sandbox attribute is not present
370    IFrameUnsandboxed,
371}
372
373/// Specifies the information required to load an auxiliary browsing context.
374#[derive(Debug, Deserialize, Serialize)]
375pub struct AuxiliaryWebViewCreationRequest {
376    /// Load data containing the url to load
377    pub load_data: LoadData,
378    /// The webview that caused this request.
379    pub opener_webview_id: WebViewId,
380    /// The pipeline opener browsing context.
381    pub opener_pipeline_id: PipelineId,
382    /// Sender for the constellation’s response to our request.
383    pub response_sender: IpcSender<Option<AuxiliaryWebViewCreationResponse>>,
384}
385
386/// Constellation’s response to auxiliary browsing context creation requests.
387#[derive(Debug, Deserialize, Serialize)]
388pub struct AuxiliaryWebViewCreationResponse {
389    /// The new webview ID.
390    pub new_webview_id: WebViewId,
391    /// The new pipeline ID.
392    pub new_pipeline_id: PipelineId,
393}
394
395/// Specifies the information required to load an iframe.
396#[derive(Debug, Deserialize, Serialize)]
397pub struct IFrameLoadInfo {
398    /// Pipeline ID of the parent of this iframe
399    pub parent_pipeline_id: PipelineId,
400    /// The ID for this iframe's nested browsing context.
401    pub browsing_context_id: BrowsingContextId,
402    /// The ID for the top-level ancestor browsing context of this iframe's nested browsing context.
403    pub webview_id: WebViewId,
404    /// The new pipeline ID that the iframe has generated.
405    pub new_pipeline_id: PipelineId,
406    ///  Whether this iframe should be considered private
407    pub is_private: bool,
408    ///  Whether this iframe should be considered secure
409    pub inherited_secure_context: Option<bool>,
410    /// Whether this load should replace the current entry (reload). If true, the current
411    /// entry will be replaced instead of a new entry being added.
412    pub history_handling: NavigationHistoryBehavior,
413}
414
415/// Specifies the information required to load a URL in an iframe.
416#[derive(Debug, Deserialize, Serialize)]
417pub struct IFrameLoadInfoWithData {
418    /// The information required to load an iframe.
419    pub info: IFrameLoadInfo,
420    /// Load data containing the url to load
421    pub load_data: LoadData,
422    /// The old pipeline ID for this iframe, if a page was previously loaded.
423    pub old_pipeline_id: Option<PipelineId>,
424    /// Sandbox type of this iframe
425    pub sandbox: IFrameSandboxState,
426    /// The initial viewport size for this iframe.
427    pub viewport_details: ViewportDetails,
428    /// The [`Theme`] to use within this iframe.
429    pub theme: Theme,
430}
431
432/// Resources required by workerglobalscopes
433#[derive(Clone, Debug, Deserialize, Serialize)]
434pub struct WorkerGlobalScopeInit {
435    /// Chan to a resource thread
436    pub resource_threads: ResourceThreads,
437    /// Chan to the memory profiler
438    pub mem_profiler_chan: mem::ProfilerChan,
439    /// Chan to the time profiler
440    pub time_profiler_chan: profile_time::ProfilerChan,
441    /// To devtools sender
442    pub to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
443    /// From devtools sender
444    pub from_devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
445    /// Messages to send to constellation
446    pub script_to_constellation_chan: ScriptToConstellationChan,
447    /// The worker id
448    pub worker_id: WorkerId,
449    /// The pipeline id
450    pub pipeline_id: PipelineId,
451    /// The origin
452    pub origin: ImmutableOrigin,
453    /// The creation URL
454    pub creation_url: ServoUrl,
455    /// True if secure context
456    pub inherited_secure_context: Option<bool>,
457}
458
459/// Common entities representing a network load origin
460#[derive(Clone, Debug, Deserialize, Serialize)]
461pub struct WorkerScriptLoadOrigin {
462    /// referrer url
463    pub referrer_url: Option<ServoUrl>,
464    /// the referrer policy which is used
465    pub referrer_policy: ReferrerPolicy,
466    /// the pipeline id of the entity requesting the load
467    pub pipeline_id: PipelineId,
468}
469
470/// An iframe sizing operation.
471#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
472pub struct IFrameSizeMsg {
473    /// The child browsing context for this iframe.
474    pub browsing_context_id: BrowsingContextId,
475    /// The size and scale factor of the iframe.
476    pub size: ViewportDetails,
477    /// The kind of sizing operation.
478    pub type_: WindowSizeType,
479}
480
481/// Messages from the script to the constellation.
482#[derive(Deserialize, IntoStaticStr, Serialize)]
483pub enum ScriptToConstellationMessage {
484    /// Request to complete the transfer of a set of ports to a router.
485    CompleteMessagePortTransfer(MessagePortRouterId, Vec<MessagePortId>),
486    /// The results of attempting to complete the transfer of a batch of ports.
487    MessagePortTransferResult(
488        /* The router whose transfer of ports succeeded, if any */
489        Option<MessagePortRouterId>,
490        /* The ids of ports transferred successfully */
491        Vec<MessagePortId>,
492        /* The ids, and buffers, of ports whose transfer failed */
493        HashMap<MessagePortId, PortTransferInfo>,
494    ),
495    /// A new message-port was created or transferred, with corresponding control-sender.
496    NewMessagePort(MessagePortRouterId, MessagePortId),
497    /// A global has started managing message-ports
498    NewMessagePortRouter(MessagePortRouterId, IpcSender<MessagePortMsg>),
499    /// A global has stopped managing message-ports
500    RemoveMessagePortRouter(MessagePortRouterId),
501    /// A task requires re-routing to an already shipped message-port.
502    RerouteMessagePort(MessagePortId, PortMessageTask),
503    /// A message-port was shipped, let the entangled port know.
504    MessagePortShipped(MessagePortId),
505    /// Entangle two message-ports.
506    EntanglePorts(MessagePortId, MessagePortId),
507    /// Disentangle two message-ports.
508    /// The first is the initiator, the second the other port,
509    /// unless the message is sent to complete a disentanglement,
510    /// in which case the first one is the other port,
511    /// and the second is none.
512    DisentanglePorts(MessagePortId, Option<MessagePortId>),
513    /// A global has started managing broadcast-channels.
514    NewBroadcastChannelRouter(
515        BroadcastChannelRouterId,
516        IpcSender<BroadcastChannelMsg>,
517        ImmutableOrigin,
518    ),
519    /// A global has stopped managing broadcast-channels.
520    RemoveBroadcastChannelRouter(BroadcastChannelRouterId, ImmutableOrigin),
521    /// A global started managing broadcast channels for a given channel-name.
522    NewBroadcastChannelNameInRouter(BroadcastChannelRouterId, String, ImmutableOrigin),
523    /// A global stopped managing broadcast channels for a given channel-name.
524    RemoveBroadcastChannelNameInRouter(BroadcastChannelRouterId, String, ImmutableOrigin),
525    /// Broadcast a message to all same-origin broadcast channels,
526    /// excluding the source of the broadcast.
527    ScheduleBroadcast(BroadcastChannelRouterId, BroadcastChannelMsg),
528    /// Forward a message to the embedder.
529    ForwardToEmbedder(EmbedderMsg),
530    /// Broadcast a storage event to every same-origin pipeline.
531    /// The strings are key, old value and new value.
532    BroadcastStorageEvent(
533        StorageType,
534        ServoUrl,
535        Option<String>,
536        Option<String>,
537        Option<String>,
538    ),
539    /// Indicates whether this pipeline is currently running animations.
540    ChangeRunningAnimationsState(AnimationState),
541    /// Requests that a new 2D canvas thread be created. (This is done in the constellation because
542    /// 2D canvases may use the GPU and we don't want to give untrusted content access to the GPU.)
543    CreateCanvasPaintThread(
544        UntypedSize2D<u64>,
545        IpcSender<Option<(IpcSender<CanvasMsg>, CanvasId, ImageKey)>>,
546    ),
547    /// Notifies the constellation that this pipeline is requesting focus.
548    ///
549    /// When this message is sent, the sender pipeline has already its local
550    /// focus state updated. The constellation, after receiving this message,
551    /// will broadcast messages to other pipelines that are affected by this
552    /// focus operation.
553    ///
554    /// The first field contains the browsing context ID of the container
555    /// element if one was focused.
556    ///
557    /// The second field is a sequence number that the constellation should use
558    /// when sending a focus-related message to the sender pipeline next time.
559    Focus(Option<BrowsingContextId>, FocusSequenceNumber),
560    /// Requests the constellation to focus the specified browsing context.
561    FocusRemoteDocument(BrowsingContextId),
562    /// Get the top-level browsing context info for a given browsing context.
563    GetTopForBrowsingContext(BrowsingContextId, IpcSender<Option<WebViewId>>),
564    /// Get the browsing context id of the browsing context in which pipeline is
565    /// embedded and the parent pipeline id of that browsing context.
566    GetBrowsingContextInfo(
567        PipelineId,
568        IpcSender<Option<(BrowsingContextId, Option<PipelineId>)>>,
569    ),
570    /// Get the nth child browsing context ID for a given browsing context, sorted in tree order.
571    GetChildBrowsingContextId(
572        BrowsingContextId,
573        usize,
574        IpcSender<Option<BrowsingContextId>>,
575    ),
576    /// All pending loads are complete, and the `load` event for this pipeline
577    /// has been dispatched.
578    LoadComplete,
579    /// A new load has been requested, with an option to replace the current entry once loaded
580    /// instead of adding a new entry.
581    LoadUrl(LoadData, NavigationHistoryBehavior),
582    /// Abort loading after sending a LoadUrl message.
583    AbortLoadUrl,
584    /// Post a message to the currently active window of a given browsing context.
585    PostMessage {
586        /// The target of the posted message.
587        target: BrowsingContextId,
588        /// The source of the posted message.
589        source: PipelineId,
590        /// The expected origin of the target.
591        target_origin: Option<ImmutableOrigin>,
592        /// The source origin of the message.
593        /// <https://html.spec.whatwg.org/multipage/#dom-messageevent-origin>
594        source_origin: ImmutableOrigin,
595        /// The data to be posted.
596        data: StructuredSerializedData,
597    },
598    /// Inform the constellation that a fragment was navigated to and whether or not it was a replacement navigation.
599    NavigatedToFragment(ServoUrl, NavigationHistoryBehavior),
600    /// HTMLIFrameElement Forward or Back traversal.
601    TraverseHistory(TraversalDirection),
602    /// Inform the constellation of a pushed history state.
603    PushHistoryState(HistoryStateId, ServoUrl),
604    /// Inform the constellation of a replaced history state.
605    ReplaceHistoryState(HistoryStateId, ServoUrl),
606    /// Gets the length of the joint session history from the constellation.
607    JointSessionHistoryLength(IpcSender<u32>),
608    /// Notification that this iframe should be removed.
609    /// Returns a list of pipelines which were closed.
610    RemoveIFrame(BrowsingContextId, IpcSender<Vec<PipelineId>>),
611    /// Successful response to [crate::ConstellationControlMsg::SetThrottled].
612    SetThrottledComplete(bool),
613    /// A load has been requested in an IFrame.
614    ScriptLoadedURLInIFrame(IFrameLoadInfoWithData),
615    /// A load of the initial `about:blank` has been completed in an IFrame.
616    ScriptNewIFrame(IFrameLoadInfoWithData),
617    /// Script has opened a new auxiliary browsing context.
618    CreateAuxiliaryWebView(AuxiliaryWebViewCreationRequest),
619    /// Mark a new document as active
620    ActivateDocument,
621    /// Set the document state for a pipeline (used by screenshot / reftests)
622    SetDocumentState(DocumentState),
623    /// Update the layout epoch in the constellation (used by screenshot / reftests).
624    SetLayoutEpoch(Epoch, IpcSender<bool>),
625    /// Update the pipeline Url, which can change after redirections.
626    SetFinalUrl(ServoUrl),
627    /// Script has handled a touch event, and either prevented or allowed default actions.
628    TouchEventProcessed(TouchEventResult),
629    /// A log entry, with the top-level browsing context id and thread name
630    LogEntry(Option<String>, LogEntry),
631    /// Discard the document.
632    DiscardDocument,
633    /// Discard the browsing context.
634    DiscardTopLevelBrowsingContext,
635    /// Notifies the constellation that this pipeline has exited.
636    PipelineExited,
637    /// Send messages from postMessage calls from serviceworker
638    /// to constellation for storing in service worker manager
639    ForwardDOMMessage(DOMMessage, ServoUrl),
640    /// <https://w3c.github.io/ServiceWorker/#schedule-job-algorithm>
641    ScheduleJob(Job),
642    /// Notifies the constellation about media session events
643    /// (i.e. when there is metadata for the active media session, playback state changes...).
644    MediaSessionEvent(PipelineId, MediaSessionEvent),
645    #[cfg(feature = "webgpu")]
646    /// Create a WebGPU Adapter instance
647    RequestAdapter(
648        IpcSender<WebGPUAdapterResponse>,
649        wgpu_core::instance::RequestAdapterOptions,
650        wgpu_core::id::AdapterId,
651    ),
652    #[cfg(feature = "webgpu")]
653    /// Get WebGPU channel
654    GetWebGPUChan(IpcSender<Option<WebGPU>>),
655    /// Notify the constellation of a pipeline's document's title.
656    TitleChanged(PipelineId, String),
657    /// Notify the constellation that the size of some `<iframe>`s has changed.
658    IFrameSizes(Vec<IFrameSizeMsg>),
659    /// Request results from the memory reporter.
660    ReportMemory(IpcSender<MemoryReportResult>),
661    /// Return the result of the evaluated JavaScript with the given [`JavaScriptEvaluationId`].
662    FinishJavaScriptEvaluation(
663        JavaScriptEvaluationId,
664        Result<JSValue, JavaScriptEvaluationError>,
665    ),
666    /// Notify the completion of a webdriver command.
667    WebDriverInputComplete(WebDriverMessageId),
668}
669
670impl fmt::Debug for ScriptToConstellationMessage {
671    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
672        let variant_string: &'static str = self.into();
673        write!(formatter, "ScriptMsg::{variant_string}")
674    }
675}