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