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