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