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