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