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 http://mozilla.org/MPL/2.0/. */
4
5 //! This module contains traits in script used generically in the rest of Servo.
6 //! The traits are here instead of in script so that these modules won't have
7 //! to depend on script.
8
9 #![deny(missing_docs)]
10 #![deny(unsafe_code)]
11
12 extern crate bluetooth_traits;
13 extern crate canvas_traits;
14 extern crate cookie as cookie_rs;
15 extern crate devtools_traits;
16 extern crate euclid;
17 extern crate gfx_traits;
18 extern crate hyper;
19 extern crate hyper_serde;
20 extern crate ipc_channel;
21 extern crate libc;
22 #[macro_use]
23 extern crate malloc_size_of;
24 #[macro_use]
25 extern crate malloc_size_of_derive;
26 extern crate msg;
27 extern crate net_traits;
28 extern crate profile_traits;
29 extern crate rustc_serialize;
30 #[macro_use] extern crate serde;
31 extern crate servo_atoms;
32 extern crate servo_url;
33 extern crate style_traits;
34 extern crate time;
35 extern crate webrender_api;
36 extern crate webvr_traits;
37
38 mod script_msg;
39 pub mod webdriver_msg;
40
41 use bluetooth_traits::BluetoothRequest;
42 use canvas_traits::webgl::WebGLPipeline;
43 use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
44 use euclid::{Size2D, Length, Point2D, Vector2D, Rect, TypedScale, TypedSize2D};
45 use gfx_traits::Epoch;
46 use hyper::header::Headers;
47 use hyper::method::Method;
48 use ipc_channel::{Error as IpcError};
49 use ipc_channel::ipc::{IpcReceiver, IpcSender};
50 use libc::c_void;
51 use msg::constellation_msg::{BrowsingContextId, TopLevelBrowsingContextId, Key, KeyModifiers, KeyState};
52 use msg::constellation_msg::{PipelineId, PipelineNamespaceId, TraversalDirection};
53 use net_traits::{FetchResponseMsg, ReferrerPolicy, ResourceThreads};
54 use net_traits::image::base::Image;
55 use net_traits::image::base::PixelFormat;
56 use net_traits::image_cache::ImageCache;
57 use net_traits::storage_thread::StorageType;
58 use profile_traits::mem;
59 use profile_traits::time as profile_time;
60 use serde::{Deserialize, Deserializer, Serialize, Serializer};
61 use servo_atoms::Atom;
62 use servo_url::ImmutableOrigin;
63 use servo_url::ServoUrl;
64 use std::collections::HashMap;
65 use std::fmt;
66 use std::sync::Arc;
67 use std::sync::mpsc::{Receiver, Sender, RecvTimeoutError};
68 use style_traits::CSSPixel;
69 use style_traits::SpeculativePainter;
70 use style_traits::cursor::CursorKind;
71 use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
72 use webrender_api::{ExternalScrollId, DevicePixel, DocumentId, ImageKey};
73 use webvr_traits::{WebVREvent, WebVRMsg};
74
75 pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry};
76 pub use script_msg::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage};
77
78 /// The address of a node. Layout sends these back. They must be validated via
79 /// `from_untrusted_node_address` before they can be used, because we do not trust layout.
80 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
81 pub struct UntrustedNodeAddress(pub *const c_void);
82
83 malloc_size_of_is_0!(UntrustedNodeAddress);
84
85 #[allow(unsafe_code)]
86 unsafe impl Send for UntrustedNodeAddress {}
87
88 impl Serialize for UntrustedNodeAddress {
serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error>89 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
90 (self.0 as usize).serialize(s)
91 }
92 }
93
94 impl<'de> Deserialize<'de> for UntrustedNodeAddress {
deserialize<D: Deserializer<'de>>(d: D) -> Result<UntrustedNodeAddress, D::Error>95 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<UntrustedNodeAddress, D::Error> {
96 let value: usize = Deserialize::deserialize(d)?;
97 Ok(UntrustedNodeAddress::from_id(value))
98 }
99 }
100
101 impl UntrustedNodeAddress {
102 /// Creates an `UntrustedNodeAddress` from the given pointer address value.
103 #[inline]
from_id(id: usize) -> UntrustedNodeAddress104 pub fn from_id(id: usize) -> UntrustedNodeAddress {
105 UntrustedNodeAddress(id as *const c_void)
106 }
107 }
108
109 /// Messages sent to the layout thread from the constellation and/or compositor.
110 #[derive(Deserialize, Serialize)]
111 pub enum LayoutControlMsg {
112 /// Requests that this layout thread exit.
113 ExitNow,
114 /// Requests the current epoch (layout counter) from this layout.
115 GetCurrentEpoch(IpcSender<Epoch>),
116 /// Asks layout to run another step in its animation.
117 TickAnimations,
118 /// Tells layout about the new scrolling offsets of each scrollable stacking context.
119 SetScrollStates(Vec<ScrollState>),
120 /// Requests the current load state of Web fonts. `true` is returned if fonts are still loading
121 /// and `false` is returned if all fonts have loaded.
122 GetWebFontLoadState(IpcSender<bool>),
123 /// Send the paint time for a specific epoch to the layout thread.
124 PaintMetric(Epoch, u64),
125 }
126
127 /// can be passed to `LoadUrl` to load a page with GET/POST
128 /// parameters or headers
129 #[derive(Clone, Debug, Deserialize, Serialize)]
130 pub struct LoadData {
131 /// The URL.
132 pub url: ServoUrl,
133 /// The creator pipeline id if this is an about:blank load.
134 pub creator_pipeline_id: Option<PipelineId>,
135 /// The method.
136 #[serde(deserialize_with = "::hyper_serde::deserialize",
137 serialize_with = "::hyper_serde::serialize")]
138 pub method: Method,
139 /// The headers.
140 #[serde(deserialize_with = "::hyper_serde::deserialize",
141 serialize_with = "::hyper_serde::serialize")]
142 pub headers: Headers,
143 /// The data.
144 pub data: Option<Vec<u8>>,
145 /// The result of evaluating a javascript scheme url.
146 pub js_eval_result: Option<JsEvalResult>,
147 /// The referrer policy.
148 pub referrer_policy: Option<ReferrerPolicy>,
149 /// The referrer URL.
150 pub referrer_url: Option<ServoUrl>,
151 }
152
153 /// The result of evaluating a javascript scheme url.
154 #[derive(Clone, Debug, Deserialize, Serialize)]
155 pub enum JsEvalResult {
156 /// The js evaluation had a non-string result, 204 status code.
157 /// <https://html.spec.whatwg.org/multipage/#navigate> 12.11
158 NoContent,
159 /// The js evaluation had a string result.
160 Ok(Vec<u8>)
161 }
162
163 impl LoadData {
164 /// Create a new `LoadData` object.
new(url: ServoUrl, creator_pipeline_id: Option<PipelineId>, referrer_policy: Option<ReferrerPolicy>, referrer_url: Option<ServoUrl>) -> LoadData165 pub fn new(url: ServoUrl,
166 creator_pipeline_id: Option<PipelineId>,
167 referrer_policy: Option<ReferrerPolicy>,
168 referrer_url: Option<ServoUrl>)
169 -> LoadData {
170 LoadData {
171 url: url,
172 creator_pipeline_id: creator_pipeline_id,
173 method: Method::Get,
174 headers: Headers::new(),
175 data: None,
176 js_eval_result: None,
177 referrer_policy: referrer_policy,
178 referrer_url: referrer_url,
179 }
180 }
181 }
182
183 /// The initial data required to create a new layout attached to an existing script thread.
184 #[derive(Deserialize, Serialize)]
185 pub struct NewLayoutInfo {
186 /// The ID of the parent pipeline and frame type, if any.
187 /// If `None`, this is a root pipeline.
188 pub parent_info: Option<PipelineId>,
189 /// Id of the newly-created pipeline.
190 pub new_pipeline_id: PipelineId,
191 /// Id of the browsing context associated with this pipeline.
192 pub browsing_context_id: BrowsingContextId,
193 /// Id of the top-level browsing context associated with this pipeline.
194 pub top_level_browsing_context_id: TopLevelBrowsingContextId,
195 /// Network request data which will be initiated by the script thread.
196 pub load_data: LoadData,
197 /// Information about the initial window size.
198 pub window_size: Option<WindowSizeData>,
199 /// A port on which layout can receive messages from the pipeline.
200 pub pipeline_port: IpcReceiver<LayoutControlMsg>,
201 /// A shutdown channel so that layout can tell the content process to shut down when it's done.
202 pub content_process_shutdown_chan: Option<IpcSender<()>>,
203 /// Number of threads to use for layout.
204 pub layout_threads: usize,
205 }
206
207 /// When a pipeline is closed, should its browsing context be discarded too?
208 #[derive(Clone, Copy, Deserialize, Eq, Hash, PartialEq, Serialize)]
209 pub enum DiscardBrowsingContext {
210 /// Discard the browsing context
211 Yes,
212 /// Don't discard the browsing context
213 No,
214 }
215
216 /// Is a document fully active, active or inactive?
217 /// A document is active if it is the current active document in its session history,
218 /// it is fuly active if it is active and all of its ancestors are active,
219 /// and it is inactive otherwise.
220 ///
221 /// * <https://html.spec.whatwg.org/multipage/#active-document>
222 /// * <https://html.spec.whatwg.org/multipage/#fully-active>
223 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
224 pub enum DocumentActivity {
225 /// An inactive document
226 Inactive,
227 /// An active but not fully active document
228 Active,
229 /// A fully active document
230 FullyActive,
231 }
232
233 /// Type of recorded progressive web metric
234 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
235 pub enum ProgressiveWebMetricType {
236 /// Time to first Paint
237 FirstPaint,
238 /// Time to first contentful paint
239 FirstContentfulPaint,
240 /// Time to interactive
241 TimeToInteractive,
242 }
243
244 /// The reason why the pipeline id of an iframe is being updated.
245 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
246 pub enum UpdatePipelineIdReason {
247 /// The pipeline id is being updated due to a navigation.
248 Navigation,
249 /// The pipeline id is being updated due to a history traversal.
250 Traversal,
251 }
252
253 /// Messages sent from the constellation or layout to the script thread.
254 #[derive(Deserialize, Serialize)]
255 pub enum ConstellationControlMsg {
256 /// Sends the final response to script thread for fetching after all redirections
257 /// have been resolved
258 NavigationResponse(PipelineId, FetchResponseMsg),
259 /// Gives a channel and ID to a layout thread, as well as the ID of that layout's parent
260 AttachLayout(NewLayoutInfo),
261 /// Window resized. Sends a DOM event eventually, but first we combine events.
262 Resize(PipelineId, WindowSizeData, WindowSizeType),
263 /// Notifies script that window has been resized but to not take immediate action.
264 ResizeInactive(PipelineId, WindowSizeData),
265 /// Notifies the script that a pipeline should be closed.
266 ExitPipeline(PipelineId, DiscardBrowsingContext),
267 /// Notifies the script that the whole thread should be closed.
268 ExitScriptThread,
269 /// Sends a DOM event.
270 SendEvent(PipelineId, CompositorEvent),
271 /// Notifies script of the viewport.
272 Viewport(PipelineId, Rect<f32>),
273 /// Notifies script of a new set of scroll offsets.
274 SetScrollState(PipelineId, Vec<(UntrustedNodeAddress, Vector2D<f32>)>),
275 /// Requests that the script thread immediately send the constellation the title of a pipeline.
276 GetTitle(PipelineId),
277 /// Notifies script thread of a change to one of its document's activity
278 SetDocumentActivity(PipelineId, DocumentActivity),
279 /// Notifies script thread whether frame is visible
280 ChangeFrameVisibilityStatus(PipelineId, bool),
281 /// Notifies script thread that frame visibility change is complete
282 /// PipelineId is for the parent, BrowsingContextId is for the nested browsing context
283 NotifyVisibilityChange(PipelineId, BrowsingContextId, bool),
284 /// Notifies script thread that a url should be loaded in this iframe.
285 /// PipelineId is for the parent, BrowsingContextId is for the nested browsing context
286 Navigate(PipelineId, BrowsingContextId, LoadData, bool),
287 /// Post a message to a given window.
288 PostMessage(PipelineId, Option<ImmutableOrigin>, Vec<u8>),
289 /// Updates the current pipeline ID of a given iframe.
290 /// First PipelineId is for the parent, second is the new PipelineId for the frame.
291 UpdatePipelineId(PipelineId, BrowsingContextId, PipelineId, UpdatePipelineIdReason),
292 /// Set an iframe to be focused. Used when an element in an iframe gains focus.
293 /// PipelineId is for the parent, BrowsingContextId is for the nested browsing context
294 FocusIFrame(PipelineId, BrowsingContextId),
295 /// Passes a webdriver command to the script thread for execution
296 WebDriverScriptCommand(PipelineId, WebDriverScriptCommand),
297 /// Notifies script thread that all animations are done
298 TickAllAnimations(PipelineId),
299 /// Notifies the script thread of a transition end
300 TransitionEnd(UntrustedNodeAddress, String, f64),
301 /// Notifies the script thread that a new Web font has been loaded, and thus the page should be
302 /// reflowed.
303 WebFontLoaded(PipelineId),
304 /// Cause a `load` event to be dispatched at the appropriate iframe element.
305 DispatchIFrameLoadEvent {
306 /// The frame that has been marked as loaded.
307 target: BrowsingContextId,
308 /// The pipeline that contains a frame loading the target pipeline.
309 parent: PipelineId,
310 /// The pipeline that has completed loading.
311 child: PipelineId,
312 },
313 /// Cause a `storage` event to be dispatched at the appropriate window.
314 /// The strings are key, old value and new value.
315 DispatchStorageEvent(PipelineId, StorageType, ServoUrl, Option<String>, Option<String>, Option<String>),
316 /// Report an error from a CSS parser for the given pipeline
317 ReportCSSError(PipelineId, String, u32, u32, String),
318 /// Reload the given page.
319 Reload(PipelineId),
320 /// Notifies the script thread of WebVR events.
321 WebVREvents(PipelineId, Vec<WebVREvent>),
322 /// Notifies the script thread about a new recorded paint metric.
323 PaintMetric(PipelineId, ProgressiveWebMetricType, u64),
324 }
325
326 impl fmt::Debug for ConstellationControlMsg {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result327 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
328 use self::ConstellationControlMsg::*;
329 let variant = match *self {
330 NavigationResponse(..) => "NavigationResponse",
331 AttachLayout(..) => "AttachLayout",
332 Resize(..) => "Resize",
333 ResizeInactive(..) => "ResizeInactive",
334 ExitPipeline(..) => "ExitPipeline",
335 ExitScriptThread => "ExitScriptThread",
336 SendEvent(..) => "SendEvent",
337 Viewport(..) => "Viewport",
338 SetScrollState(..) => "SetScrollState",
339 GetTitle(..) => "GetTitle",
340 SetDocumentActivity(..) => "SetDocumentActivity",
341 ChangeFrameVisibilityStatus(..) => "ChangeFrameVisibilityStatus",
342 NotifyVisibilityChange(..) => "NotifyVisibilityChange",
343 Navigate(..) => "Navigate",
344 PostMessage(..) => "PostMessage",
345 UpdatePipelineId(..) => "UpdatePipelineId",
346 FocusIFrame(..) => "FocusIFrame",
347 WebDriverScriptCommand(..) => "WebDriverScriptCommand",
348 TickAllAnimations(..) => "TickAllAnimations",
349 TransitionEnd(..) => "TransitionEnd",
350 WebFontLoaded(..) => "WebFontLoaded",
351 DispatchIFrameLoadEvent { .. } => "DispatchIFrameLoadEvent",
352 DispatchStorageEvent(..) => "DispatchStorageEvent",
353 ReportCSSError(..) => "ReportCSSError",
354 Reload(..) => "Reload",
355 WebVREvents(..) => "WebVREvents",
356 PaintMetric(..) => "PaintMetric",
357 };
358 write!(formatter, "ConstellationMsg::{}", variant)
359 }
360 }
361
362 /// Used to determine if a script has any pending asynchronous activity.
363 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
364 pub enum DocumentState {
365 /// The document has been loaded and is idle.
366 Idle,
367 /// The document is either loading or waiting on an event.
368 Pending,
369 }
370
371 /// For a given pipeline, whether any animations are currently running
372 /// and any animation callbacks are queued
373 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
374 pub enum AnimationState {
375 /// Animations are active but no callbacks are queued
376 AnimationsPresent,
377 /// Animations are active and callbacks are queued
378 AnimationCallbacksPresent,
379 /// No animations are active and no callbacks are queued
380 NoAnimationsPresent,
381 /// No animations are active but callbacks are queued
382 NoAnimationCallbacksPresent,
383 }
384
385 /// The type of input represented by a multi-touch event.
386 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
387 pub enum TouchEventType {
388 /// A new touch point came in contact with the screen.
389 Down,
390 /// An existing touch point changed location.
391 Move,
392 /// A touch point was removed from the screen.
393 Up,
394 /// The system stopped tracking a touch point.
395 Cancel,
396 }
397
398 /// An opaque identifier for a touch point.
399 ///
400 /// <http://w3c.github.io/touch-events/#widl-Touch-identifier>
401 #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
402 pub struct TouchId(pub i32);
403
404 /// The mouse button involved in the event.
405 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
406 pub enum MouseButton {
407 /// The left mouse button.
408 Left,
409 /// The middle mouse button.
410 Middle,
411 /// The right mouse button.
412 Right,
413 }
414
415 /// The types of mouse events
416 #[derive(Deserialize, MallocSizeOf, Serialize)]
417 pub enum MouseEventType {
418 /// Mouse button clicked
419 Click,
420 /// Mouse button down
421 MouseDown,
422 /// Mouse button up
423 MouseUp,
424 }
425
426 /// Events from the compositor that the script thread needs to know about
427 #[derive(Deserialize, Serialize)]
428 pub enum CompositorEvent {
429 /// The window was resized.
430 ResizeEvent(WindowSizeData, WindowSizeType),
431 /// A mouse button state changed.
432 MouseButtonEvent(
433 MouseEventType,
434 MouseButton,
435 Point2D<f32>,
436 Option<UntrustedNodeAddress>,
437 Option<Point2D<f32>>
438 ),
439 /// The mouse was moved over a point (or was moved out of the recognizable region).
440 MouseMoveEvent(Option<Point2D<f32>>, Option<UntrustedNodeAddress>),
441 /// A touch event was generated with a touch ID and location.
442 TouchEvent(TouchEventType, TouchId, Point2D<f32>, Option<UntrustedNodeAddress>),
443 /// A key was pressed.
444 KeyEvent(Option<char>, Key, KeyState, KeyModifiers),
445 }
446
447 /// Requests a TimerEvent-Message be sent after the given duration.
448 #[derive(Deserialize, Serialize)]
449 pub struct TimerEventRequest(pub IpcSender<TimerEvent>, pub TimerSource, pub TimerEventId, pub MsDuration);
450
451 /// Type of messages that can be sent to the timer scheduler.
452 #[derive(Deserialize, Serialize)]
453 pub enum TimerSchedulerMsg {
454 /// Message to schedule a new timer event.
455 Request(TimerEventRequest),
456 /// Message to exit the timer scheduler.
457 Exit,
458 }
459
460 /// Notifies the script thread to fire due timers.
461 /// `TimerSource` must be `FromWindow` when dispatched to `ScriptThread` and
462 /// must be `FromWorker` when dispatched to a `DedicatedGlobalWorkerScope`
463 #[derive(Debug, Deserialize, Serialize)]
464 pub struct TimerEvent(pub TimerSource, pub TimerEventId);
465
466 /// Describes the thread that requested the TimerEvent.
467 #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
468 pub enum TimerSource {
469 /// The event was requested from a window (ScriptThread).
470 FromWindow(PipelineId),
471 /// The event was requested from a worker (DedicatedGlobalWorkerScope).
472 FromWorker,
473 }
474
475 /// The id to be used for a `TimerEvent` is defined by the corresponding `TimerEventRequest`.
476 #[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
477 pub struct TimerEventId(pub u32);
478
479 /// Unit of measurement.
480 #[derive(Clone, Copy, MallocSizeOf)]
481 pub enum Milliseconds {}
482 /// Unit of measurement.
483 #[derive(Clone, Copy, MallocSizeOf)]
484 pub enum Nanoseconds {}
485
486 /// Amount of milliseconds.
487 pub type MsDuration = Length<u64, Milliseconds>;
488 /// Amount of nanoseconds.
489 pub type NsDuration = Length<u64, Nanoseconds>;
490
491 /// Returns the duration since an unspecified epoch measured in ms.
precise_time_ms() -> MsDuration492 pub fn precise_time_ms() -> MsDuration {
493 Length::new(time::precise_time_ns() / (1000 * 1000))
494 }
495 /// Returns the duration since an unspecified epoch measured in ns.
precise_time_ns() -> NsDuration496 pub fn precise_time_ns() -> NsDuration {
497 Length::new(time::precise_time_ns())
498 }
499
500 /// Data needed to construct a script thread.
501 ///
502 /// NB: *DO NOT* add any Senders or Receivers here! pcwalton will have to rewrite your code if you
503 /// do! Use IPC senders and receivers instead.
504 pub struct InitialScriptState {
505 /// The ID of the pipeline with which this script thread is associated.
506 pub id: PipelineId,
507 /// The subpage ID of this pipeline to create in its pipeline parent.
508 /// If `None`, this is the root.
509 pub parent_info: Option<PipelineId>,
510 /// The ID of the browsing context this script is part of.
511 pub browsing_context_id: BrowsingContextId,
512 /// The ID of the top-level browsing context this script is part of.
513 pub top_level_browsing_context_id: TopLevelBrowsingContextId,
514 /// A channel with which messages can be sent to us (the script thread).
515 pub control_chan: IpcSender<ConstellationControlMsg>,
516 /// A port on which messages sent by the constellation to script can be received.
517 pub control_port: IpcReceiver<ConstellationControlMsg>,
518 /// A channel on which messages can be sent to the constellation from script.
519 pub script_to_constellation_chan: ScriptToConstellationChan,
520 /// A sender for the layout thread to communicate to the constellation.
521 pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
522 /// A channel to schedule timer events.
523 pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
524 /// A channel to the resource manager thread.
525 pub resource_threads: ResourceThreads,
526 /// A channel to the bluetooth thread.
527 pub bluetooth_thread: IpcSender<BluetoothRequest>,
528 /// The image cache for this script thread.
529 pub image_cache: Arc<ImageCache>,
530 /// A channel to the time profiler thread.
531 pub time_profiler_chan: profile_traits::time::ProfilerChan,
532 /// A channel to the memory profiler thread.
533 pub mem_profiler_chan: mem::ProfilerChan,
534 /// A channel to the developer tools, if applicable.
535 pub devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
536 /// Information about the initial window size.
537 pub window_size: Option<WindowSizeData>,
538 /// The ID of the pipeline namespace for this script thread.
539 pub pipeline_namespace_id: PipelineNamespaceId,
540 /// A ping will be sent on this channel once the script thread shuts down.
541 pub content_process_shutdown_chan: IpcSender<()>,
542 /// A channel to the WebGL thread used in this pipeline.
543 pub webgl_chan: Option<WebGLPipeline>,
544 /// A channel to the webvr thread, if available.
545 pub webvr_chan: Option<IpcSender<WebVRMsg>>,
546 /// The Webrender document ID associated with this thread.
547 pub webrender_document: DocumentId,
548 }
549
550 /// This trait allows creating a `ScriptThread` without depending on the `script`
551 /// crate.
552 pub trait ScriptThreadFactory {
553 /// Type of message sent from script to layout.
554 type Message;
555 /// Create a `ScriptThread`.
create(state: InitialScriptState, load_data: LoadData) -> (Sender<Self::Message>, Receiver<Self::Message>)556 fn create(state: InitialScriptState, load_data: LoadData)
557 -> (Sender<Self::Message>, Receiver<Self::Message>);
558 }
559
560 /// Whether the sandbox attribute is present for an iframe element
561 #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
562 pub enum IFrameSandboxState {
563 /// Sandbox attribute is present
564 IFrameSandboxed,
565 /// Sandbox attribute is not present
566 IFrameUnsandboxed,
567 }
568
569 /// Specifies the information required to load an iframe.
570 #[derive(Deserialize, Serialize)]
571 pub struct IFrameLoadInfo {
572 /// Pipeline ID of the parent of this iframe
573 pub parent_pipeline_id: PipelineId,
574 /// The ID for this iframe's nested browsing context.
575 pub browsing_context_id: BrowsingContextId,
576 /// The ID for the top-level ancestor browsing context of this iframe's nested browsing context.
577 pub top_level_browsing_context_id: TopLevelBrowsingContextId,
578 /// The new pipeline ID that the iframe has generated.
579 pub new_pipeline_id: PipelineId,
580 /// Whether this iframe should be considered private
581 pub is_private: bool,
582 /// Wether this load should replace the current entry (reload). If true, the current
583 /// entry will be replaced instead of a new entry being added.
584 pub replace: bool,
585 }
586
587 /// Specifies the information required to load a URL in an iframe.
588 #[derive(Deserialize, Serialize)]
589 pub struct IFrameLoadInfoWithData {
590 /// The information required to load an iframe.
591 pub info: IFrameLoadInfo,
592 /// Load data containing the url to load
593 pub load_data: Option<LoadData>,
594 /// The old pipeline ID for this iframe, if a page was previously loaded.
595 pub old_pipeline_id: Option<PipelineId>,
596 /// Sandbox type of this iframe
597 pub sandbox: IFrameSandboxState,
598 }
599
600 /// Specifies whether the script or layout thread needs to be ticked for animation.
601 #[derive(Deserialize, Serialize)]
602 pub enum AnimationTickType {
603 /// The script thread.
604 Script,
605 /// The layout thread.
606 Layout,
607 }
608
609 /// The scroll state of a stacking context.
610 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
611 pub struct ScrollState {
612 /// The ID of the scroll root.
613 pub scroll_id: ExternalScrollId,
614 /// The scrolling offset of this stacking context.
615 pub scroll_offset: Vector2D<f32>,
616 }
617
618 /// Data about the window size.
619 #[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
620 pub struct WindowSizeData {
621 /// The size of the initial layout viewport, before parsing an
622 /// <http://www.w3.org/TR/css-device-adapt/#initial-viewport>
623 pub initial_viewport: TypedSize2D<f32, CSSPixel>,
624
625 /// The resolution of the window in dppx, not including any "pinch zoom" factor.
626 pub device_pixel_ratio: TypedScale<f32, CSSPixel, DevicePixel>,
627 }
628
629 /// The type of window size change.
630 #[derive(Clone, Copy, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
631 pub enum WindowSizeType {
632 /// Initial load.
633 Initial,
634 /// Window resize.
635 Resize,
636 }
637
638 /// Messages to the constellation originating from the WebDriver server.
639 #[derive(Deserialize, Serialize)]
640 pub enum WebDriverCommandMsg {
641 /// Get the window size.
642 GetWindowSize(TopLevelBrowsingContextId, IpcSender<WindowSizeData>),
643 /// Load a URL in the top-level browsing context with the given ID.
644 LoadUrl(TopLevelBrowsingContextId, LoadData, IpcSender<LoadStatus>),
645 /// Refresh the top-level browsing context with the given ID.
646 Refresh(TopLevelBrowsingContextId, IpcSender<LoadStatus>),
647 /// Pass a webdriver command to the script thread of the current pipeline
648 /// of a browsing context.
649 ScriptCommand(BrowsingContextId, WebDriverScriptCommand),
650 /// Act as if keys were pressed in the browsing context with the given ID.
651 SendKeys(BrowsingContextId, Vec<(Key, KeyModifiers, KeyState)>),
652 /// Set the window size.
653 SetWindowSize(TopLevelBrowsingContextId, Size2D<u32>, IpcSender<WindowSizeData>),
654 /// Take a screenshot of the window.
655 TakeScreenshot(TopLevelBrowsingContextId, IpcSender<Option<Image>>),
656 }
657
658 /// Messages to the constellation.
659 #[derive(Deserialize, Serialize)]
660 pub enum ConstellationMsg {
661 /// Exit the constellation.
662 Exit,
663 /// Request that the constellation send the BrowsingContextId corresponding to the document
664 /// with the provided pipeline id
665 GetBrowsingContext(PipelineId, IpcSender<Option<BrowsingContextId>>),
666 /// Request that the constellation send the current pipeline id for the provided
667 /// browsing context id, over a provided channel.
668 GetPipeline(BrowsingContextId, IpcSender<Option<PipelineId>>),
669 /// Request that the constellation send the current focused top-level browsing context id,
670 /// over a provided channel.
671 GetFocusTopLevelBrowsingContext(IpcSender<Option<TopLevelBrowsingContextId>>),
672 /// Query the constellation to see if the current compositor output is stable
673 IsReadyToSaveImage(HashMap<PipelineId, Epoch>),
674 /// Inform the constellation of a key event.
675 KeyEvent(Option<char>, Key, KeyState, KeyModifiers),
676 /// Request to load a page.
677 LoadUrl(TopLevelBrowsingContextId, ServoUrl),
678 /// Request to traverse the joint session history of the provided browsing context.
679 TraverseHistory(TopLevelBrowsingContextId, TraversalDirection),
680 /// Inform the constellation of a window being resized.
681 WindowSize(Option<TopLevelBrowsingContextId>, WindowSizeData, WindowSizeType),
682 /// Requests that the constellation instruct layout to begin a new tick of the animation.
683 TickAnimation(PipelineId, AnimationTickType),
684 /// Dispatch a webdriver command
685 WebDriverCommand(WebDriverCommandMsg),
686 /// Reload a top-level browsing context.
687 Reload(TopLevelBrowsingContextId),
688 /// A log entry, with the top-level browsing context id and thread name
689 LogEntry(Option<TopLevelBrowsingContextId>, Option<String>, LogEntry),
690 /// Dispatch WebVR events to the subscribed script threads.
691 WebVREvents(Vec<PipelineId>, Vec<WebVREvent>),
692 /// Create a new top level browsing context.
693 NewBrowser(ServoUrl, IpcSender<TopLevelBrowsingContextId>),
694 /// Close a top level browsing context.
695 CloseBrowser(TopLevelBrowsingContextId),
696 /// Make browser visible.
697 SelectBrowser(TopLevelBrowsingContextId),
698 /// Forward an event to the script task of the given pipeline.
699 ForwardEvent(PipelineId, CompositorEvent),
700 /// Requesting a change to the onscreen cursor.
701 SetCursor(CursorKind),
702 }
703
704 /// Resources required by workerglobalscopes
705 #[derive(Clone, Deserialize, Serialize)]
706 pub struct WorkerGlobalScopeInit {
707 /// Chan to a resource thread
708 pub resource_threads: ResourceThreads,
709 /// Chan to the memory profiler
710 pub mem_profiler_chan: mem::ProfilerChan,
711 /// Chan to the time profiler
712 pub time_profiler_chan: profile_time::ProfilerChan,
713 /// To devtools sender
714 pub to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
715 /// From devtools sender
716 pub from_devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
717 /// Messages to send to constellation
718 pub script_to_constellation_chan: ScriptToConstellationChan,
719 /// Message to send to the scheduler
720 pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
721 /// The worker id
722 pub worker_id: WorkerId,
723 /// The pipeline id
724 pub pipeline_id: PipelineId,
725 /// The origin
726 pub origin: ImmutableOrigin,
727 }
728
729 /// Common entities representing a network load origin
730 #[derive(Clone, Deserialize, Serialize)]
731 pub struct WorkerScriptLoadOrigin {
732 /// referrer url
733 pub referrer_url: Option<ServoUrl>,
734 /// the referrer policy which is used
735 pub referrer_policy: Option<ReferrerPolicy>,
736 /// the pipeline id of the entity requesting the load
737 pub pipeline_id: Option<PipelineId>,
738 }
739
740 /// Errors from executing a paint worklet
741 #[derive(Clone, Debug, Deserialize, Serialize)]
742 pub enum PaintWorkletError {
743 /// Execution timed out.
744 Timeout,
745 /// No such worklet.
746 WorkletNotFound,
747 }
748
749 impl From<RecvTimeoutError> for PaintWorkletError {
from(_: RecvTimeoutError) -> PaintWorkletError750 fn from(_: RecvTimeoutError) -> PaintWorkletError {
751 PaintWorkletError::Timeout
752 }
753 }
754
755 /// Execute paint code in the worklet thread pool.
756 pub trait Painter: SpeculativePainter {
757 /// <https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image>
draw_a_paint_image(&self, size: TypedSize2D<f32, CSSPixel>, zoom: TypedScale<f32, CSSPixel, DevicePixel>, properties: Vec<(Atom, String)>, arguments: Vec<String>) -> Result<DrawAPaintImageResult, PaintWorkletError>758 fn draw_a_paint_image(&self,
759 size: TypedSize2D<f32, CSSPixel>,
760 zoom: TypedScale<f32, CSSPixel, DevicePixel>,
761 properties: Vec<(Atom, String)>,
762 arguments: Vec<String>)
763 -> Result<DrawAPaintImageResult, PaintWorkletError>;
764 }
765
766 impl fmt::Debug for Painter {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result767 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
768 fmt.debug_tuple("Painter").field(&format_args!("..")).finish()
769 }
770 }
771
772 /// The result of executing paint code: the image together with any image URLs that need to be loaded.
773 ///
774 /// TODO: this should return a WR display list. <https://github.com/servo/servo/issues/17497>
775 #[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
776 pub struct DrawAPaintImageResult {
777 /// The image height
778 pub width: u32,
779 /// The image width
780 pub height: u32,
781 /// The image format
782 pub format: PixelFormat,
783 /// The image drawn, or None if an invalid paint image was drawn
784 pub image_key: Option<ImageKey>,
785 /// Drawing the image might have requested loading some image URLs.
786 pub missing_image_urls: Vec<ServoUrl>,
787 }
788
789 /// A Script to Constellation channel.
790 #[derive(Clone, Deserialize, Serialize)]
791 pub struct ScriptToConstellationChan {
792 /// Sender for communicating with constellation thread.
793 pub sender: IpcSender<(PipelineId, ScriptMsg)>,
794 /// Used to identify the origin of the message.
795 pub pipeline_id: PipelineId,
796 }
797
798 impl ScriptToConstellationChan {
799 /// Send ScriptMsg and attach the pipeline_id to the message.
send(&self, msg: ScriptMsg) -> Result<(), IpcError>800 pub fn send(&self, msg: ScriptMsg) -> Result<(), IpcError> {
801 self.sender.send((self.pipeline_id, msg))
802 }
803 }
804