aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/window.rs')
-rw-r--r--components/script/dom/window.rs147
1 files changed, 100 insertions, 47 deletions
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 7f3b6d1fb8d..37b5b5e3b2c 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -13,11 +13,10 @@ use crate::dom::bindings::codegen::Bindings::MediaQueryListBinding::MediaQueryLi
use crate::dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionState;
use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use crate::dom::bindings::codegen::Bindings::WindowBinding::{
- self, FrameRequestCallback, WindowMethods,
+ self, FrameRequestCallback, WindowMethods, WindowPostMessageOptions,
};
use crate::dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
use crate::dom::bindings::codegen::UnionTypes::RequestOrUSVString;
-use crate::dom::bindings::conversions::ToJSValConvertible;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
@@ -25,7 +24,7 @@ use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
-use crate::dom::bindings::structuredclone::StructuredCloneData;
+use crate::dom::bindings::structuredclone;
use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::bindings::utils::{GlobalStaticData, WindowProxyHandler};
use crate::dom::bindings::weakref::DOMTracker;
@@ -44,7 +43,6 @@ use crate::dom::location::Location;
use crate::dom::mediaquerylist::{MediaQueryList, MediaQueryListMatchState};
use crate::dom::mediaquerylistevent::MediaQueryListEvent;
use crate::dom::messageevent::MessageEvent;
-use crate::dom::messageport::TRANSFERRED_MESSAGE_PORTS;
use crate::dom::navigator::Navigator;
use crate::dom::node::{document_from_node, from_untrusted_node_address, Node, NodeDamage};
use crate::dom::performance::Performance;
@@ -81,6 +79,7 @@ use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use ipc_channel::ipc::{channel, IpcSender};
use ipc_channel::router::ROUTER;
+use js::jsapi::Heap;
use js::jsapi::JSAutoRealm;
use js::jsapi::JSObject;
use js::jsapi::JSPROP_ENUMERATE;
@@ -88,7 +87,7 @@ use js::jsapi::{GCReason, JS_GC};
use js::jsval::UndefinedValue;
use js::jsval::{JSVal, NullValue};
use js::rust::wrappers::JS_DefineProperty;
-use js::rust::{CustomAutoRooterGuard, HandleValue};
+use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
use media::WindowGLContext;
use msg::constellation_msg::PipelineId;
use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse};
@@ -107,7 +106,10 @@ use script_layout_interface::rpc::{
use script_layout_interface::{PendingImageState, TrustedNodeAddress};
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use script_traits::{ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData};
-use script_traits::{ScriptMsg, ScriptToConstellationChan, ScrollState, TimerEvent, TimerEventId};
+use script_traits::{
+ ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEvent,
+ TimerEventId,
+};
use script_traits::{TimerSchedulerMsg, WindowSizeData, WindowSizeType};
use selectors::attr::CaseSensitivity;
use servo_geometry::{f32_rect_to_au_rect, MaxRect};
@@ -976,31 +978,53 @@ impl WindowMethods for Window {
&self,
cx: JSContext,
message: HandleValue,
- origin: USVString,
- transfer: CustomAutoRooterGuard<Option<Vec<*mut JSObject>>>,
+ target_origin: USVString,
+ mut transfer: CustomAutoRooterGuard<Option<Vec<*mut JSObject>>>,
) -> ErrorResult {
- let source_global = GlobalScope::incumbent().expect("no incumbent global??");
- let source = source_global.as_window();
+ let incumbent = GlobalScope::incumbent().expect("no incumbent global?");
+ let source = incumbent.as_window();
+ let source_origin = source.Document().origin().immutable().clone();
+
+ if transfer.is_some() {
+ let mut rooted = CustomAutoRooter::new(transfer.take().unwrap());
+ let transfer = Some(CustomAutoRooterGuard::new(*cx, &mut rooted));
+ self.post_message_impl(&target_origin, source_origin, source, cx, message, transfer)
+ } else {
+ self.post_message_impl(&target_origin, source_origin, source, cx, message, None)
+ }
+ }
- // Step 3-5.
- let origin = match &origin.0[..] {
- "*" => None,
- "/" => Some(source.Document().origin().immutable().clone()),
- url => match ServoUrl::parse(&url) {
- Ok(url) => Some(url.origin().clone()),
- Err(_) => return Err(Error::Syntax),
- },
- };
+ /// <https://html.spec.whatwg.org/multipage/#dom-messageport-postmessage>
+ fn PostMessage_(
+ &self,
+ cx: JSContext,
+ message: HandleValue,
+ options: RootedTraceableBox<WindowPostMessageOptions>,
+ ) -> ErrorResult {
+ let mut rooted = CustomAutoRooter::new(
+ options
+ .transfer
+ .as_ref()
+ .unwrap_or(&Vec::with_capacity(0))
+ .iter()
+ .map(|js: &RootedTraceableBox<Heap<*mut JSObject>>| js.get())
+ .collect(),
+ );
+ let transfer = Some(CustomAutoRooterGuard::new(*cx, &mut rooted));
- // Step 1-2, 6-8.
- rooted!(in(*cx) let mut val = UndefinedValue());
- (*transfer).as_ref().unwrap_or(&Vec::new()).to_jsval(*cx, val.handle_mut());
+ let incumbent = GlobalScope::incumbent().expect("no incumbent global?");
+ let source = incumbent.as_window();
- let data = StructuredCloneData::write(*cx, message, val.handle())?;
+ let source_origin = source.Document().origin().immutable().clone();
- // Step 9.
- self.post_message(origin, &*source.window_proxy(), data);
- Ok(())
+ self.post_message_impl(
+ &options.targetOrigin,
+ source_origin,
+ source,
+ cx,
+ message,
+ transfer,
+ )
}
// https://html.spec.whatwg.org/multipage/#dom-window-captureevents
@@ -1298,6 +1322,34 @@ impl WindowMethods for Window {
}
impl Window {
+ /// https://html.spec.whatwg.org/multipage/#window-post-message-steps
+ fn post_message_impl(
+ &self,
+ target_origin: &USVString,
+ source_origin: ImmutableOrigin,
+ source: &Window,
+ cx: JSContext,
+ message: HandleValue,
+ transfer: Option<CustomAutoRooterGuard<Vec<*mut JSObject>>>,
+ ) -> ErrorResult {
+ // Step 1-2, 6-8.
+ let data = structuredclone::write(cx, message, transfer)?;
+
+ // Step 3-5.
+ let target_origin = match target_origin.0[..].as_ref() {
+ "*" => None,
+ "/" => Some(source_origin.clone()),
+ url => match ServoUrl::parse(&url) {
+ Ok(url) => Some(url.origin().clone()),
+ Err(_) => return Err(Error::Syntax),
+ },
+ };
+
+ // Step 9.
+ self.post_message(target_origin, source_origin, &*source.window_proxy(), data);
+ Ok(())
+ }
+
// https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet
pub fn paint_worklet(&self) -> DomRoot<Worklet> {
self.paint_worklet.or_init(|| self.new_paint_worklet())
@@ -1344,6 +1396,9 @@ impl Window {
// thread, informing it that it can safely free the memory.
self.Document().upcast::<Node>().teardown();
+ // Tell the constellation to drop the sender to our message-port router, if there is any.
+ self.upcast::<GlobalScope>().remove_message_ports_router();
+
// Clean up any active promises
// https://github.com/servo/servo/issues/15318
if let Some(custom_elements) = self.custom_element_registry.get() {
@@ -2345,8 +2400,9 @@ impl Window {
pub fn post_message(
&self,
target_origin: Option<ImmutableOrigin>,
+ source_origin: ImmutableOrigin,
source: &WindowProxy,
- serialize_with_transfer_result: StructuredCloneData,
+ data: StructuredSerializedData,
) {
let this = Trusted::new(self);
let source = Trusted::new(source);
@@ -2367,26 +2423,23 @@ impl Window {
let obj = this.reflector().get_jsobject();
let _ac = JSAutoRealm::new(*cx, obj.get());
rooted!(in(*cx) let mut message_clone = UndefinedValue());
- assert!(serialize_with_transfer_result.read(
- this.upcast(),
- message_clone.handle_mut(),
- ));
-
- // Step 7.6.
- let new_ports = TRANSFERRED_MESSAGE_PORTS.with(|list| {
- mem::replace(&mut *list.borrow_mut(), vec![])
- });
-
- // Step 7.7.
- // TODO(#12719): Set the other attributes.
- MessageEvent::dispatch_jsval(
- this.upcast(),
- this.upcast(),
- message_clone.handle(),
- Some(&document.origin().immutable().ascii_serialization()),
- Some(&*source),
- new_ports,
- );
+ if let Ok(ports) = structuredclone::read(this.upcast(), data, message_clone.handle_mut()) {
+ // Step 7.6, 7.7
+ MessageEvent::dispatch_jsval(
+ this.upcast(),
+ this.upcast(),
+ message_clone.handle(),
+ Some(&source_origin.ascii_serialization()),
+ Some(&*source),
+ ports,
+ );
+ } else {
+ // Step 4, fire messageerror.
+ MessageEvent::dispatch_error(
+ this.upcast(),
+ this.upcast(),
+ );
+ }
});
// FIXME(nox): Why are errors silenced here?
// TODO(#12718): Use the "posted message task source".