aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/document.rs4
-rw-r--r--components/script/dom/webidls/Window.webidl2
-rw-r--r--components/script/dom/window.rs88
3 files changed, 92 insertions, 2 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index e70501d3711..9366f9e18bb 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -349,6 +349,10 @@ impl Document {
true
}
+ pub fn origin(&self) -> &Origin {
+ &self.origin
+ }
+
// https://dom.spec.whatwg.org/#concept-document-url
pub fn url(&self) -> &Url {
&self.url
diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl
index 651c7081305..7057a4541a6 100644
--- a/components/script/dom/webidls/Window.webidl
+++ b/components/script/dom/webidls/Window.webidl
@@ -54,6 +54,8 @@
void cancelAnimationFrame(unsigned long handle);
//void postMessage(any message, DOMString targetOrigin, optional sequence<Transferable> transfer);
+ [Throws]
+ void postMessage(any message, DOMString targetOrigin);
// also has obsolete members
};
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index ebd9550d117..c25c826b4ec 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -19,8 +19,10 @@ use dom::bindings::global::{GlobalRef, global_root_from_object};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::num::Finite;
+use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::Reflectable;
use dom::bindings::str::DOMString;
+use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler};
use dom::browsingcontext::BrowsingContext;
use dom::console::Console;
@@ -33,6 +35,7 @@ use dom::eventtarget::EventTarget;
use dom::history::History;
use dom::htmliframeelement::build_mozbrowser_custom_event;
use dom::location::Location;
+use dom::messageevent::MessageEvent;
use dom::navigator::Navigator;
use dom::node::{Node, from_untrusted_node_address, window_from_node};
use dom::performance::Performance;
@@ -43,6 +46,7 @@ use gfx_traits::LayerId;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{Evaluate2, HandleObject, HandleValue, JSAutoCompartment, JSContext};
use js::jsapi::{JS_GetRuntime, JS_GC, MutableHandleValue, SetWindowProxy};
+use js::jsval::UndefinedValue;
use js::rust::CompileOptionsWrapper;
use js::rust::Runtime;
use libc;
@@ -53,6 +57,7 @@ use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::storage_thread::StorageType;
use num_traits::ToPrimitive;
use open;
+use origin::Origin;
use profile_traits::mem;
use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
use profile_traits::time::{ProfilerChan, TimerMetadataReflowType, profile};
@@ -62,9 +67,9 @@ use script_layout_interface::message::{Msg, Reflow, ReflowQueryType, ScriptReflo
use script_layout_interface::reporter::CSSErrorReporter;
use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC};
use script_layout_interface::rpc::{MarginStyleResponse, ResolvedStyleResponse};
-use script_runtime::{ScriptChan, ScriptPort, maybe_take_panic_result};
+use script_runtime::{ScriptChan, ScriptPort, CommonScriptMsg, ScriptThreadEventCategory, maybe_take_panic_result};
use script_thread::SendableMainThreadScriptChan;
-use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
+use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper, Runnable};
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use script_traits::{ConstellationControlMsg, MozBrowserEvent, UntrustedNodeAddress};
use script_traits::{DocumentState, MsDuration, TimerEvent, TimerEventId};
@@ -650,6 +655,38 @@ impl WindowMethods for Window {
doc.cancel_animation_frame(ident);
}
+ // https://html.spec.whatwg.org/multipage/#dom-window-postmessage
+ fn PostMessage(&self,
+ cx: *mut JSContext,
+ message: HandleValue,
+ origin: DOMString)
+ -> ErrorResult {
+ // Step 3-5.
+ let origin = match &origin[..] {
+ "*" => None,
+ "/" => {
+ // TODO(#12715): Should be the origin of the incumbent settings
+ // object, not self's.
+ Some(self.Document().origin().copy())
+ },
+ url => match Url::parse(&url) {
+ Ok(url) => Some(Origin::new(&url)),
+ 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.
+ let runnable = PostMessageHandler::new(self, origin, data);
+ let msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::DomEvent, box runnable);
+ // TODO(#12718): Use the "posted message task source".
+ let _ = self.script_chan.send(msg);
+ Ok(())
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-window-captureevents
fn CaptureEvents(&self) {
// This method intentionally does nothing
@@ -1767,3 +1804,50 @@ fn debug_reflow_events(id: PipelineId, goal: &ReflowGoal, query_type: &ReflowQue
println!("{}", debug_msg);
}
+
+struct PostMessageHandler {
+ destination: Trusted<Window>,
+ origin: Option<Origin>,
+ message: StructuredCloneData,
+}
+
+impl PostMessageHandler {
+ fn new(window: &Window,
+ origin: Option<Origin>,
+ message: StructuredCloneData) -> PostMessageHandler {
+ PostMessageHandler {
+ destination: Trusted::new(window),
+ origin: origin,
+ message: message,
+ }
+ }
+}
+
+impl Runnable for PostMessageHandler {
+ // https://html.spec.whatwg.org/multipage/#dom-window-postmessage steps 10-12.
+ fn handler(self: Box<PostMessageHandler>) {
+ let this = *self;
+ let window = this.destination.root();
+
+ // Step 10.
+ let doc = window.Document();
+ if let Some(source) = this.origin {
+ if !source.same_origin(doc.origin()) {
+ return;
+ }
+ }
+
+ let cx = window.get_cx();
+ let globalhandle = window.reflector().get_jsobject();
+ let _ac = JSAutoCompartment::new(cx, globalhandle.get());
+
+ rooted!(in(cx) let mut message = UndefinedValue());
+ this.message.read(GlobalRef::Window(&*window), message.handle_mut());
+
+ // Step 11-12.
+ // TODO(#12719): set the other attributes.
+ MessageEvent::dispatch_jsval(window.upcast(),
+ GlobalRef::Window(&*window),
+ message.handle());
+ }
+}