mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Provide the source window as part of postMessage events.
This commit is contained in:
parent
212ae3b94a
commit
45619db0ba
12 changed files with 128 additions and 26 deletions
|
@ -1279,8 +1279,13 @@ where
|
|||
warn!("constellation got set final url message for dead pipeline");
|
||||
}
|
||||
},
|
||||
FromScriptMsg::PostMessage(browsing_context_id, origin, data) => {
|
||||
self.handle_post_message_msg(browsing_context_id, origin, data);
|
||||
FromScriptMsg::PostMessage {
|
||||
target: browsing_context_id,
|
||||
source: source_pipeline_id,
|
||||
target_origin: origin,
|
||||
data,
|
||||
} => {
|
||||
self.handle_post_message_msg(browsing_context_id, source_pipeline_id, origin, data);
|
||||
},
|
||||
FromScriptMsg::Focus => {
|
||||
self.handle_focus_msg(source_pipeline_id);
|
||||
|
@ -2844,6 +2849,7 @@ where
|
|||
fn handle_post_message_msg(
|
||||
&mut self,
|
||||
browsing_context_id: BrowsingContextId,
|
||||
source_pipeline: PipelineId,
|
||||
origin: Option<ImmutableOrigin>,
|
||||
data: Vec<u8>,
|
||||
) {
|
||||
|
@ -2856,7 +2862,17 @@ where
|
|||
},
|
||||
Some(browsing_context) => browsing_context.pipeline_id,
|
||||
};
|
||||
let msg = ConstellationControlMsg::PostMessage(pipeline_id, origin, data);
|
||||
let source_browsing_context = match self.pipelines.get(&source_pipeline) {
|
||||
Some(pipeline) => pipeline.top_level_browsing_context_id,
|
||||
None => return warn!("PostMessage from closed pipeline {:?}", source_pipeline),
|
||||
};
|
||||
let msg = ConstellationControlMsg::PostMessage {
|
||||
target: pipeline_id,
|
||||
source: source_pipeline,
|
||||
source_browsing_context: source_browsing_context,
|
||||
target_origin: origin,
|
||||
data,
|
||||
};
|
||||
let result = match self.pipelines.get(&pipeline_id) {
|
||||
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||
None => return warn!("postMessage to closed pipeline {}.", pipeline_id),
|
||||
|
|
|
@ -424,7 +424,7 @@ impl DedicatedWorkerGlobalScope {
|
|||
JSAutoCompartment::new(scope.get_cx(), scope.reflector().get_jsobject().get());
|
||||
rooted!(in(scope.get_cx()) let mut message = UndefinedValue());
|
||||
data.read(scope.upcast(), message.handle_mut());
|
||||
MessageEvent::dispatch_jsval(target, scope.upcast(), message.handle(), None);
|
||||
MessageEvent::dispatch_jsval(target, scope.upcast(), message.handle(), None, None);
|
||||
},
|
||||
WorkerScriptMsg::Common(msg) => {
|
||||
self.upcast::<WorkerGlobalScope>().process_event(msg);
|
||||
|
|
|
@ -203,11 +203,12 @@ impl DissimilarOriginWindow {
|
|||
None => return warn!("postMessage called with no incumbent global"),
|
||||
Some(incumbent) => incumbent,
|
||||
};
|
||||
let msg = ScriptMsg::PostMessage(
|
||||
self.window_proxy.browsing_context_id(),
|
||||
origin,
|
||||
data.move_to_arraybuffer(),
|
||||
);
|
||||
let msg = ScriptMsg::PostMessage {
|
||||
target: self.window_proxy.browsing_context_id(),
|
||||
source: incumbent.pipeline_id(),
|
||||
target_origin: origin,
|
||||
data: data.move_to_arraybuffer(),
|
||||
};
|
||||
let _ = incumbent.script_to_constellation_chan().send(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,6 +238,7 @@ impl EventSourceContext {
|
|||
false,
|
||||
data.handle(),
|
||||
DOMString::from(self.origin.clone()),
|
||||
None,
|
||||
event_source.last_event_id.borrow().clone(),
|
||||
)
|
||||
};
|
||||
|
|
|
@ -7,24 +7,27 @@ use crate::dom::bindings::codegen::Bindings::MessageEventBinding;
|
|||
use crate::dom::bindings::codegen::Bindings::MessageEventBinding::MessageEventMethods;
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::trace::RootedTraceableBox;
|
||||
use crate::dom::event::Event;
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::windowproxy::WindowProxy;
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::{Heap, JSContext};
|
||||
use js::jsapi::{Heap, JSContext, JSObject};
|
||||
use js::jsval::JSVal;
|
||||
use js::rust::HandleValue;
|
||||
use servo_atoms::Atom;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct MessageEvent {
|
||||
event: Event,
|
||||
data: Heap<JSVal>,
|
||||
origin: DOMString,
|
||||
source: Option<Dom<WindowProxy>>,
|
||||
lastEventId: DOMString,
|
||||
}
|
||||
|
||||
|
@ -34,6 +37,7 @@ impl MessageEvent {
|
|||
global,
|
||||
HandleValue::undefined(),
|
||||
DOMString::new(),
|
||||
None,
|
||||
DOMString::new(),
|
||||
)
|
||||
}
|
||||
|
@ -42,12 +46,14 @@ impl MessageEvent {
|
|||
global: &GlobalScope,
|
||||
data: HandleValue,
|
||||
origin: DOMString,
|
||||
source: Option<&WindowProxy>,
|
||||
lastEventId: DOMString,
|
||||
) -> DomRoot<MessageEvent> {
|
||||
let ev = Box::new(MessageEvent {
|
||||
event: Event::new_inherited(),
|
||||
data: Heap::default(),
|
||||
origin: origin,
|
||||
source: source.map(Dom::from_ref),
|
||||
lastEventId: lastEventId,
|
||||
});
|
||||
let ev = reflect_dom_object(ev, global, MessageEventBinding::Wrap);
|
||||
|
@ -63,9 +69,10 @@ impl MessageEvent {
|
|||
cancelable: bool,
|
||||
data: HandleValue,
|
||||
origin: DOMString,
|
||||
source: Option<&WindowProxy>,
|
||||
lastEventId: DOMString,
|
||||
) -> DomRoot<MessageEvent> {
|
||||
let ev = MessageEvent::new_initialized(global, data, origin, lastEventId);
|
||||
let ev = MessageEvent::new_initialized(global, data, origin, source, lastEventId);
|
||||
{
|
||||
let event = ev.upcast::<Event>();
|
||||
event.init_event(type_, bubbles, cancelable);
|
||||
|
@ -78,6 +85,10 @@ impl MessageEvent {
|
|||
type_: DOMString,
|
||||
init: RootedTraceableBox<MessageEventBinding::MessageEventInit>,
|
||||
) -> Fallible<DomRoot<MessageEvent>> {
|
||||
let source = init
|
||||
.source
|
||||
.as_ref()
|
||||
.and_then(|inner| inner.as_ref().map(|source| source.window_proxy()));
|
||||
let ev = MessageEvent::new(
|
||||
global,
|
||||
Atom::from(type_),
|
||||
|
@ -85,6 +96,7 @@ impl MessageEvent {
|
|||
init.parent.cancelable,
|
||||
init.data.handle(),
|
||||
init.origin.clone(),
|
||||
source.as_ref().map(|source| &**source),
|
||||
init.lastEventId.clone(),
|
||||
);
|
||||
Ok(ev)
|
||||
|
@ -97,6 +109,7 @@ impl MessageEvent {
|
|||
scope: &GlobalScope,
|
||||
message: HandleValue,
|
||||
origin: Option<&str>,
|
||||
source: Option<&WindowProxy>,
|
||||
) {
|
||||
let messageevent = MessageEvent::new(
|
||||
scope,
|
||||
|
@ -105,6 +118,7 @@ impl MessageEvent {
|
|||
false,
|
||||
message,
|
||||
DOMString::from(origin.unwrap_or("")),
|
||||
source,
|
||||
DOMString::new(),
|
||||
);
|
||||
messageevent.upcast::<Event>().fire(target);
|
||||
|
@ -123,6 +137,14 @@ impl MessageEventMethods for MessageEvent {
|
|||
self.origin.clone()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-messageevent-source
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn GetSource(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> {
|
||||
self.source
|
||||
.as_ref()
|
||||
.and_then(|source| NonNull::new(source.reflector().get_jsobject().get()))
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-messageevent-lasteventid
|
||||
fn LastEventId(&self) -> DOMString {
|
||||
self.lastEventId.clone()
|
||||
|
|
|
@ -8,6 +8,8 @@ interface MessageEvent : Event {
|
|||
readonly attribute any data;
|
||||
readonly attribute DOMString origin;
|
||||
readonly attribute DOMString lastEventId;
|
||||
// FIXME(#22617): WindowProxy is not exposed in Worker globals
|
||||
readonly attribute object? source;
|
||||
//readonly attribute (WindowProxy or MessagePort)? source;
|
||||
//readonly attribute MessagePort[]? ports;
|
||||
};
|
||||
|
@ -17,6 +19,7 @@ dictionary MessageEventInit : EventInit {
|
|||
DOMString origin = "";
|
||||
DOMString lastEventId = "";
|
||||
//DOMString channel;
|
||||
Window? source;
|
||||
//(WindowProxy or MessagePort)? source;
|
||||
//sequence<MessagePort> ports;
|
||||
};
|
||||
|
|
|
@ -599,6 +599,7 @@ impl TaskOnce for MessageReceivedTask {
|
|||
&global,
|
||||
message.handle(),
|
||||
Some(&ws.origin().ascii_serialization()),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -859,6 +859,9 @@ impl WindowMethods for Window {
|
|||
message: HandleValue,
|
||||
origin: DOMString,
|
||||
) -> ErrorResult {
|
||||
let source_global = GlobalScope::incumbent().expect("no incumbent global??");
|
||||
let source = source_global.as_window();
|
||||
|
||||
// Step 3-5.
|
||||
let origin = match &origin[..] {
|
||||
"*" => None,
|
||||
|
@ -878,7 +881,7 @@ impl WindowMethods for Window {
|
|||
let data = StructuredCloneData::write(cx, message)?;
|
||||
|
||||
// Step 9.
|
||||
self.post_message(origin, data);
|
||||
self.post_message(origin, &*source.window_proxy(), data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -2194,11 +2197,14 @@ impl Window {
|
|||
pub fn post_message(
|
||||
&self,
|
||||
target_origin: Option<ImmutableOrigin>,
|
||||
source: &WindowProxy,
|
||||
serialize_with_transfer_result: StructuredCloneData,
|
||||
) {
|
||||
let this = Trusted::new(self);
|
||||
let source = Trusted::new(source);
|
||||
let task = task!(post_serialised_message: move || {
|
||||
let this = this.root();
|
||||
let source = source.root();
|
||||
|
||||
// Step 7.1.
|
||||
if let Some(target_origin) = target_origin {
|
||||
|
@ -2226,7 +2232,8 @@ impl Window {
|
|||
this.upcast(),
|
||||
this.upcast(),
|
||||
message_clone.handle(),
|
||||
None
|
||||
None,
|
||||
Some(&*source),
|
||||
);
|
||||
});
|
||||
// FIXME(nox): Why are errors silenced here?
|
||||
|
|
|
@ -140,7 +140,7 @@ impl Worker {
|
|||
let _ac = JSAutoCompartment::new(global.get_cx(), target.reflector().get_jsobject().get());
|
||||
rooted!(in(global.get_cx()) let mut message = UndefinedValue());
|
||||
data.read(&global, message.handle_mut());
|
||||
MessageEvent::dispatch_jsval(target, &global, message.handle(), None);
|
||||
MessageEvent::dispatch_jsval(target, &global, message.handle(), None, None);
|
||||
}
|
||||
|
||||
pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
|
||||
|
|
|
@ -1419,7 +1419,7 @@ impl ScriptThread {
|
|||
ChangeFrameVisibilityStatus(id, ..) => Some(id),
|
||||
NotifyVisibilityChange(id, ..) => Some(id),
|
||||
Navigate(id, ..) => Some(id),
|
||||
PostMessage(id, ..) => Some(id),
|
||||
PostMessage { target: id, .. } => Some(id),
|
||||
UpdatePipelineId(_, _, id, _) => Some(id),
|
||||
UpdateHistoryState(id, ..) => Some(id),
|
||||
RemoveHistoryStates(id, ..) => Some(id),
|
||||
|
@ -1592,9 +1592,19 @@ impl ScriptThread {
|
|||
browsing_context_id,
|
||||
visible,
|
||||
),
|
||||
ConstellationControlMsg::PostMessage(pipeline_id, origin, data) => {
|
||||
self.handle_post_message_msg(pipeline_id, origin, data)
|
||||
},
|
||||
ConstellationControlMsg::PostMessage {
|
||||
target: target_pipeline_id,
|
||||
source: source_pipeline_id,
|
||||
source_browsing_context,
|
||||
target_origin: origin,
|
||||
data,
|
||||
} => self.handle_post_message_msg(
|
||||
target_pipeline_id,
|
||||
source_pipeline_id,
|
||||
source_browsing_context,
|
||||
origin,
|
||||
data,
|
||||
),
|
||||
ConstellationControlMsg::UpdatePipelineId(
|
||||
parent_pipeline_id,
|
||||
browsing_context_id,
|
||||
|
@ -2080,12 +2090,33 @@ impl ScriptThread {
|
|||
fn handle_post_message_msg(
|
||||
&self,
|
||||
pipeline_id: PipelineId,
|
||||
source_pipeline_id: PipelineId,
|
||||
source_browsing_context: TopLevelBrowsingContextId,
|
||||
origin: Option<ImmutableOrigin>,
|
||||
data: Vec<u8>,
|
||||
) {
|
||||
match { self.documents.borrow().find_window(pipeline_id) } {
|
||||
None => return warn!("postMessage after pipeline {} closed.", pipeline_id),
|
||||
Some(window) => window.post_message(origin, StructuredCloneData::Vector(data)),
|
||||
None => return warn!("postMessage after target pipeline {} closed.", pipeline_id),
|
||||
Some(window) => {
|
||||
// FIXME: synchronously talks to constellation.
|
||||
// send the required info as part of postmessage instead.
|
||||
let source = match self.remote_window_proxy(
|
||||
&*window.global(),
|
||||
source_browsing_context,
|
||||
source_pipeline_id,
|
||||
None,
|
||||
) {
|
||||
None => {
|
||||
return warn!(
|
||||
"postMessage after source pipeline {} closed.",
|
||||
source_pipeline_id,
|
||||
);
|
||||
},
|
||||
Some(source) => source,
|
||||
};
|
||||
// FIXME(#22512): enqueues a task; unnecessary delay.
|
||||
window.post_message(origin, &*source, StructuredCloneData::Vector(data))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -284,7 +284,18 @@ pub enum ConstellationControlMsg {
|
|||
/// PipelineId is for the parent, BrowsingContextId is for the nested browsing context
|
||||
Navigate(PipelineId, BrowsingContextId, LoadData, bool),
|
||||
/// Post a message to a given window.
|
||||
PostMessage(PipelineId, Option<ImmutableOrigin>, Vec<u8>),
|
||||
PostMessage {
|
||||
/// The target of the message.
|
||||
target: PipelineId,
|
||||
/// The source of the message.
|
||||
source: PipelineId,
|
||||
/// The top level browsing context associated with the source pipeline.
|
||||
source_browsing_context: TopLevelBrowsingContextId,
|
||||
/// The expected origin of the target.
|
||||
target_origin: Option<ImmutableOrigin>,
|
||||
/// The data to be posted.
|
||||
data: Vec<u8>,
|
||||
},
|
||||
/// Updates the current pipeline ID of a given iframe.
|
||||
/// First PipelineId is for the parent, second is the new PipelineId for the frame.
|
||||
UpdatePipelineId(
|
||||
|
@ -358,7 +369,7 @@ impl fmt::Debug for ConstellationControlMsg {
|
|||
ChangeFrameVisibilityStatus(..) => "ChangeFrameVisibilityStatus",
|
||||
NotifyVisibilityChange(..) => "NotifyVisibilityChange",
|
||||
Navigate(..) => "Navigate",
|
||||
PostMessage(..) => "PostMessage",
|
||||
PostMessage { .. } => "PostMessage",
|
||||
UpdatePipelineId(..) => "UpdatePipelineId",
|
||||
UpdateHistoryState(..) => "UpdateHistoryState",
|
||||
RemoveHistoryStates(..) => "RemoveHistoryStates",
|
||||
|
|
|
@ -134,7 +134,16 @@ pub enum ScriptMsg {
|
|||
/// Abort loading after sending a LoadUrl message.
|
||||
AbortLoadUrl,
|
||||
/// Post a message to the currently active window of a given browsing context.
|
||||
PostMessage(BrowsingContextId, Option<ImmutableOrigin>, Vec<u8>),
|
||||
PostMessage {
|
||||
/// The target of the posted message.
|
||||
target: BrowsingContextId,
|
||||
/// The source of the posted message.
|
||||
source: PipelineId,
|
||||
/// The expected origin of the target.
|
||||
target_origin: Option<ImmutableOrigin>,
|
||||
/// The data to be posted.
|
||||
data: Vec<u8>,
|
||||
},
|
||||
/// Inform the constellation that a fragment was navigated to and whether or not it was a replacement navigation.
|
||||
NavigatedToFragment(ServoUrl, bool),
|
||||
/// HTMLIFrameElement Forward or Back traversal.
|
||||
|
@ -209,7 +218,7 @@ impl fmt::Debug for ScriptMsg {
|
|||
LoadComplete => "LoadComplete",
|
||||
LoadUrl(..) => "LoadUrl",
|
||||
AbortLoadUrl => "AbortLoadUrl",
|
||||
PostMessage(..) => "PostMessage",
|
||||
PostMessage { .. } => "PostMessage",
|
||||
NavigatedToFragment(..) => "NavigatedToFragment",
|
||||
TraverseHistory(..) => "TraverseHistory",
|
||||
PushHistoryState(..) => "PushHistoryState",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue