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