Skip to main content

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;
8use std::sync::Arc;
9
10use content_security_policy::sandboxing_directive::SandboxingFlagSet;
11#[cfg(feature = "devtools")]
12use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg};
13use embedder_traits::user_contents::UserContentManagerId;
14use embedder_traits::{
15    AnimationState, FocusSequenceNumber, JSValue, JavaScriptEvaluationError,
16    JavaScriptEvaluationId, MediaSessionEvent, ScriptToEmbedderChan, ViewportDetails, WakeLockType,
17};
18use encoding_rs::Encoding;
19use euclid::default::Size2D as UntypedSize2D;
20use fonts_traits::SystemFontServiceProxySender;
21use http::{HeaderMap, Method};
22use malloc_size_of_derive::MallocSizeOf;
23use net_traits::policy_container::PolicyContainer;
24use net_traits::request::{Destination, InsecureRequestsPolicy, Referrer, RequestBody};
25use net_traits::{ReferrerPolicy, ResourceThreads};
26use paint_api::CrossProcessPaintApi;
27use profile_traits::mem::MemoryReportResult;
28use profile_traits::{mem, time as profile_time};
29use rustc_hash::FxHashMap;
30use serde::{Deserialize, Serialize};
31use servo_base::Epoch;
32use servo_base::generic_channel::{GenericCallback, GenericReceiver, GenericSender, SendResult};
33use servo_base::id::{
34    BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId,
35    MessagePortRouterId, PipelineId, ScriptEventLoopId, ServiceWorkerId,
36    ServiceWorkerRegistrationId, WebViewId, WorkerId,
37};
38use servo_canvas_traits::canvas::{CanvasId, CanvasMsg};
39#[cfg(feature = "webgl")]
40use servo_canvas_traits::webgl::WebGLChan;
41use servo_url::{ImmutableOrigin, OriginSnapshot, ServoUrl};
42use storage_traits::StorageThreads;
43use storage_traits::webstorage_thread::WebStorageType;
44use strum::IntoStaticStr;
45#[cfg(feature = "webgpu")]
46use webgpu_traits::{WebGPU, WebGPUAdapterResponse};
47
48use crate::structured_data::{BroadcastChannelMsg, StructuredSerializedData};
49use crate::{
50    LogEntry, MessagePortMsg, PortMessageTask, PortTransferInfo, SessionHistoryTraversalRequest,
51    WindowSizeType,
52};
53
54pub type ScriptToConstellationSender =
55    GenericSender<(WebViewId, PipelineId, ScriptToConstellationMessage)>;
56
57/// A Script to Constellation channel.
58#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
59pub struct ScriptToConstellationChan {
60    /// Sender for communicating with constellation thread.
61    pub sender: ScriptToConstellationSender,
62    /// Used to identify the origin `WebView` of the message.
63    pub webview_id: WebViewId,
64    /// Used to identify the origin `Pipeline` of the message.
65    pub pipeline_id: PipelineId,
66}
67
68impl ScriptToConstellationChan {
69    /// Send ScriptMsg and attach the pipeline_id to the message.
70    pub fn send(&self, msg: ScriptToConstellationMessage) -> SendResult {
71        self.sender.send((self.webview_id, self.pipeline_id, msg))
72    }
73}
74
75/// The origin where a given load was initiated.
76/// Useful for origin checks, for example before evaluation a JS URL.
77#[derive(Clone, Debug, Deserialize, Serialize)]
78pub enum LoadOrigin {
79    /// A load originating in the constellation.
80    Constellation,
81    /// A load originating in webdriver.
82    WebDriver,
83    /// A load originating in script.
84    Script(OriginSnapshot),
85}
86
87/// Messages sent from the service worker manager to the constellation.
88#[derive(Debug, Deserialize, Serialize)]
89pub enum ServiceWorkerManagerMsg {
90    /// <https://w3c.github.io/ServiceWorker/#update-worker-state>
91    UpdateWorkerState {
92        /// The identity of the service worker.
93        worker_id: ServiceWorkerId,
94        /// The new state of the service worker.
95        state: ServiceWorkerState,
96        /// The script url origin.
97        origin: ImmutableOrigin,
98    },
99}
100
101/// <https://w3c.github.io/ServiceWorker/#dfn-state>
102/// A service worker has an associated state, which is one of:
103#[derive(Clone, Debug, Deserialize, Serialize)]
104pub enum ServiceWorkerState {
105    /// "parsed".
106    /// It is initially "parsed".
107    Parsed,
108    /// "installing".
109    Installing,
110    /// "installed".
111    Installed,
112    /// "activating".
113    Activating,
114    /// "activated".
115    Activated,
116    /// "redundant".
117    Redundant,
118}
119
120/// can be passed to `LoadUrl` to load a page with GET/POST
121/// parameters or headers
122#[derive(Clone, Debug, Deserialize, Serialize)]
123pub struct LoadData {
124    /// The origin where the load started.
125    pub load_origin: LoadOrigin,
126    /// The URL.
127    pub url: ServoUrl,
128    /// <https://html.spec.whatwg.org/multipage/#concept-document-about-base-url>
129    pub about_base_url: Option<ServoUrl>,
130    /// The creator pipeline id if this is an about:blank load.
131    pub creator_pipeline_id: Option<PipelineId>,
132    /// The method.
133    #[serde(
134        deserialize_with = "::hyper_serde::deserialize",
135        serialize_with = "::hyper_serde::serialize"
136    )]
137    pub method: Method,
138    /// The headers.
139    #[serde(
140        deserialize_with = "::hyper_serde::deserialize",
141        serialize_with = "::hyper_serde::serialize"
142    )]
143    pub headers: HeaderMap,
144    /// The data that will be used as the body of the request.
145    pub data: Option<RequestBody>,
146    /// <https://fetch.spec.whatwg.org/#concept-request-reload-navigation-flag>
147    /// A request has an associated reload-navigation flag. Unless stated otherwise, it is unset.
148    pub reload_navigation: bool,
149    /// <https://fetch.spec.whatwg.org/#concept-request-history-navigation-flag>
150    /// A request has an associated history-navigation flag. Unless stated otherwise, it is unset.
151    pub history_navigation: bool,
152    /// The result of evaluating a javascript scheme url.
153    pub js_eval_result: Option<String>,
154    /// The referrer.
155    pub referrer: Referrer,
156    /// The referrer policy.
157    pub referrer_policy: ReferrerPolicy,
158    /// The policy container.
159    pub policy_container: Option<Arc<PolicyContainer>>,
160
161    /// The source to use instead of a network response for a srcdoc document.
162    pub srcdoc: String,
163    /// The inherited context is Secure, None if not inherited
164    pub inherited_secure_context: Option<bool>,
165    /// The inherited policy for upgrading insecure requests; None if not inherited.
166    pub inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
167    /// Whether the page's ancestors have potentially trustworthy origin
168    pub has_trustworthy_ancestor_origin: bool,
169    /// Servo internal: if crash details are present, trigger a crash error page with these details.
170    pub crash: Option<String>,
171    /// Destination, used for CSP checks
172    pub destination: Destination,
173    /// The "creation sandboxing flag set" that this Pipeline should use when it is created.
174    /// See <https://html.spec.whatwg.org/multipage/#determining-the-creation-sandboxing-flags>.
175    pub creation_sandboxing_flag_set: SandboxingFlagSet,
176    /// If this is a load operation for an `<iframe>` whose origin is same-origin with its
177    /// container documents origin then this is the encoding of the container document.
178    pub container_document_encoding: Option<&'static Encoding>,
179
180    /// If this request is for the initial about:blank document.
181    pub is_initial_about_blank: bool,
182}
183
184impl LoadData {
185    /// Create a new `LoadData` object.
186    #[expect(clippy::too_many_arguments)]
187    pub fn new(
188        load_origin: LoadOrigin,
189        url: ServoUrl,
190        about_base_url: Option<ServoUrl>,
191        creator_pipeline_id: Option<PipelineId>,
192        referrer: Referrer,
193        referrer_policy: ReferrerPolicy,
194        inherited_secure_context: Option<bool>,
195        inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
196        has_trustworthy_ancestor_origin: bool,
197        creation_sandboxing_flag_set: SandboxingFlagSet,
198    ) -> Self {
199        Self {
200            load_origin,
201            url,
202            about_base_url,
203            creator_pipeline_id,
204            method: Method::GET,
205            headers: HeaderMap::new(),
206            data: None,
207            reload_navigation: false,
208            history_navigation: false,
209            js_eval_result: None,
210            referrer,
211            referrer_policy,
212            policy_container: None,
213            srcdoc: String::new(),
214            inherited_secure_context,
215            crash: None,
216            inherited_insecure_requests_policy,
217            has_trustworthy_ancestor_origin,
218            destination: Destination::Document,
219            creation_sandboxing_flag_set,
220            container_document_encoding: None,
221            is_initial_about_blank: false,
222        }
223    }
224
225    /// Create a new [`LoadData`] for a completely new top-level `WebView` that isn't created
226    /// via APIs like `window.open`. This is for `WebView`s completely unrelated to others.
227    pub fn new_for_new_unrelated_webview(url: ServoUrl) -> Self {
228        Self::new(
229            LoadOrigin::Constellation,
230            url,
231            None,
232            None,
233            Referrer::NoReferrer,
234            ReferrerPolicy::EmptyString,
235            None,
236            None,
237            false,
238            SandboxingFlagSet::empty(),
239        )
240    }
241}
242
243/// <https://html.spec.whatwg.org/multipage/#navigation-supporting-concepts:navigationhistorybehavior>
244#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
245pub enum NavigationHistoryBehavior {
246    /// The default value, which will be converted very early in the navigate algorithm into "push"
247    /// or "replace". Usually it becomes "push", but under certain circumstances it becomes
248    /// "replace" instead.
249    #[default]
250    Auto,
251    /// A regular navigation which adds a new session history entry, and will clear the forward
252    /// session history.
253    Push,
254    /// A navigation that will replace the active session history entry.
255    Replace,
256}
257
258/// Entities required to spawn service workers
259#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
260pub struct ScopeThings {
261    /// script resource url
262    pub script_url: ServoUrl,
263    /// network load origin of the resource
264    pub worker_load_origin: WorkerScriptLoadOrigin,
265    /// base resources required to create worker global scopes
266    pub init: WorkerGlobalScopeInit,
267    /// the port to receive devtools message from
268    #[cfg(feature = "devtools")]
269    pub devtools_chan: Option<GenericCallback<ScriptToDevtoolsControlMsg>>,
270    /// service worker id
271    #[cfg(feature = "devtools")]
272    pub worker_id: WorkerId,
273    /// the browsing context id of the page that registered the service worker
274    pub browsing_context_id: BrowsingContextId,
275    /// the webview id of the page that registered the service worker
276    pub webview_id: WebViewId,
277}
278
279/// Message that gets passed to service worker scope on postMessage
280#[derive(Debug, Deserialize, Serialize)]
281pub struct DOMMessage {
282    /// The origin of the message
283    pub origin: ImmutableOrigin,
284    pub pipeline_id: PipelineId,
285    /// The payload of the message
286    pub data: StructuredSerializedData,
287}
288
289/// Channels to allow service worker manager to communicate with constellation and resource thread
290#[derive(Deserialize, Serialize)]
291pub struct SWManagerSenders {
292    /// Sender of messages to the constellation.
293    pub constellation_sender: GenericSender<ServiceWorkerManagerMsg>,
294    /// [`ResourceThreads`] for initating fetches or using i/o.
295    pub resource_threads: ResourceThreads,
296    /// [`CrossProcessPaintApi`] for communicating with `Paint`.
297    pub paint_api: CrossProcessPaintApi,
298    /// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
299    pub system_font_service_sender: SystemFontServiceProxySender,
300    /// Sender of messages to the manager.
301    pub own_sender: GenericSender<ServiceWorkerMsg>,
302    /// Receiver of messages from the constellation.
303    pub receiver: GenericReceiver<ServiceWorkerMsg>,
304}
305
306/// Messages sent to Service Worker Manager thread
307#[derive(Debug, Deserialize, Serialize)]
308pub enum ServiceWorkerMsg {
309    /// Timeout message sent by active service workers
310    Timeout(ServoUrl),
311    /// Message sent by constellation to forward to a running service worker
312    ForwardDOMMessage(DOMMessage, ServoUrl),
313    ForwardWorkerMessage {
314        data: StructuredSerializedData,
315        url: ServoUrl,
316        source: ServiceWorkerId,
317        origin: ImmutableOrigin,
318    },
319    /// <https://w3c.github.io/ServiceWorker/#algorithms>
320    HandleAlgorithm(ServiceWorkerAlgorithm),
321    SetNetworkOnlineState(bool),
322    /// Exit the service worker manager
323    Exit,
324}
325
326#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
327/// <https://w3c.github.io/ServiceWorker/#dfn-job-type>
328pub enum JobType {
329    /// <https://w3c.github.io/ServiceWorker/#register>
330    Register,
331    /// <https://w3c.github.io/ServiceWorker/#unregister-algorithm>
332    Unregister,
333    /// <https://w3c.github.io/ServiceWorker/#update-algorithm>
334    Update,
335}
336
337#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
338/// The kind of error the job promise should be rejected with.
339pub enum JobError {
340    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise>
341    TypeError,
342    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise>
343    SecurityError,
344}
345
346#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
347/// Messages sent from Job algorithms steps running in the SW manager,
348/// in order to resolve or reject the job promise.
349pub enum JobResult {
350    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise>
351    RejectPromise(JobError),
352    /// <https://w3c.github.io/ServiceWorker/#resolve-job-promise>
353    ResolvePromise(JobResultValue),
354}
355
356#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
357/// Jobs are resolved with the help of various values.
358pub enum JobResultValue {
359    Register(ServiceWorkerRegistrationInfo),
360    Unregister(bool),
361}
362
363/// <https://w3c.github.io/ServiceWorker/#dfn-service-worker-registration>
364#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
365pub struct ServiceWorkerRegistrationInfo {
366    /// The Id of the registration.
367    pub id: ServiceWorkerRegistrationId,
368    /// <https://w3c.github.io/ServiceWorker/#dfn-installing-worker>
369    pub installing_worker: Option<ServiceWorkerId>,
370    /// <https://w3c.github.io/ServiceWorker/#dfn-waiting-worker>
371    pub waiting_worker: Option<ServiceWorkerId>,
372    /// <https://w3c.github.io/ServiceWorker/#dfn-active-worker>
373    pub active_worker: Option<ServiceWorkerId>,
374    /// <https://w3c.github.io/ServiceWorker/#service-worker-registration-storage-key>
375    pub storage_key: ImmutableOrigin,
376    /// <https://w3c.github.io/ServiceWorker/#dfn-scope-url>
377    pub scope_url: ServoUrl,
378    /// <https://w3c.github.io/ServiceWorker/#dfn-job-script-url>
379    pub script_url: ServoUrl,
380}
381
382/// <https://w3c.github.io/ServiceWorker/#algorithms>
383#[derive(Debug, Deserialize, Serialize)]
384pub enum ServiceWorkerAlgorithm {
385    /// <https://w3c.github.io/ServiceWorker/#start-register>
386    StartRegister(Job),
387    /// <https://w3c.github.io/ServiceWorker/#unregister>
388    Unregister(Job),
389    /// <https://w3c.github.io/ServiceWorker/#match-service-worker-registration>
390    MatchServiceWorkerRegistration {
391        storage_key: ImmutableOrigin,
392        client_url: ServoUrl,
393        result_handler: GenericCallback<ServiceWorkerAlgorithmResult>,
394    },
395}
396
397/// <https://w3c.github.io/ServiceWorker/#algorithms>
398#[allow(clippy::large_enum_variant)]
399#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
400pub enum ServiceWorkerAlgorithmResult {
401    /// <https://w3c.github.io/ServiceWorker/#resolve-job-promise-algorithm>
402    /// <https://w3c.github.io/ServiceWorker/#reject-job-promise-algorithm>
403    Job(JobResult),
404
405    /// <https://w3c.github.io/ServiceWorker/#match-service-worker-registration>
406    MatchServiceWorkerRegistration(Option<ServiceWorkerRegistrationInfo>),
407
408    /// <https://w3c.github.io/ServiceWorker/#dom-client-postmessage-message-options>
409    /// Note: this is not algorithm; re-using algo channel for convenience.
410    MessageFromWorker {
411        message: StructuredSerializedData,
412        source: ServiceWorkerId,
413        scope_url: ServoUrl,
414        script_url: ServoUrl,
415        origin: ImmutableOrigin,
416    },
417}
418
419#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
420/// <https://w3c.github.io/ServiceWorker/#dfn-job>
421pub struct Job {
422    /// <https://w3c.github.io/ServiceWorker/#dfn-job-type>
423    pub job_type: JobType,
424    /// <https://w3c.github.io/ServiceWorker/#dfn-job-scope-url>
425    pub scope_url: ServoUrl,
426    /// <https://w3c.github.io/ServiceWorker/#dfn-job-script-url>
427    pub script_url: ServoUrl,
428    /// <https://w3c.github.io/ServiceWorker/#dfn-job-client>
429    pub client: GenericCallback<ServiceWorkerAlgorithmResult>,
430    /// <https://w3c.github.io/ServiceWorker/#job-referrer>
431    pub referrer: ServoUrl,
432    /// Various data needed to process job.
433    pub scope_things: Option<ScopeThings>,
434    /// <https://w3c.github.io/ServiceWorker/#job-storage-key>
435    pub storage_key: ImmutableOrigin,
436}
437
438impl Job {
439    /// <https://w3c.github.io/ServiceWorker/#create-job-algorithm>
440    pub fn create_job(
441        job_type: JobType,
442        scope_url: ServoUrl,
443        script_url: ServoUrl,
444        client: GenericCallback<ServiceWorkerAlgorithmResult>,
445        referrer: ServoUrl,
446        scope_things: Option<ScopeThings>,
447        storage_key: ImmutableOrigin,
448    ) -> Job {
449        Job {
450            job_type,
451            scope_url,
452            script_url,
453            client,
454            referrer,
455            scope_things,
456            storage_key,
457        }
458    }
459}
460
461impl PartialEq for Job {
462    /// Equality criteria as described in <https://w3c.github.io/ServiceWorker/#dfn-job-equivalent>
463    fn eq(&self, other: &Self) -> bool {
464        // TODO: match on job type, take worker type and `update_via_cache_mode` into account.
465        let same_job = self.job_type == other.job_type;
466        if same_job {
467            match self.job_type {
468                JobType::Register | JobType::Update => {
469                    self.scope_url == other.scope_url && self.script_url == other.script_url
470                },
471                JobType::Unregister => self.scope_url == other.scope_url,
472            }
473        } else {
474            false
475        }
476    }
477}
478
479/// This trait allows creating a `ServiceWorkerManager` without depending on the `script`
480/// crate.
481pub trait ServiceWorkerManagerFactory {
482    /// Create a `ServiceWorkerManager`.
483    fn create(sw_senders: SWManagerSenders, origin: ImmutableOrigin);
484}
485
486/// Specifies the information required to load an auxiliary browsing context.
487#[derive(Debug, Deserialize, Serialize)]
488pub struct AuxiliaryWebViewCreationRequest {
489    /// Load data containing the url to load
490    pub load_data: LoadData,
491    /// The webview that caused this request.
492    pub opener_webview_id: WebViewId,
493    /// The pipeline opener browsing context.
494    pub opener_pipeline_id: PipelineId,
495    /// Sender for the constellation’s response to our request.
496    pub response_sender: GenericSender<Option<AuxiliaryWebViewCreationResponse>>,
497}
498
499/// Constellation’s response to auxiliary browsing context creation requests.
500#[derive(Debug, Deserialize, Serialize)]
501pub struct AuxiliaryWebViewCreationResponse {
502    /// The new webview ID.
503    pub new_webview_id: WebViewId,
504    /// The new pipeline ID.
505    pub new_pipeline_id: PipelineId,
506    /// The [`UserContentManagerId`] for this new auxiliary browsing context.
507    pub user_content_manager_id: Option<UserContentManagerId>,
508}
509
510/// Specifies the information required to load an iframe.
511#[derive(Debug, Deserialize, Serialize)]
512pub struct IFrameLoadInfo {
513    /// Pipeline ID of the parent of this iframe
514    pub parent_pipeline_id: PipelineId,
515    /// The ID for this iframe's nested browsing context.
516    pub browsing_context_id: BrowsingContextId,
517    /// The ID for the top-level ancestor browsing context of this iframe's nested browsing context.
518    pub webview_id: WebViewId,
519    /// The new pipeline ID that the iframe has generated.
520    pub new_pipeline_id: PipelineId,
521    ///  Whether this iframe should be considered private
522    pub is_private: bool,
523    ///  Whether this iframe should be considered secure
524    pub inherited_secure_context: Option<bool>,
525    /// Whether this load should replace the current entry (reload). If true, the current
526    /// entry will be replaced instead of a new entry being added.
527    pub history_handling: NavigationHistoryBehavior,
528    /// A snapshot of the navigation-related parameters of the target
529    /// of this navigation.
530    pub target_snapshot_params: TargetSnapshotParams,
531    /// Name of this iframe, if any
532    pub name: Option<String>,
533}
534
535/// Specifies the information required to load a URL in an iframe.
536#[derive(Debug, Deserialize, Serialize)]
537pub struct IFrameLoadInfoWithData {
538    /// The information required to load an iframe.
539    pub info: IFrameLoadInfo,
540    /// Load data containing the url to load
541    pub load_data: LoadData,
542    /// The old pipeline ID for this iframe, if a page was previously loaded.
543    pub old_pipeline_id: Option<PipelineId>,
544    /// The initial viewport size for this iframe.
545    pub viewport_details: ViewportDetails,
546}
547
548/// Resources required by workerglobalscopes
549#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
550pub struct WorkerGlobalScopeInit {
551    /// Chan to a resource thread
552    pub resource_threads: ResourceThreads,
553    /// Chan to a storage thread
554    pub storage_threads: StorageThreads,
555    /// Chan to the memory profiler
556    pub mem_profiler_chan: mem::ProfilerChan,
557    /// Chan to the time profiler
558    pub time_profiler_chan: profile_time::ProfilerChan,
559    /// To devtools sender
560    #[cfg(feature = "devtools")]
561    pub to_devtools_sender: Option<GenericCallback<ScriptToDevtoolsControlMsg>>,
562    /// From devtools sender
563    #[cfg(feature = "devtools")]
564    pub from_devtools_sender: Option<GenericSender<DevtoolScriptControlMsg>>,
565    /// Messages to send to constellation
566    pub script_to_constellation_chan: ScriptToConstellationSender,
567    /// Messages to send to the Embedder
568    pub script_to_embedder_chan: ScriptToEmbedderChan,
569    /// The worker id
570    pub worker_id: WorkerId,
571    /// Whether this worker's `AnimationFrameProvider` is supported.
572    pub animation_frame_provider_supported: bool,
573    /// The pipeline id
574    pub pipeline_id: PipelineId,
575    /// The origin
576    pub origin: ImmutableOrigin,
577    /// True if secure context
578    pub inherited_secure_context: Option<bool>,
579    /// Unminify Javascript.
580    pub unminify_js: bool,
581    /// Handle for communicating messages to the WebGL thread, if available.
582    #[cfg(feature = "webgl")]
583    pub webgl_chan: Option<WebGLChan>,
584    /// Whether or not Servo is online.
585    pub online: bool,
586}
587
588/// Message delivered to a worker event loop to run animation frame callbacks.
589#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
590pub struct WorkerAnimationFrameTick;
591
592/// Common entities representing a network load origin
593#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
594pub struct WorkerScriptLoadOrigin {
595    /// referrer url
596    pub referrer_url: Option<ServoUrl>,
597    /// the referrer policy which is used
598    pub referrer_policy: ReferrerPolicy,
599    /// the pipeline id of the entity requesting the load
600    pub pipeline_id: PipelineId,
601}
602
603/// An iframe sizing operation.
604#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
605pub struct IFrameSizeMsg {
606    /// The child browsing context for this iframe.
607    pub browsing_context_id: BrowsingContextId,
608    /// The size and scale factor of the iframe.
609    pub size: ViewportDetails,
610    /// The kind of sizing operation.
611    pub type_: WindowSizeType,
612}
613
614/// An enum that describe a type of keyboard scroll.
615#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
616pub enum KeyboardScroll {
617    /// Scroll the container one line up.
618    Up,
619    /// Scroll the container one line down.
620    Down,
621    /// Scroll the container one "line" left.
622    Left,
623    /// Scroll the container one "line" right.
624    Right,
625    /// Scroll the container one page up.
626    PageUp,
627    /// Scroll the container one page down.
628    PageDown,
629    /// Scroll the container to the vertical start.
630    Home,
631    /// Scroll the container to the vertical end.
632    End,
633}
634
635#[derive(Debug, Deserialize, Serialize)]
636pub enum ScreenshotReadinessResponse {
637    /// The Pipeline associated with this response, is ready for a screenshot at the
638    /// provided [`Epoch`].
639    Ready(Epoch),
640    /// The Pipeline associated with this response is no longer active and should be
641    /// ignored for the purposes of the screenshot.
642    NoLongerActive,
643}
644
645/// Identifies a category of events/notifications that a pipeline can register
646/// interest in with the constellation. When a pipeline has active listeners for
647/// events in a given category, it registers interest so the constellation only
648/// sends notifications to pipelines that care.
649#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
650pub enum ConstellationInterest {
651    /// Interest in `storage` events (fired when another same-origin pipeline modifies storage).
652    StorageEvent,
653}
654
655/// Messages from the script to the constellation.
656#[derive(Deserialize, IntoStaticStr, Serialize)]
657pub enum ScriptToConstellationMessage {
658    ServiceWorkerAlgorithm(ServiceWorkerAlgorithm),
659    /// Request to complete the transfer of a set of ports to a router.
660    CompleteMessagePortTransfer(MessagePortRouterId, Vec<MessagePortId>),
661    /// The results of attempting to complete the transfer of a batch of ports.
662    MessagePortTransferResult(
663        /* The router whose transfer of ports succeeded, if any */
664        Option<MessagePortRouterId>,
665        /* The ids of ports transferred successfully */
666        Vec<MessagePortId>,
667        /* The ids, and buffers, of ports whose transfer failed */
668        FxHashMap<MessagePortId, PortTransferInfo>,
669    ),
670    /// A new message-port was created or transferred, with corresponding control-sender.
671    NewMessagePort(MessagePortRouterId, MessagePortId),
672    /// A global has started managing message-ports
673    NewMessagePortRouter(MessagePortRouterId, GenericCallback<MessagePortMsg>),
674    /// A global has stopped managing message-ports
675    RemoveMessagePortRouter(MessagePortRouterId),
676    /// A task requires re-routing to an already shipped message-port.
677    RerouteMessagePort(MessagePortId, PortMessageTask),
678    /// A message-port was shipped, let the entangled port know.
679    MessagePortShipped(MessagePortId),
680    /// Entangle two message-ports.
681    EntanglePorts(MessagePortId, MessagePortId),
682    /// Disentangle two message-ports.
683    /// The first is the initiator, the second the other port,
684    /// unless the message is sent to complete a disentanglement,
685    /// in which case the first one is the other port,
686    /// and the second is none.
687    DisentanglePorts(MessagePortId, Option<MessagePortId>),
688    /// A global has started managing broadcast-channels.
689    NewBroadcastChannelRouter(
690        BroadcastChannelRouterId,
691        GenericCallback<BroadcastChannelMsg>,
692        ImmutableOrigin,
693    ),
694    /// A global has stopped managing broadcast-channels.
695    RemoveBroadcastChannelRouter(BroadcastChannelRouterId, ImmutableOrigin),
696    /// A global started managing broadcast channels for a given channel-name.
697    NewBroadcastChannelNameInRouter(BroadcastChannelRouterId, String, ImmutableOrigin),
698    /// A global stopped managing broadcast channels for a given channel-name.
699    RemoveBroadcastChannelNameInRouter(BroadcastChannelRouterId, String, ImmutableOrigin),
700    /// Broadcast a message to all same-origin broadcast channels,
701    /// excluding the source of the broadcast.
702    ScheduleBroadcast(BroadcastChannelRouterId, BroadcastChannelMsg),
703    /// Register this pipeline's interest in a category of notifications.
704    /// The constellation will only send notifications in this category to
705    /// pipelines that have registered interest.
706    RegisterInterest(ConstellationInterest),
707    /// Unregister this pipeline's interest in a category of notifications.
708    UnregisterInterest(ConstellationInterest),
709    /// Broadcast a storage event to every same-origin pipeline.
710    /// The strings are key, old value and new value.
711    BroadcastStorageEvent(
712        WebStorageType,
713        ServoUrl,
714        Option<String>,
715        Option<String>,
716        Option<String>,
717    ),
718    /// Indicates whether this pipeline is currently running animations.
719    ChangeRunningAnimationsState(AnimationState),
720    /// Register a dedicated worker that can receive animation frame ticks.
721    RegisterWorkerAnimationFrameProvider(WorkerId, GenericSender<WorkerAnimationFrameTick>),
722    /// Unregister a dedicated worker animation frame provider.
723    UnregisterWorkerAnimationFrameProvider(WorkerId),
724    /// Indicates whether a dedicated worker has pending animation frame callbacks.
725    ChangeWorkerAnimationFrameProviderState(WorkerId, bool),
726    /// Requests that a new 2D canvas thread be created. (This is done in the constellation because
727    /// 2D canvases may use the GPU and we don't want to give untrusted content access to the GPU.)
728    CreateCanvasPaintThread(
729        UntypedSize2D<u64>,
730        GenericSender<Option<(GenericSender<CanvasMsg>, CanvasId)>>,
731    ),
732    /// Notifies the constellation that this pipeline is requesting focus.
733    ///
734    /// When this message is sent, the sender pipeline has already its local
735    /// focus state updated. The constellation, after receiving this message,
736    /// will broadcast messages to other pipelines that are affected by this
737    /// focus operation.
738    ///
739    /// The first field contains the browsing context ID of the container
740    /// element if one was focused.
741    ///
742    /// The second field is a sequence number that the constellation should use
743    /// when sending a focus-related message to the sender pipeline next time.
744    FocusAncestorBrowsingContextsForFocusingSteps(Option<BrowsingContextId>, FocusSequenceNumber),
745    /// Focus a remote `BrowsingContext` and run the focusing steps. This is used in two situations:
746    /// - When calling the DOM `focus()` API on a remote `Window` as well as from
747    ///   WebDriver. The difference between this and `FocusDocumentAsPartOfFocusingSteps` is that this
748    ///   version actually does run the focusing steps and may result in blur and focus events firing
749    ///   up the frame tree.
750    /// - When doing sequential focus navigation into and out of frames.
751    FocusRemoteBrowsingContext(BrowsingContextId, RemoteFocusOperation),
752    /// Get the top-level browsing context info for a given browsing context.
753    GetTopForBrowsingContext(BrowsingContextId, GenericSender<Option<WebViewId>>),
754    /// Get the browsing context id of the browsing context in which pipeline is
755    /// embedded and the parent pipeline id of that browsing context.
756    GetBrowsingContextInfo(
757        PipelineId,
758        GenericSender<Option<(BrowsingContextId, Option<PipelineId>)>>,
759    ),
760    /// Get the count of child browsing contexts for a given browsing context.
761    GetChildBrowsingContextCount(BrowsingContextId, GenericSender<usize>),
762    /// Get the nth child browsing context ID for a given browsing context, when sorted in
763    /// insertion order.
764    GetChildBrowsingContextId(
765        BrowsingContextId,
766        usize,
767        GenericSender<Option<BrowsingContextId>>,
768    ),
769    /// Get the origin of the document corresponding to the given pipeline
770    GetDocumentOrigin(PipelineId, GenericSender<Option<OriginSnapshot>>),
771    /// If the document corresponding to the given pipeline is fully active
772    IsCurrentlyFullyActive(PipelineId, GenericSender<bool>),
773    /// Get the origin and internal ancestor origin objects list of the `Document`
774    /// corresponding to the given `PipelineId`.
775    GetDocumentOriginDetails(
776        PipelineId,
777        GenericSender<Option<(OriginSnapshot, Vec<ImmutableOrigin>)>>,
778    ),
779    /// All pending loads are complete, and the `load` event for this pipeline
780    /// has been dispatched.
781    LoadComplete,
782    /// A new load has been requested, with an option to replace the current entry once loaded
783    /// instead of adding a new entry.
784    LoadUrl(LoadData, NavigationHistoryBehavior, TargetSnapshotParams),
785    /// Abort loading after sending a LoadUrl message.
786    AbortLoadUrl,
787    /// Post a message to the currently active window of a given browsing context.
788    PostMessage {
789        /// The target of the posted message.
790        target: BrowsingContextId,
791        /// The source of the posted message.
792        source: PipelineId,
793        /// The expected origin of the target.
794        target_origin: Option<ImmutableOrigin>,
795        /// The source origin of the message.
796        /// <https://html.spec.whatwg.org/multipage/#dom-messageevent-origin>
797        source_origin: ImmutableOrigin,
798        /// The data to be posted.
799        data: StructuredSerializedData,
800    },
801    /// Inform the constellation that a fragment was navigated to and whether or not it was a replacement navigation.
802    NavigatedToFragment(ServoUrl, NavigationHistoryBehavior),
803    /// HTMLIFrameElement Forward or Back traversal.
804    TraverseHistory(SessionHistoryTraversalRequest),
805    /// Inform the constellation of a pushed history state.
806    PushHistoryState(HistoryStateId, ServoUrl),
807    /// Inform the constellation of a replaced history state.
808    ReplaceHistoryState(HistoryStateId, ServoUrl),
809    /// Gets the length of the joint session history from the constellation.
810    JointSessionHistoryLength(GenericSender<u32>),
811    /// Notification that this iframe should be removed.
812    /// Returns a list of pipelines which were closed.
813    RemoveIFrame(BrowsingContextId, GenericSender<Vec<PipelineId>>),
814    /// A load has been requested in an IFrame.
815    ScriptLoadedURLInIFrame(IFrameLoadInfoWithData),
816    /// A load of the initial `about:blank` has been completed in an IFrame.
817    ScriptNewIFrame(IFrameLoadInfoWithData),
818    /// Script has opened a new auxiliary browsing context.
819    CreateAuxiliaryWebView(AuxiliaryWebViewCreationRequest),
820    /// Mark a new document as active
821    ActivateDocument,
822    /// Update the pipeline Url, which can change after redirections.
823    SetFinalUrl(ServoUrl),
824    /// A log entry, with the top-level browsing context id and thread name
825    LogEntry(Option<ScriptEventLoopId>, Option<String>, LogEntry),
826    /// Discard the document.
827    DiscardDocument,
828    /// Discard the browsing context.
829    DiscardTopLevelBrowsingContext,
830    /// Notifies the constellation that this pipeline has exited.
831    PipelineExited,
832    /// Send messages from postMessage calls from serviceworker
833    /// to constellation for storing in service worker manager
834    ForwardDOMMessage(DOMMessage, ServoUrl),
835    /// Notifies the constellation about media session events
836    /// (i.e. when there is metadata for the active media session, playback state changes...).
837    MediaSessionEvent(PipelineId, MediaSessionEvent),
838    #[cfg(feature = "webgpu")]
839    /// Create a WebGPU Adapter instance
840    RequestAdapter(
841        GenericCallback<WebGPUAdapterResponse>,
842        wgpu_core::instance::RequestAdapterOptions,
843        wgpu_core::id::AdapterId,
844    ),
845    #[cfg(feature = "webgpu")]
846    /// Get WebGPU channel
847    GetWebGPUChan(GenericSender<Option<WebGPU>>),
848    /// Notify the constellation of a pipeline's document's title.
849    TitleChanged(PipelineId, String),
850    /// Notify the constellation that the size of some `<iframe>`s has changed.
851    IFrameSizes(Vec<IFrameSizeMsg>),
852    /// Request results from the memory reporter.
853    ReportMemory(GenericCallback<MemoryReportResult>),
854    /// Return the result of the evaluated JavaScript with the given [`JavaScriptEvaluationId`].
855    FinishJavaScriptEvaluation(
856        JavaScriptEvaluationId,
857        Result<JSValue, JavaScriptEvaluationError>,
858    ),
859    /// Forward a keyboard scroll operation from an `<iframe>` to a parent pipeline.
860    ForwardKeyboardScroll(PipelineId, KeyboardScroll),
861    /// Notify the Constellation of the screenshot readiness of a given pipeline.
862    RespondToScreenshotReadinessRequest(ScreenshotReadinessResponse),
863    /// Request the constellation to force garbage collection in all `ScriptThread`'s.
864    TriggerGarbageCollection,
865    /// Request to acquire a wake lock of the given type. The constellation will track the
866    /// aggregate lock count and notify the provider only when the count transitions from 0 to 1.
867    /// <https://w3c.github.io/screen-wake-lock/#dfn-acquire-wake-lock>
868    AcquireWakeLock(WakeLockType),
869    /// Request to release a wake lock of the given type. The constellation will track the
870    /// aggregate lock count and notify the provider only when the count transitions from N to 0.
871    /// <https://w3c.github.io/screen-wake-lock/#dfn-release-wake-lock>
872    ReleaseWakeLock(WakeLockType),
873}
874
875impl fmt::Debug for ScriptToConstellationMessage {
876    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
877        let variant_string: &'static str = self.into();
878        write!(formatter, "ScriptMsg::{variant_string}")
879    }
880}
881
882/// <https://html.spec.whatwg.org/multipage/#target-snapshot-params>
883#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
884pub struct TargetSnapshotParams {
885    /// <https://html.spec.whatwg.org/multipage/#target-snapshot-params-sandbox>
886    pub sandboxing_flags: SandboxingFlagSet,
887    /// <https://html.spec.whatwg.org/multipage/#target-snapshot-params-iframe-referrer-policy>
888    pub iframe_element_referrer_policy: ReferrerPolicy,
889}
890
891impl Default for TargetSnapshotParams {
892    fn default() -> Self {
893        Self {
894            sandboxing_flags: SandboxingFlagSet::empty(),
895            iframe_element_referrer_policy: ReferrerPolicy::EmptyString,
896        }
897    }
898}
899
900/// <https://html.spec.whatwg.org/multipage/#sequential-focus-direction>
901///
902/// > A sequential focus direction is one of two possible values: "forward", or "backward". They are
903/// > used in the below algorithms to describe the direction in which sequential focus travels at the
904/// > user's request.
905#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
906pub enum SequentialFocusDirection {
907    Forward,
908    Backward,
909}
910
911/// The type of focus operation to do on a remote document.
912#[derive(Deserialize, Serialize)]
913pub enum RemoteFocusOperation {
914    /// Focus the entire viewport of the remote document.
915    Viewport,
916    /// Do sequential focus navigation using the `<iframe>` element with the given
917    /// [`BrowsingContextId`] as the starting point and in the given direction.
918    Sequential(SequentialFocusDirection, Option<BrowsingContextId>),
919}