aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/dissimilaroriginwindow.rs
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-10 17:24:27 +0900
committeryvt <i@yvt.jp>2021-07-10 17:55:42 +0900
commit01a7de50ab1843d85295f9dccad7f4c099e7208c (patch)
treeee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/dissimilaroriginwindow.rs
parentff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff)
parent94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff)
downloadservo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz
servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html` was reverted to the upstream version.
Diffstat (limited to 'components/script/dom/dissimilaroriginwindow.rs')
-rw-r--r--components/script/dom/dissimilaroriginwindow.rs229
1 files changed, 143 insertions, 86 deletions
diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs
index 0c367d8d21f..adba29c23fb 100644
--- a/components/script/dom/dissimilaroriginwindow.rs
+++ b/components/script/dom/dissimilaroriginwindow.rs
@@ -1,25 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding;
-use dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding::DissimilarOriginWindowMethods;
-use dom::bindings::error::{Error, ErrorResult};
-use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableJS, Root};
-use dom::bindings::str::DOMString;
-use dom::bindings::structuredclone::StructuredCloneData;
-use dom::browsingcontext::BrowsingContext;
-use dom::dissimilaroriginlocation::DissimilarOriginLocation;
-use dom::globalscope::GlobalScope;
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding;
+use crate::dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding::DissimilarOriginWindowMethods;
+use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowPostMessageOptions;
+use crate::dom::bindings::error::{Error, ErrorResult};
+use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
+use crate::dom::bindings::str::USVString;
+use crate::dom::bindings::structuredclone;
+use crate::dom::bindings::trace::RootedTraceableBox;
+use crate::dom::dissimilaroriginlocation::DissimilarOriginLocation;
+use crate::dom::globalscope::GlobalScope;
+use crate::dom::windowproxy::WindowProxy;
+use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
-use ipc_channel::ipc;
-use js::jsapi::{JSContext, HandleValue};
+use js::jsapi::{Heap, JSObject};
use js::jsval::{JSVal, UndefinedValue};
+use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
use msg::constellation_msg::PipelineId;
-use script_traits::ScriptMsg as ConstellationMsg;
-use servo_url::ImmutableOrigin;
-use servo_url::MutableOrigin;
+use script_traits::{ScriptMsg, StructuredSerializedData};
use servo_url::ServoUrl;
/// Represents a dissimilar-origin `Window` that exists in another script thread.
@@ -28,7 +28,7 @@ use servo_url::ServoUrl;
/// directly, but some of its accessors (for example `window.parent`)
/// still need to function.
///
-/// In `browsingcontext.rs`, we create a custom window proxy for these windows,
+/// In `windowproxy.rs`, we create a custom window proxy for these windows,
/// that throws security exceptions for most accessors. This is not a replacement
/// for XOWs, but provides belt-and-braces security.
#[dom_struct]
@@ -36,80 +36,86 @@ pub struct DissimilarOriginWindow {
/// The global for this window.
globalscope: GlobalScope,
- /// The browsing context this window is part of.
- browsing_context: JS<BrowsingContext>,
+ /// The window proxy for this window.
+ window_proxy: Dom<WindowProxy>,
/// The location of this window, initialized lazily.
- location: MutNullableJS<DissimilarOriginLocation>,
+ location: MutNullableDom<DissimilarOriginLocation>,
}
impl DissimilarOriginWindow {
#[allow(unsafe_code)]
- pub fn new(global_to_clone_from: &GlobalScope, browsing_context: &BrowsingContext) -> Root<DissimilarOriginWindow> {
+ pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> DomRoot<Self> {
let cx = global_to_clone_from.get_cx();
- // Any timer events fired on this window are ignored.
- let (timer_event_chan, _) = ipc::channel().unwrap();
- let win = box DissimilarOriginWindow {
- globalscope: GlobalScope::new_inherited(PipelineId::new(),
- global_to_clone_from.devtools_chan().cloned(),
- global_to_clone_from.mem_profiler_chan().clone(),
- global_to_clone_from.time_profiler_chan().clone(),
- global_to_clone_from.constellation_chan().clone(),
- global_to_clone_from.scheduler_chan().clone(),
- global_to_clone_from.resource_threads().clone(),
- timer_event_chan,
- global_to_clone_from.origin().clone()),
- browsing_context: JS::from_ref(browsing_context),
- location: MutNullableJS::new(None),
- };
+ let win = Box::new(Self {
+ globalscope: GlobalScope::new_inherited(
+ PipelineId::new(),
+ global_to_clone_from.devtools_chan().cloned(),
+ global_to_clone_from.mem_profiler_chan().clone(),
+ global_to_clone_from.time_profiler_chan().clone(),
+ global_to_clone_from.script_to_constellation_chan().clone(),
+ global_to_clone_from.scheduler_chan().clone(),
+ global_to_clone_from.resource_threads().clone(),
+ global_to_clone_from.origin().clone(),
+ global_to_clone_from.creation_url().clone(),
+ // FIXME(nox): The microtask queue is probably not important
+ // here, but this whole DOM interface is a hack anyway.
+ global_to_clone_from.microtask_queue().clone(),
+ global_to_clone_from.is_headless(),
+ global_to_clone_from.get_user_agent(),
+ global_to_clone_from.wgpu_id_hub(),
+ Some(global_to_clone_from.is_secure_context()),
+ ),
+ window_proxy: Dom::from_ref(window_proxy),
+ location: Default::default(),
+ });
unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) }
}
- #[allow(dead_code)]
- pub fn origin(&self) -> &MutableOrigin {
- self.globalscope.origin()
+ pub fn window_proxy(&self) -> DomRoot<WindowProxy> {
+ DomRoot::from_ref(&*self.window_proxy)
}
}
impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
// https://html.spec.whatwg.org/multipage/#dom-window
- fn Window(&self) -> Root<BrowsingContext> {
- Root::from_ref(&*self.browsing_context)
+ fn Window(&self) -> DomRoot<WindowProxy> {
+ self.window_proxy()
}
// https://html.spec.whatwg.org/multipage/#dom-self
- fn Self_(&self) -> Root<BrowsingContext> {
- Root::from_ref(&*self.browsing_context)
+ fn Self_(&self) -> DomRoot<WindowProxy> {
+ self.window_proxy()
}
// https://html.spec.whatwg.org/multipage/#dom-frames
- fn Frames(&self) -> Root<BrowsingContext> {
+ fn Frames(&self) -> DomRoot<WindowProxy> {
println!("calling cross origin frames");
- Root::from_ref(&*self.browsing_context)
+ self.window_proxy()
}
// https://html.spec.whatwg.org/multipage/#dom-parent
- fn GetParent(&self) -> Option<Root<BrowsingContext>> {
+ fn GetParent(&self) -> Option<DomRoot<WindowProxy>> {
// Steps 1-3.
- if self.browsing_context.is_discarded() {
+ if self.window_proxy.is_browsing_context_discarded() {
return None;
}
// Step 4.
- if let Some(parent) = self.browsing_context.parent() {
- return Some(Root::from_ref(parent));
+ if let Some(parent) = self.window_proxy.parent() {
+ return Some(DomRoot::from_ref(parent));
}
// Step 5.
- Some(Root::from_ref(&*self.browsing_context))
+ Some(DomRoot::from_ref(&*self.window_proxy))
}
// https://html.spec.whatwg.org/multipage/#dom-top
- fn GetTop(&self) -> Option<Root<BrowsingContext>> {
+ fn GetTop(&self) -> Option<DomRoot<WindowProxy>> {
// Steps 1-3.
- if self.browsing_context.is_discarded() {
+ if self.window_proxy.is_browsing_context_discarded() {
return None;
}
// Steps 4-5.
- Some(Root::from_ref(self.browsing_context.top()))
+ Some(DomRoot::from_ref(self.window_proxy.top()))
}
// https://html.spec.whatwg.org/multipage/#dom-length
@@ -129,41 +135,45 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
false
}
- #[allow(unsafe_code)]
- // https://html.spec.whatwg.org/multipage/#dom-window-postmessage
- unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue, origin: DOMString) -> ErrorResult {
- // Step 3-5.
- let origin = match &origin[..] {
- "*" => None,
- "/" => {
- // TODO: Should be the origin of the incumbent settings object.
- None
- },
- url => match ServoUrl::parse(&url) {
- Ok(url) => Some(url.origin()),
- Err(_) => return Err(Error::Syntax),
- }
- };
-
- // Step 1-2, 6-8.
- // TODO(#12717): Should implement the `transfer` argument.
- let data = try!(StructuredCloneData::write(cx, message));
-
- // Step 9.
- self.post_message(origin, data);
- Ok(())
+ /// https://html.spec.whatwg.org/multipage/#dom-window-postmessage
+ fn PostMessage(
+ &self,
+ cx: JSContext,
+ message: HandleValue,
+ target_origin: USVString,
+ transfer: CustomAutoRooterGuard<Vec<*mut JSObject>>,
+ ) -> ErrorResult {
+ self.post_message_impl(&target_origin, cx, message, transfer)
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#dom-window-postmessage-options
+ fn PostMessage_(
+ &self,
+ cx: JSContext,
+ message: HandleValue,
+ options: RootedTraceableBox<WindowPostMessageOptions>,
+ ) -> ErrorResult {
+ let mut rooted = CustomAutoRooter::new(
+ options
+ .parent
+ .transfer
+ .iter()
+ .map(|js: &RootedTraceableBox<Heap<*mut JSObject>>| js.get())
+ .collect(),
+ );
+ let transfer = CustomAutoRooterGuard::new(*cx, &mut rooted);
+
+ self.post_message_impl(&options.targetOrigin, cx, message, transfer)
}
- #[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-opener
- unsafe fn Opener(&self, _: *mut JSContext) -> JSVal {
+ fn Opener(&self, _: JSContext) -> JSVal {
// TODO: Implement x-origin opener
UndefinedValue()
}
- #[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-opener
- unsafe fn SetOpener(&self, _: *mut JSContext, _: HandleValue) {
+ fn SetOpener(&self, _: JSContext, _: HandleValue) {
// TODO: Implement x-origin opener
}
@@ -178,14 +188,61 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
}
// https://html.spec.whatwg.org/multipage/#dom-location
- fn Location(&self) -> Root<DissimilarOriginLocation> {
- self.location.or_init(|| DissimilarOriginLocation::new(self))
+ fn Location(&self) -> DomRoot<DissimilarOriginLocation> {
+ self.location
+ .or_init(|| DissimilarOriginLocation::new(self))
}
}
impl DissimilarOriginWindow {
- pub fn post_message(&self, origin: Option<ImmutableOrigin>, data: StructuredCloneData) {
- let msg = ConstellationMsg::PostMessage(self.browsing_context.frame_id(), origin, data.move_to_arraybuffer());
- let _ = self.upcast::<GlobalScope>().constellation_chan().send(msg);
+ /// https://html.spec.whatwg.org/multipage/#window-post-message-steps
+ fn post_message_impl(
+ &self,
+ target_origin: &USVString,
+ cx: JSContext,
+ message: HandleValue,
+ transfer: CustomAutoRooterGuard<Vec<*mut JSObject>>,
+ ) -> ErrorResult {
+ // Step 6-7.
+ let data = structuredclone::write(cx, message, Some(transfer))?;
+
+ self.post_message(target_origin, data)
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#window-post-message-steps
+ pub fn post_message(
+ &self,
+ target_origin: &USVString,
+ data: StructuredSerializedData,
+ ) -> ErrorResult {
+ // Step 1.
+ let target = self.window_proxy.browsing_context_id();
+ // Step 2.
+ let incumbent = match GlobalScope::incumbent() {
+ None => panic!("postMessage called with no incumbent global"),
+ Some(incumbent) => incumbent,
+ };
+
+ let source_origin = incumbent.origin().immutable().clone();
+
+ // 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),
+ },
+ };
+ let msg = ScriptMsg::PostMessage {
+ target,
+ source: incumbent.pipeline_id(),
+ source_origin,
+ target_origin,
+ data: data,
+ };
+ // Step 8
+ let _ = incumbent.script_to_constellation_chan().send(msg);
+ Ok(())
}
}