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