diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/document.rs | 4 | ||||
-rw-r--r-- | components/script/dom/webidls/Window.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/window.rs | 88 |
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()); + } +} |