aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/document_loader.rs15
-rw-r--r--components/script/dom/beforeunloadevent.rs67
-rw-r--r--components/script/dom/bindings/global.rs12
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs21
-rw-r--r--components/script/dom/document.rs5
-rw-r--r--components/script/dom/eventtarget.rs44
-rw-r--r--components/script/dom/htmlbodyelement.rs26
-rw-r--r--components/script/dom/htmlelement.rs39
-rw-r--r--components/script/dom/htmlframesetelement.rs10
-rw-r--r--components/script/dom/macros.rs128
-rw-r--r--components/script/dom/mod.rs11
-rw-r--r--components/script/dom/webidls/BeforeUnloadEvent.webidl11
-rw-r--r--components/script/dom/webidls/Document.webidl1
-rw-r--r--components/script/dom/webidls/EventHandler.webidl59
-rw-r--r--components/script/dom/webidls/HTMLElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLFrameSetElement.webidl3
-rw-r--r--components/script/dom/window.rs21
-rw-r--r--components/script/dom/worker.rs35
-rw-r--r--components/script/dom/workerglobalscope.rs43
-rw-r--r--components/script/dom/xmlhttprequest.rs30
-rw-r--r--components/script/script_thread.rs39
21 files changed, 554 insertions, 67 deletions
diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs
index 7282e23c322..4d5df6c74e5 100644
--- a/components/script/document_loader.rs
+++ b/components/script/document_loader.rs
@@ -8,8 +8,8 @@
use dom::bindings::js::JS;
use dom::document::Document;
use msg::constellation_msg::PipelineId;
-use net_traits::AsyncResponseTarget;
use net_traits::{PendingAsyncLoad, CoreResourceThread, LoadContext};
+use net_traits::{RequestSource, AsyncResponseTarget};
use std::sync::Arc;
use std::thread;
use url::Url;
@@ -130,20 +130,27 @@ impl DocumentLoader {
/// Create a new pending network request, which can be initiated at some point in
/// the future.
- pub fn prepare_async_load(&mut self, load: LoadType, referrer: &Document) -> PendingAsyncLoad {
+ pub fn prepare_async_load(&mut self,
+ load: LoadType,
+ referrer: &Document) -> PendingAsyncLoad {
let context = load.to_load_context();
let url = load.url().clone();
self.add_blocking_load(load);
+ let client_chan = referrer.window().custom_message_chan();
PendingAsyncLoad::new(context,
(*self.resource_thread).clone(),
url,
self.pipeline,
referrer.get_referrer_policy(),
- Some(referrer.url().clone()))
+ Some(referrer.url().clone()),
+ RequestSource::Window(client_chan))
}
/// Create and initiate a new network request.
- pub fn load_async(&mut self, load: LoadType, listener: AsyncResponseTarget, referrer: &Document) {
+ pub fn load_async(&mut self,
+ load: LoadType,
+ listener: AsyncResponseTarget,
+ referrer: &Document) {
let pending = self.prepare_async_load(load, referrer);
pending.load_async(listener)
}
diff --git a/components/script/dom/beforeunloadevent.rs b/components/script/dom/beforeunloadevent.rs
new file mode 100644
index 00000000000..9257cbcafcb
--- /dev/null
+++ b/components/script/dom/beforeunloadevent.rs
@@ -0,0 +1,67 @@
+/* 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::cell::DOMRefCell;
+use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding;
+use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEventMethods;
+use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::js::Root;
+use dom::bindings::reflector::reflect_dom_object;
+use dom::event::{Event, EventBubbles, EventCancelable};
+use string_cache::Atom;
+use util::str::DOMString;
+
+// https://html.spec.whatwg.org/multipage/#beforeunloadevent
+#[dom_struct]
+pub struct BeforeUnloadEvent {
+ event: Event,
+ return_value: DOMRefCell<DOMString>,
+}
+
+impl BeforeUnloadEvent {
+ fn new_inherited() -> BeforeUnloadEvent {
+ BeforeUnloadEvent {
+ event: Event::new_inherited(),
+ return_value: DOMRefCell::new(DOMString::new()),
+ }
+ }
+
+ pub fn new_uninitialized(global: GlobalRef) -> Root<BeforeUnloadEvent> {
+ reflect_dom_object(box BeforeUnloadEvent::new_inherited(),
+ global,
+ BeforeUnloadEventBinding::Wrap)
+ }
+
+ pub fn new(global: GlobalRef,
+ type_: Atom,
+ bubbles: EventBubbles,
+ cancelable: EventCancelable) -> Root<BeforeUnloadEvent> {
+ let ev = BeforeUnloadEvent::new_uninitialized(global);
+ {
+ let event = ev.upcast::<Event>();
+ event.init_event(type_, bool::from(bubbles),
+ bool::from(cancelable));
+ }
+ ev
+ }
+}
+
+impl BeforeUnloadEventMethods for BeforeUnloadEvent {
+ // https://html.spec.whatwg.org/multipage/#dom-beforeunloadevent-returnvalue
+ fn ReturnValue(&self) -> DOMString {
+ self.return_value.borrow().clone()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-beforeunloadevent-returnvalue
+ fn SetReturnValue(&self, value: DOMString) {
+ *self.return_value.borrow_mut() = value;
+ }
+
+ // https://dom.spec.whatwg.org/#dom-event-istrusted
+ fn IsTrusted(&self) -> bool {
+ self.event.IsTrusted()
+ }
+}
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index 61b948dbf35..ff36817b660 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -18,8 +18,8 @@ use ipc_channel::ipc::IpcSender;
use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
-use msg::constellation_msg::{PanicMsg, PipelineId};
-use net_traits::CoreResourceThread;
+use msg::constellation_msg::{PipelineId, PanicMsg};
+use net_traits::{CoreResourceThread, RequestSource};
use profile_traits::{mem, time};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
use script_thread::{MainThreadScriptChan, ScriptThread};
@@ -65,6 +65,14 @@ impl<'a> GlobalRef<'a> {
}
}
+ /// gets the custom message channel associated with global object
+ pub fn request_source(&self) -> RequestSource {
+ match *self {
+ GlobalRef::Window(ref window) => RequestSource::Window(window.custom_message_chan()),
+ GlobalRef::Worker(ref worker) => RequestSource::Worker(worker.custom_message_chan()),
+ }
+ }
+
/// Get the `PipelineId` for this global scope.
pub fn pipeline(&self) -> PipelineId {
match *self {
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index bd5cd63fcfb..120565b00fa 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -16,7 +16,8 @@ use dom::bindings::refcounted::LiveDOMReferences;
use dom::bindings::reflector::Reflectable;
use dom::bindings::structuredclone::StructuredCloneData;
use dom::messageevent::MessageEvent;
-use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress, WorkerMessageHandler};
+use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress};
+use dom::worker::{WorkerScriptLoadOrigin, WorkerMessageHandler};
use dom::workerglobalscope::WorkerGlobalScope;
use dom::workerglobalscope::WorkerGlobalScopeInit;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
@@ -26,7 +27,7 @@ use js::jsapi::{JSAutoCompartment, JSContext, RootedValue};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use msg::constellation_msg::PipelineId;
-use net_traits::{LoadContext, load_whole_resource};
+use net_traits::{LoadContext, load_whole_resource, CustomResponse};
use rand::random;
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
@@ -133,6 +134,7 @@ enum MixedMessage {
FromWorker((TrustedWorkerAddress, WorkerScriptMsg)),
FromScheduler((TrustedWorkerAddress, TimerEvent)),
FromDevtools(DevtoolScriptControlMsg),
+ FromNetwork(IpcSender<Option<CustomResponse>>),
}
// https://html.spec.whatwg.org/multipage/#dedicatedworkerglobalscope
@@ -215,18 +217,18 @@ impl DedicatedWorkerGlobalScope {
worker: TrustedWorkerAddress,
parent_sender: Box<ScriptChan + Send>,
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
- receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>) {
+ receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
+ worker_load_origin: WorkerScriptLoadOrigin) {
let serialized_worker_url = worker_url.to_string();
let name = format!("WebWorker for {}", serialized_worker_url);
let panic_chan = init.panic_chan.clone();
spawn_named_with_send_on_panic(name, SCRIPT | IN_WORKER, move || {
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);
-
let (url, source) = match load_whole_resource(LoadContext::Script,
&init.core_resource_thread,
worker_url,
- None) {
+ &worker_load_origin) {
Err(_) => {
println!("error loading script {}", serialized_worker_url);
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
@@ -316,17 +318,20 @@ impl DedicatedWorkerGlobalScope {
let worker_port = &self.receiver;
let timer_event_port = &self.timer_event_port;
let devtools_port = scope.from_devtools_receiver();
+ let msg_port = scope.custom_message_port();
let sel = Select::new();
let mut worker_handle = sel.handle(worker_port);
let mut timer_event_handle = sel.handle(timer_event_port);
let mut devtools_handle = sel.handle(devtools_port);
+ let mut msg_port_handle = sel.handle(msg_port);
unsafe {
worker_handle.add();
timer_event_handle.add();
if scope.from_devtools_sender().is_some() {
devtools_handle.add();
}
+ msg_port_handle.add();
}
let ret = sel.wait();
if ret == worker_handle.id() {
@@ -335,6 +340,8 @@ impl DedicatedWorkerGlobalScope {
Ok(MixedMessage::FromScheduler(try!(timer_event_port.recv())))
} else if ret == devtools_handle.id() {
Ok(MixedMessage::FromDevtools(try!(devtools_port.recv())))
+ } else if ret == msg_port_handle.id() {
+ Ok(MixedMessage::FromNetwork(try!(msg_port.recv())))
} else {
panic!("unexpected select result!")
}
@@ -397,6 +404,10 @@ impl DedicatedWorkerGlobalScope {
let _ar = AutoWorkerReset::new(self, linked_worker);
self.handle_script_event(msg);
},
+ MixedMessage::FromNetwork(network_sender) => {
+ // We send None as of now
+ let _ = network_sender.send(None);
+ }
}
}
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index ddf23297282..10645b761d7 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -1354,7 +1354,7 @@ impl Document {
pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget) {
let mut loader = self.loader.borrow_mut();
- loader.load_async(load, listener, self)
+ loader.load_async(load, listener, self);
}
pub fn finish_load(&self, load: LoadType) {
@@ -2795,6 +2795,9 @@ impl DocumentMethods for Document {
// Step 5
elements
}
+
+ // https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
+ document_and_element_event_handlers!();
}
fn update_with_current_time_ms(marker: &Cell<u64>) {
diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs
index 3b20120628d..c8eecc8e65d 100644
--- a/components/script/dom/eventtarget.rs
+++ b/components/script/dom/eventtarget.rs
@@ -2,11 +2,14 @@
* 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::beforeunloadevent::BeforeUnloadEvent;
use dom::bindings::callback::{CallbackContainer, ExceptionHandling, CallbackFunction};
use dom::bindings::cell::DOMRefCell;
+use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEventMethods;
use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
+use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
@@ -45,6 +48,7 @@ use util::str::DOMString;
pub enum CommonEventHandler {
EventHandler(Rc<EventHandlerNonNull>),
ErrorEventHandler(Rc<OnErrorEventHandlerNonNull>),
+ BeforeUnloadEventHandler(Rc<OnBeforeUnloadEventHandlerNonNull>),
}
impl CommonEventHandler {
@@ -52,6 +56,7 @@ impl CommonEventHandler {
match *self {
CommonEventHandler::EventHandler(ref handler) => &handler.parent,
CommonEventHandler::ErrorEventHandler(ref handler) => &handler.parent,
+ CommonEventHandler::BeforeUnloadEventHandler(ref handler) => &handler.parent,
}
}
}
@@ -173,6 +178,27 @@ impl CompiledEventListener {
None, None, None, None, exception_handle);
}
+ CommonEventHandler::BeforeUnloadEventHandler(ref handler) => {
+ if let Some(event) = event.downcast::<BeforeUnloadEvent>() {
+ let rv = event.ReturnValue();
+
+ if let Ok(value) = handler.Call_(object,
+ event.upcast::<Event>(),
+ exception_handle) {
+ match value {
+ Some(value) => {
+ if rv.is_empty() {
+ event.SetReturnValue(value);
+ }
+ }
+ None => {
+ event.upcast::<Event>().PreventDefault();
+ }
+ }
+ }
+ }
+ }
+
CommonEventHandler::EventHandler(ref handler) => {
if let Ok(value) = handler.Call_(object, event, exception_handle) {
let global = object.global();
@@ -183,7 +209,6 @@ impl CompiledEventListener {
//Step 4
let should_cancel = match event.type_() {
atom!("mouseover") => value.is_boolean() && value.to_boolean() == true,
- atom!("beforeunload") => value.is_null(),
_ => value.is_boolean() && value.to_boolean() == false
};
if should_cancel {
@@ -412,7 +437,12 @@ impl EventTarget {
if is_error {
Some(CommonEventHandler::ErrorEventHandler(OnErrorEventHandlerNonNull::new(funobj)))
} else {
- Some(CommonEventHandler::EventHandler(EventHandlerNonNull::new(funobj)))
+ if ty == &atom!("beforeunload") {
+ Some(CommonEventHandler::BeforeUnloadEventHandler(
+ OnBeforeUnloadEventHandlerNonNull::new(funobj)))
+ } else {
+ Some(CommonEventHandler::EventHandler(EventHandlerNonNull::new(funobj)))
+ }
}
}
@@ -436,6 +466,16 @@ impl EventTarget {
self.set_inline_event_listener(Atom::from(ty), event_listener);
}
+ pub fn set_beforeunload_event_handler<T: CallbackContainer>(&self, ty: &str,
+ listener: Option<Rc<T>>) {
+ let event_listener = listener.map(|listener|
+ InlineEventListener::Compiled(
+ CommonEventHandler::BeforeUnloadEventHandler(
+ OnBeforeUnloadEventHandlerNonNull::new(listener.callback())))
+ );
+ self.set_inline_event_listener(Atom::from(ty), event_listener);
+ }
+
pub fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<Rc<T>> {
let listener = self.get_inline_event_listener(&Atom::from(ty));
listener.map(|listener| CallbackContainer::new(listener.parent().callback()))
diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs
index 2fd18a00c08..536e3759fb3 100644
--- a/components/script/dom/htmlbodyelement.rs
+++ b/components/script/dom/htmlbodyelement.rs
@@ -4,7 +4,7 @@
use cssparser::RGBA;
use dom::attr::{Attr, AttrValue};
-use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
+use dom::bindings::codegen::Bindings::EventHandlerBinding::{EventHandlerNonNull, OnBeforeUnloadEventHandlerNonNull};
use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyElementMethods};
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::inheritance::Castable;
@@ -16,7 +16,6 @@ use dom::htmlelement::HTMLElement;
use dom::node::{Node, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use script_traits::ScriptMsg as ConstellationMsg;
-use std::rc::Rc;
use string_cache::Atom;
use time;
use url::Url;
@@ -70,31 +69,14 @@ impl HTMLBodyElementMethods for HTMLBodyElement {
// https://html.spec.whatwg.org/multipage/#dom-body-text
make_legacy_color_setter!(SetText, "text");
- // https://html.spec.whatwg.org/multipage/#the-body-element
- fn GetOnunload(&self) -> Option<Rc<EventHandlerNonNull>> {
- window_from_node(self).GetOnunload()
- }
-
- // https://html.spec.whatwg.org/multipage/#the-body-element
- fn SetOnunload(&self, listener: Option<Rc<EventHandlerNonNull>>) {
- window_from_node(self).SetOnunload(listener)
- }
-
- // https://html.spec.whatwg.org/multipage/#the-body-element
- fn GetOnstorage(&self) -> Option<Rc<EventHandlerNonNull>> {
- window_from_node(self).GetOnstorage()
- }
-
- // https://html.spec.whatwg.org/multipage/#the-body-element
- fn SetOnstorage(&self, listener: Option<Rc<EventHandlerNonNull>>) {
- window_from_node(self).SetOnstorage(listener)
- }
-
// https://html.spec.whatwg.org/multipage/#dom-body-background
make_getter!(Background, "background");
// https://html.spec.whatwg.org/multipage/#dom-body-background
make_url_setter!(SetBackground, "background");
+
+ // https://html.spec.whatwg.org/multipage/#windoweventhandlers
+ window_event_handlers!(ForwardToWindow);
}
pub trait HTMLBodyElementLayoutHelpers {
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index 3ad8f977869..7e310db8903 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -137,6 +137,9 @@ impl HTMLElementMethods for HTMLElement {
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
global_event_handlers!(NoOnload);
+ // https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
+ document_and_element_event_handlers!();
+
// https://html.spec.whatwg.org/multipage/#dom-dataset
fn Dataset(&self) -> Root<DOMStringMap> {
self.dataset.or_init(|| DOMStringMap::new(self))
@@ -196,6 +199,42 @@ impl HTMLElementMethods for HTMLElement {
}
}
+ // https://html.spec.whatwg.org/multipage/#handler-onfocus
+ fn GetOnfocus(&self) -> Option<Rc<EventHandlerNonNull>> {
+ if self.is_body_or_frameset() {
+ window_from_node(self).GetOnfocus()
+ } else {
+ self.upcast::<EventTarget>().get_event_handler_common("focus")
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#handler-onfocus
+ fn SetOnfocus(&self, listener: Option<Rc<EventHandlerNonNull>>) {
+ if self.is_body_or_frameset() {
+ window_from_node(self).SetOnfocus(listener)
+ } else {
+ self.upcast::<EventTarget>().set_event_handler_common("focus", listener)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#handler-onscroll
+ fn GetOnscroll(&self) -> Option<Rc<EventHandlerNonNull>> {
+ if self.is_body_or_frameset() {
+ window_from_node(self).GetOnscroll()
+ } else {
+ self.upcast::<EventTarget>().get_event_handler_common("scroll")
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#handler-onscroll
+ fn SetOnscroll(&self, listener: Option<Rc<EventHandlerNonNull>>) {
+ if self.is_body_or_frameset() {
+ window_from_node(self).SetOnscroll(listener)
+ } else {
+ self.upcast::<EventTarget>().set_event_handler_common("scroll", listener)
+ }
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-click
fn Click(&self) {
if !self.upcast::<Element>().disabled_state() {
diff --git a/components/script/dom/htmlframesetelement.rs b/components/script/dom/htmlframesetelement.rs
index 92170a0baf4..df73bc893e9 100644
--- a/components/script/dom/htmlframesetelement.rs
+++ b/components/script/dom/htmlframesetelement.rs
@@ -2,11 +2,14 @@
* 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::EventHandlerBinding::{EventHandlerNonNull, OnBeforeUnloadEventHandlerNonNull};
use dom::bindings::codegen::Bindings::HTMLFrameSetElementBinding;
+use dom::bindings::codegen::Bindings::HTMLFrameSetElementBinding::HTMLFrameSetElementMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::js::Root;
use dom::document::Document;
use dom::htmlelement::HTMLElement;
-use dom::node::Node;
+use dom::node::{Node, window_from_node};
use string_cache::Atom;
use util::str::DOMString;
@@ -33,3 +36,8 @@ impl HTMLFrameSetElement {
Node::reflect_node(box element, document, HTMLFrameSetElementBinding::Wrap)
}
}
+
+impl HTMLFrameSetElementMethods for HTMLFrameSetElement {
+ // https://html.spec.whatwg.org/multipage/#windoweventhandlers
+ window_event_handlers!(ForwardToWindow);
+}
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs
index cf93b72f985..78238dc09fd 100644
--- a/components/script/dom/macros.rs
+++ b/components/script/dom/macros.rs
@@ -321,6 +321,18 @@ macro_rules! define_event_handler(
)
);
+macro_rules! define_window_owned_event_handler(
+ ($handler: ident, $event_type: ident, $getter: ident, $setter: ident) => (
+ fn $getter(&self) -> Option<::std::rc::Rc<$handler>> {
+ window_from_node(self).$getter()
+ }
+
+ fn $setter(&self, listener: Option<::std::rc::Rc<$handler>>) {
+ window_from_node(self).$setter(listener)
+ }
+ )
+);
+
macro_rules! event_handler(
($event_type: ident, $getter: ident, $setter: ident) => (
define_event_handler!(EventHandlerNonNull, $event_type, $getter, $setter,
@@ -335,42 +347,158 @@ macro_rules! error_event_handler(
)
);
+macro_rules! beforeunload_event_handler(
+ ($event_type: ident, $getter: ident, $setter: ident) => (
+ define_event_handler!(OnBeforeUnloadEventHandlerNonNull, $event_type,
+ $getter, $setter, set_beforeunload_event_handler);
+ )
+);
+
+macro_rules! window_owned_event_handler(
+ ($event_type: ident, $getter: ident, $setter: ident) => (
+ define_window_owned_event_handler!(EventHandlerNonNull,
+ $event_type, $getter, $setter);
+ )
+);
+
+macro_rules! window_owned_beforeunload_event_handler(
+ ($event_type: ident, $getter: ident, $setter: ident) => (
+ define_window_owned_event_handler!(OnBeforeUnloadEventHandlerNonNull,
+ $event_type, $getter, $setter);
+ )
+);
+
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
// see webidls/EventHandler.webidl
// As more methods get added, just update them here.
macro_rules! global_event_handlers(
() => (
event_handler!(blur, GetOnblur, SetOnblur);
+ event_handler!(focus, GetOnfocus, SetOnfocus);
event_handler!(load, GetOnload, SetOnload);
event_handler!(resize, GetOnresize, SetOnresize);
+ event_handler!(scroll, GetOnscroll, SetOnscroll);
global_event_handlers!(NoOnload);
);
(NoOnload) => (
event_handler!(abort, GetOnabort, SetOnabort);
+ event_handler!(cancel, GetOncancel, SetOncancel);
event_handler!(canplay, GetOncanplay, SetOncanplay);
event_handler!(canplaythrough, GetOncanplaythrough, SetOncanplaythrough);
event_handler!(change, GetOnchange, SetOnchange);
event_handler!(click, GetOnclick, SetOnclick);
+ event_handler!(close, GetOnclose, SetOnclose);
+ event_handler!(contextmenu, GetOncontextmenu, SetOncontextmenu);
+ event_handler!(cuechange, GetOncuechange, SetOncuechange);
event_handler!(dblclick, GetOndblclick, SetOndblclick);
+ event_handler!(drag, GetOndrag, SetOndrag);
+ event_handler!(dragend, GetOndragend, SetOndragend);
+ event_handler!(dragenter, GetOndragenter, SetOndragenter);
+ event_handler!(dragexit, GetOndragexit, SetOndragexit);
+ event_handler!(dragleave, GetOndragleave, SetOndragleave);
+ event_handler!(dragover, GetOndragover, SetOndragover);
+ event_handler!(dragstart, GetOndragstart, SetOndragstart);
+ event_handler!(drop, GetOndrop, SetOndrop);
+ event_handler!(durationchange, GetOndurationchange, SetOndurationchange);
event_handler!(emptied, GetOnemptied, SetOnemptied);
+ event_handler!(ended, GetOnended, SetOnended);
error_event_handler!(error, GetOnerror, SetOnerror);
event_handler!(input, GetOninput, SetOninput);
+ event_handler!(invalid, GetOninvalid, SetOninvalid);
event_handler!(keydown, GetOnkeydown, SetOnkeydown);
event_handler!(keypress, GetOnkeypress, SetOnkeypress);
event_handler!(keyup, GetOnkeyup, SetOnkeyup);
event_handler!(loadeddata, GetOnloadeddata, SetOnloadeddata);
event_handler!(loadedmetata, GetOnloadedmetadata, SetOnloadedmetadata);
+ event_handler!(loadstart, GetOnloadstart, SetOnloadstart);
+ event_handler!(mousedown, GetOnmousedown, SetOnmousedown);
+ event_handler!(mouseenter, GetOnmouseenter, SetOnmouseenter);
+ event_handler!(mouseleave, GetOnmouseleave, SetOnmouseleave);
+ event_handler!(mousemove, GetOnmousemove, SetOnmousemove);
+ event_handler!(mouseout, GetOnmouseout, SetOnmouseout);
event_handler!(mouseover, GetOnmouseover, SetOnmouseover);
+ event_handler!(mouseup, GetOnmouseup, SetOnmouseup);
+ event_handler!(wheel, GetOnwheel, SetOnwheel);
event_handler!(pause, GetOnpause, SetOnpause);
event_handler!(play, GetOnplay, SetOnplay);
event_handler!(playing, GetOnplaying, SetOnplaying);
event_handler!(progress, GetOnprogress, SetOnprogress);
+ event_handler!(ratechange, GetOnratechange, SetOnratechange);
event_handler!(reset, GetOnreset, SetOnreset);
+ event_handler!(seeked, GetOnseeked, SetOnseeked);
+ event_handler!(seeking, GetOnseeking, SetOnseeking);
+ event_handler!(select, GetOnselect, SetOnselect);
+ event_handler!(show, GetOnshow, SetOnshow);
+ event_handler!(stalled, GetOnstalled, SetOnstalled);
event_handler!(submit, GetOnsubmit, SetOnsubmit);
event_handler!(suspend, GetOnsuspend, SetOnsuspend);
event_handler!(timeupdate, GetOntimeupdate, SetOntimeupdate);
event_handler!(toggle, GetOntoggle, SetOntoggle);
+ event_handler!(volumechange, GetOnvolumechange, SetOnvolumechange);
event_handler!(waiting, GetOnwaiting, SetOnwaiting);
)
);
+
+// https://html.spec.whatwg.org/multipage/#windoweventhandlers
+// see webidls/EventHandler.webidl
+// As more methods get added, just update them here.
+macro_rules! window_event_handlers(
+ () => (
+ event_handler!(afterprint, GetOnafterprint, SetOnafterprint);
+ event_handler!(beforeprint, GetOnbeforeprint, SetOnbeforeprint);
+ beforeunload_event_handler!(beforeunload, GetOnbeforeunload,
+ SetOnbeforeunload);
+ event_handler!(hashchange, GetOnhashchange, SetOnhashchange);
+ event_handler!(languagechange, GetOnlanguagechange,
+ SetOnlanguagechange);
+ event_handler!(message, GetOnmessage, SetOnmessage);
+ event_handler!(offline, GetOnoffline, SetOnoffline);
+ event_handler!(online, GetOnonline, SetOnonline);
+ event_handler!(pagehide, GetOnpagehide, SetOnpagehide);
+ event_handler!(pageshow, GetOnpageshow, SetOnpageshow);
+ event_handler!(popstate, GetOnpopstate, SetOnpopstate);
+ event_handler!(rejectionhandled, GetOnrejectionhandled,
+ SetOnrejectionhandled);
+ event_handler!(storage, GetOnstorage, SetOnstorage);
+ event_handler!(unhandledrejection, GetOnunhandledrejection,
+ SetOnunhandledrejection);
+ event_handler!(unload, GetOnunload, SetOnunload);
+ );
+ (ForwardToWindow) => (
+ window_owned_event_handler!(afterprint, GetOnafterprint,
+ SetOnafterprint);
+ window_owned_event_handler!(beforeprint, GetOnbeforeprint,
+ SetOnbeforeprint);
+ window_owned_beforeunload_event_handler!(beforeunload,
+ GetOnbeforeunload,
+ SetOnbeforeunload);
+ window_owned_event_handler!(hashchange, GetOnhashchange,
+ SetOnhashchange);
+ window_owned_event_handler!(languagechange, GetOnlanguagechange,
+ SetOnlanguagechange);
+ window_owned_event_handler!(message, GetOnmessage, SetOnmessage);
+ window_owned_event_handler!(offline, GetOnoffline, SetOnoffline);
+ window_owned_event_handler!(online, GetOnonline, SetOnonline);
+ window_owned_event_handler!(pagehide, GetOnpagehide, SetOnpagehide);
+ window_owned_event_handler!(pageshow, GetOnpageshow, SetOnpageshow);
+ window_owned_event_handler!(popstate, GetOnpopstate, SetOnpopstate);
+ window_owned_event_handler!(rejectionhandled, GetOnrejectionhandled,
+ SetOnrejectionhandled);
+ window_owned_event_handler!(storage, GetOnstorage, SetOnstorage);
+ window_owned_event_handler!(unhandledrejection, GetOnunhandledrejection,
+ SetOnunhandledrejection);
+ window_owned_event_handler!(unload, GetOnunload, SetOnunload);
+ );
+);
+
+// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
+// see webidls/EventHandler.webidl
+// As more methods get added, just update them here.
+macro_rules! document_and_element_event_handlers(
+ () => (
+ event_handler!(cut, GetOncut, SetOncut);
+ event_handler!(copy, GetOncopy, SetOncopy);
+ event_handler!(paste, GetOnpaste, SetOnpaste);
+ )
+);
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index cfa41a1ae19..a5d8e7a707a 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -157,18 +157,18 @@
//! Inheritance and casting
//! =======================
//!
-//! For all DOM interfaces `Foo` in an inheritance chain, a
-//! `dom::bindings::inheritance::FooCast` provides methods to cast
-//! to other types in the inheritance chain. For example:
+//! All DOM interfaces part of an inheritance chain (i.e. interfaces
+//! that derive others or are derived from) implement the trait `Castable`
+//! which provides both downcast and upcasts.
//!
//! ```ignore
-//! # use script::dom::bindings::inheritance::{NodeCast, HTMLElementCast};
+//! # use script::dom::bindings::inheritance::Castable;
//! # use script::dom::element::Element;
//! # use script::dom::node::Node;
//! # use script::dom::htmlelement::HTMLElement;
//! fn f(element: &Element) {
//! let base = element.upcast::<Node>();
-//! let derived = element.downcast::<HTMLElement>();
+//! let derived = element.downcast::<HTMLElement>().unwrap();
//! }
//! ```
//!
@@ -211,6 +211,7 @@ pub mod types {
pub mod activation;
pub mod attr;
+pub mod beforeunloadevent;
mod create;
#[allow(unsafe_code)]
#[deny(missing_docs, non_snake_case)]
diff --git a/components/script/dom/webidls/BeforeUnloadEvent.webidl b/components/script/dom/webidls/BeforeUnloadEvent.webidl
new file mode 100644
index 00000000000..5e4a099725a
--- /dev/null
+++ b/components/script/dom/webidls/BeforeUnloadEvent.webidl
@@ -0,0 +1,11 @@
+/* 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/. */
+/*
+ * For more information on this interface please see
+ * https://html.spec.whatwg.org/multipage/#beforeunloadevent
+ */
+
+interface BeforeUnloadEvent : Event {
+ attribute DOMString returnValue;
+};
diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl
index b211fe7be58..b73d563bac7 100644
--- a/components/script/dom/webidls/Document.webidl
+++ b/components/script/dom/webidls/Document.webidl
@@ -138,6 +138,7 @@ partial /*sealed*/ interface Document {
// also has obsolete members
};
Document implements GlobalEventHandlers;
+Document implements DocumentAndElementEventHandlers;
// https://html.spec.whatwg.org/multipage/#Document-partial
partial interface Document {
diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl
index fa42b757cab..957fc0bd4dd 100644
--- a/components/script/dom/webidls/EventHandler.webidl
+++ b/components/script/dom/webidls/EventHandler.webidl
@@ -20,42 +20,99 @@ callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional
optional any error);
typedef OnErrorEventHandlerNonNull? OnErrorEventHandler;
+[TreatNonObjectAsNull]
+callback OnBeforeUnloadEventHandlerNonNull = DOMString? (Event event);
+typedef OnBeforeUnloadEventHandlerNonNull? OnBeforeUnloadEventHandler;
+
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
[NoInterfaceObject]
interface GlobalEventHandlers {
attribute EventHandler onabort;
attribute EventHandler onblur;
+ attribute EventHandler oncancel;
attribute EventHandler oncanplay;
attribute EventHandler oncanplaythrough;
attribute EventHandler onchange;
attribute EventHandler onclick;
+ attribute EventHandler onclose;
+ attribute EventHandler oncontextmenu;
+ attribute EventHandler oncuechange;
attribute EventHandler ondblclick;
+ attribute EventHandler ondrag;
+ attribute EventHandler ondragend;
+ attribute EventHandler ondragenter;
+ attribute EventHandler ondragexit;
+ attribute EventHandler ondragleave;
+ attribute EventHandler ondragover;
+ attribute EventHandler ondragstart;
+ attribute EventHandler ondrop;
+ attribute EventHandler ondurationchange;
attribute EventHandler onemptied;
+ attribute EventHandler onended;
attribute OnErrorEventHandler onerror;
+ attribute EventHandler onfocus;
attribute EventHandler oninput;
+ attribute EventHandler oninvalid;
attribute EventHandler onkeydown;
attribute EventHandler onkeypress;
attribute EventHandler onkeyup;
attribute EventHandler onload;
attribute EventHandler onloadeddata;
attribute EventHandler onloadedmetadata;
+ attribute EventHandler onloadstart;
+ attribute EventHandler onmousedown;
+ [LenientThis] attribute EventHandler onmouseenter;
+ [LenientThis] attribute EventHandler onmouseleave;
+ attribute EventHandler onmousemove;
+ attribute EventHandler onmouseout;
attribute EventHandler onmouseover;
+ attribute EventHandler onmouseup;
+ attribute EventHandler onwheel;
attribute EventHandler onpause;
attribute EventHandler onplay;
attribute EventHandler onplaying;
attribute EventHandler onprogress;
+ attribute EventHandler onratechange;
attribute EventHandler onreset;
attribute EventHandler onresize;
+ attribute EventHandler onscroll;
+ attribute EventHandler onseeked;
+ attribute EventHandler onseeking;
+ attribute EventHandler onselect;
+ attribute EventHandler onshow;
+ attribute EventHandler onstalled;
attribute EventHandler onsubmit;
attribute EventHandler onsuspend;
attribute EventHandler ontimeupdate;
attribute EventHandler ontoggle;
+ attribute EventHandler onvolumechange;
attribute EventHandler onwaiting;
};
// https://html.spec.whatwg.org/multipage/#windoweventhandlers
[NoInterfaceObject]
interface WindowEventHandlers {
- attribute EventHandler onunload;
+ attribute EventHandler onafterprint;
+ attribute EventHandler onbeforeprint;
+ attribute OnBeforeUnloadEventHandler onbeforeunload;
+ attribute EventHandler onhashchange;
+ attribute EventHandler onlanguagechange;
+ attribute EventHandler onmessage;
+ attribute EventHandler onoffline;
+ attribute EventHandler ononline;
+ attribute EventHandler onpagehide;
+ attribute EventHandler onpageshow;
+ attribute EventHandler onpopstate;
+ attribute EventHandler onrejectionhandled;
attribute EventHandler onstorage;
+ attribute EventHandler onunhandledrejection;
+ attribute EventHandler onunload;
+};
+
+// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
+[NoInterfaceObject]
+interface DocumentAndElementEventHandlers {
+ attribute EventHandler oncopy;
+ attribute EventHandler oncut;
+ attribute EventHandler onpaste;
};
diff --git a/components/script/dom/webidls/HTMLElement.webidl b/components/script/dom/webidls/HTMLElement.webidl
index 9778985dd40..19222109d63 100644
--- a/components/script/dom/webidls/HTMLElement.webidl
+++ b/components/script/dom/webidls/HTMLElement.webidl
@@ -54,5 +54,6 @@ partial interface HTMLElement {
};
HTMLElement implements GlobalEventHandlers;
+HTMLElement implements DocumentAndElementEventHandlers;
HTMLElement implements ElementContentEditable;
HTMLElement implements ElementCSSInlineStyle;
diff --git a/components/script/dom/webidls/HTMLFrameSetElement.webidl b/components/script/dom/webidls/HTMLFrameSetElement.webidl
index f35de93e545..5addd41d253 100644
--- a/components/script/dom/webidls/HTMLFrameSetElement.webidl
+++ b/components/script/dom/webidls/HTMLFrameSetElement.webidl
@@ -7,4 +7,5 @@ interface HTMLFrameSetElement : HTMLElement {
// attribute DOMString cols;
// attribute DOMString rows;
};
-//HTMLFrameSetElement implements WindowEventHandlers;
+
+HTMLFrameSetElement implements WindowEventHandlers;
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 7eab91db3a4..8fdb7049715 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -7,7 +7,9 @@ use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarker
use dom::bindings::callback::ExceptionHandling;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
-use dom::bindings::codegen::Bindings::EventHandlerBinding::{EventHandlerNonNull, OnErrorEventHandlerNonNull};
+use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
+use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHandlerNonNull;
+use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
@@ -45,10 +47,10 @@ use libc;
use msg::constellation_msg::{LoadData, PanicMsg, PipelineId, SubpageId};
use msg::constellation_msg::{WindowSizeData, WindowSizeType};
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
-use net_traits::ResourceThreads;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::storage_thread::StorageType;
+use net_traits::{ResourceThreads, CustomResponseSender};
use num_traits::ToPrimitive;
use profile_traits::mem;
use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
@@ -148,6 +150,8 @@ pub struct Window {
image_cache_thread: ImageCacheThread,
#[ignore_heap_size_of = "channels are hard"]
image_cache_chan: ImageCacheChan,
+ #[ignore_heap_size_of = "channels are hard"]
+ custom_message_chan: IpcSender<CustomResponseSender>,
#[ignore_heap_size_of = "TODO(#6911) newtypes containing unmeasurable types are hard"]
compositor: IpcSender<ScriptToCompositorMsg>,
browsing_context: MutNullableHeap<JS<BrowsingContext>>,
@@ -303,6 +307,10 @@ impl Window {
self.image_cache_chan.clone()
}
+ pub fn custom_message_chan(&self) -> IpcSender<CustomResponseSender> {
+ self.custom_message_chan.clone()
+ }
+
pub fn get_next_worker_id(&self) -> WorkerId {
let worker_id = self.next_worker_id.get();
let WorkerId(id_num) = worker_id;
@@ -585,11 +593,8 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
global_event_handlers!();
- // https://html.spec.whatwg.org/multipage/#handler-window-onunload
- event_handler!(unload, GetOnunload, SetOnunload);
-
- // https://html.spec.whatwg.org/multipage/#handler-window-onstorage
- event_handler!(storage, GetOnstorage, SetOnstorage);
+ // https://html.spec.whatwg.org/multipage/#windoweventhandlers
+ window_event_handlers!();
// https://developer.mozilla.org/en-US/docs/Web/API/Window/screen
fn Screen(&self) -> Root<Screen> {
@@ -1443,6 +1448,7 @@ impl Window {
history_task_source: HistoryTraversalTaskSource,
file_task_source: FileReadingTaskSource,
image_cache_chan: ImageCacheChan,
+ custom_message_chan: IpcSender<CustomResponseSender>,
compositor: IpcSender<ScriptToCompositorMsg>,
image_cache_thread: ImageCacheThread,
resource_threads: ResourceThreads,
@@ -1480,6 +1486,7 @@ impl Window {
history_traversal_task_source: history_task_source,
file_reading_task_source: file_task_source,
image_cache_chan: image_cache_chan,
+ custom_message_chan: custom_message_chan,
console: Default::default(),
crypto: Default::default(),
compositor: compositor,
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 661d397460f..f7900a0d0f0 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -24,10 +24,13 @@ use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
use js::jsapi::{JSAutoCompartment, JS_RequestInterruptCallback};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
+use msg::constellation_msg::{PipelineId, ReferrerPolicy};
+use net_traits::{RequestSource, LoadOrigin};
use script_thread::Runnable;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Sender, channel};
use std::sync::{Arc, Mutex};
+use url::Url;
use util::str::DOMString;
pub type TrustedWorkerAddress = Trusted<Worker>;
@@ -45,6 +48,29 @@ pub struct Worker {
runtime: Arc<Mutex<Option<SharedRt>>>
}
+#[derive(Clone)]
+pub struct WorkerScriptLoadOrigin {
+ referrer_url: Option<Url>,
+ referrer_policy: Option<ReferrerPolicy>,
+ request_source: RequestSource,
+ pipeline_id: Option<PipelineId>
+}
+
+impl LoadOrigin for WorkerScriptLoadOrigin {
+ fn referrer_url(&self) -> Option<Url> {
+ self.referrer_url.clone()
+ }
+ fn referrer_policy(&self) -> Option<ReferrerPolicy> {
+ self.referrer_policy.clone()
+ }
+ fn request_source(&self) -> RequestSource {
+ self.request_source.clone()
+ }
+ fn pipeline_id(&self) -> Option<PipelineId> {
+ self.pipeline_id.clone()
+ }
+}
+
impl Worker {
fn new_inherited(sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
closing: Arc<AtomicBool>) -> Worker {
@@ -82,6 +108,13 @@ impl Worker {
let worker_ref = Trusted::new(worker.r());
let worker_id = global.get_next_worker_id();
+ let worker_load_origin = WorkerScriptLoadOrigin {
+ referrer_url: None,
+ referrer_policy: None,
+ request_source: global.request_source(),
+ pipeline_id: Some(global.pipeline())
+ };
+
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
let optional_sender = match global.devtools_chan() {
Some(ref chan) => {
@@ -114,7 +147,7 @@ impl Worker {
DedicatedWorkerGlobalScope::run_worker_scope(
init, worker_url, global.pipeline(), devtools_receiver, worker.runtime.clone(), worker_ref,
- global.script_chan(), sender, receiver);
+ global.script_chan(), sender, receiver, worker_load_origin);
Ok(worker)
}
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index ef9afd34cf7..a8b5d9a48c3 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -17,12 +17,13 @@ use dom::eventtarget::EventTarget;
use dom::window::{base64_atob, base64_btoa};
use dom::workerlocation::WorkerLocation;
use dom::workernavigator::WorkerNavigator;
-use ipc_channel::ipc::IpcSender;
+use ipc_channel::ipc::{self, IpcSender};
+use ipc_channel::router::ROUTER;
use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
-use msg::constellation_msg::{PanicMsg, PipelineId};
-use net_traits::{LoadContext, CoreResourceThread, load_whole_resource};
+use msg::constellation_msg::{PipelineId, ReferrerPolicy, PanicMsg};
+use net_traits::{LoadContext, CoreResourceThread, load_whole_resource, RequestSource, LoadOrigin, CustomResponseSender};
use profile_traits::{mem, time};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
use script_traits::ScriptMsg as ConstellationMsg;
@@ -101,6 +102,12 @@ pub struct WorkerGlobalScope {
#[ignore_heap_size_of = "Defined in ipc-channel"]
panic_chan: IpcSender<PanicMsg>,
+
+ #[ignore_heap_size_of = "Defined in ipc-channel"]
+ custom_msg_chan: IpcSender<CustomResponseSender>,
+
+ #[ignore_heap_size_of = "Defined in std"]
+ custom_msg_port: Receiver<CustomResponseSender>,
}
impl WorkerGlobalScope {
@@ -110,7 +117,8 @@ impl WorkerGlobalScope {
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
timer_event_chan: IpcSender<TimerEvent>)
-> WorkerGlobalScope {
-
+ let (msg_chan, msg_port) = ipc::channel().unwrap();
+ let custom_msg_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(msg_port);
WorkerGlobalScope {
eventtarget: EventTarget::new_inherited(),
next_worker_id: Cell::new(WorkerId(0)),
@@ -133,6 +141,8 @@ impl WorkerGlobalScope {
constellation_chan: init.constellation_chan,
scheduler_chan: init.scheduler_chan,
panic_chan: init.panic_chan,
+ custom_msg_chan: msg_chan,
+ custom_msg_port: custom_msg_port
}
}
@@ -182,6 +192,14 @@ impl WorkerGlobalScope {
self.runtime.cx()
}
+ pub fn custom_message_chan(&self) -> IpcSender<CustomResponseSender> {
+ self.custom_msg_chan.clone()
+ }
+
+ pub fn custom_message_port(&self) -> &Receiver<CustomResponseSender> {
+ &self.custom_msg_port
+ }
+
pub fn is_closing(&self) -> bool {
self.closing.load(Ordering::SeqCst)
}
@@ -210,6 +228,21 @@ impl WorkerGlobalScope {
}
}
+impl LoadOrigin for WorkerGlobalScope {
+ fn referrer_url(&self) -> Option<Url> {
+ None
+ }
+ fn referrer_policy(&self) -> Option<ReferrerPolicy> {
+ None
+ }
+ fn request_source(&self) -> RequestSource {
+ RequestSource::None
+ }
+ fn pipeline_id(&self) -> Option<PipelineId> {
+ Some(self.pipeline())
+ }
+}
+
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
fn Self_(&self) -> Root<WorkerGlobalScope> {
@@ -236,7 +269,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
let mut rval = RootedValue::new(self.runtime.cx(), UndefinedValue());
for url in urls {
- let (url, source) = match load_whole_resource(LoadContext::Script, &self.core_resource_thread, url, None) {
+ let (url, source) = match load_whole_resource(LoadContext::Script, &self.core_resource_thread, url, self) {
Err(_) => return Err(Error::Network),
Ok((metadata, bytes)) => {
(metadata.final_url, String::from_utf8(bytes).unwrap())
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index b72d5995b20..567db277b8f 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -44,9 +44,10 @@ use ipc_channel::router::ROUTER;
use js::jsapi::JS_ClearPendingException;
use js::jsapi::{JSContext, JS_ParseJSON, RootedValue};
use js::jsval::{JSVal, NullValue, UndefinedValue};
+use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::CoreResourceMsg::Load;
-use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError};
-use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread};
+use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError, RequestSource};
+use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread, LoadOrigin};
use network_listener::{NetworkListener, PreInvoke};
use parse::html::{ParseContext, parse_html};
use parse::xml::{self, parse_xml};
@@ -295,6 +296,26 @@ impl XMLHttpRequest {
}
}
+impl LoadOrigin for XMLHttpRequest {
+ fn referrer_url(&self) -> Option<Url> {
+ None
+ }
+ fn referrer_policy(&self) -> Option<ReferrerPolicy> {
+ None
+ }
+ fn request_source(&self) -> RequestSource {
+ if self.sync.get() {
+ RequestSource::None
+ } else {
+ self.global().r().request_source()
+ }
+ }
+ fn pipeline_id(&self) -> Option<PipelineId> {
+ let global = self.global();
+ Some(global.r().pipeline())
+ }
+}
+
impl XMLHttpRequestMethods for XMLHttpRequest {
// https://xhr.spec.whatwg.org/#handler-xhr-onreadystatechange
event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange);
@@ -572,14 +593,11 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// Step 5
let global = self.global();
- let pipeline_id = global.r().pipeline();
//TODO - set referrer_policy/referrer_url in load_data
let mut load_data =
LoadData::new(LoadContext::Browsing,
self.request_url.borrow().clone().unwrap(),
- Some(pipeline_id),
- None,
- None);
+ self);
if load_data.url.origin().ne(&global.r().get_url().origin()) {
load_data.credentials_flag = self.WithCredentials();
}
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 8f43e1b1bfc..f7bb765651d 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -65,8 +65,8 @@ use msg::webdriver_msg::WebDriverScriptCommand;
use net_traits::LoadData as NetLoadData;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
-use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata};
-use net_traits::{ResourceThreads, IpcSend};
+use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata, ResourceThreads};
+use net_traits::{RequestSource, CustomResponse, CustomResponseSender, IpcSend};
use network_listener::NetworkListener;
use parse::ParserRoot;
use parse::html::{ParseContext, parse_html};
@@ -205,6 +205,7 @@ enum MixedMessage {
FromDevtools(DevtoolScriptControlMsg),
FromImageCache(ImageCacheResult),
FromScheduler(TimerEvent),
+ FromNetwork(IpcSender<Option<CustomResponse>>),
}
/// Messages used to control the script event loop
@@ -321,6 +322,12 @@ pub struct ScriptThread {
/// events in the event queue.
chan: MainThreadScriptChan,
+ /// A handle to network event messages
+ custom_message_chan: IpcSender<CustomResponseSender>,
+
+ /// The port which receives a sender from the network
+ custom_message_port: Receiver<CustomResponseSender>,
+
dom_manipulation_task_source: DOMManipulationTaskSource,
user_interaction_task_source: UserInteractionTaskSource,
@@ -536,6 +543,9 @@ impl ScriptThread {
let (ipc_devtools_sender, ipc_devtools_receiver) = ipc::channel().unwrap();
let devtools_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_devtools_receiver);
+ let (ipc_custom_resp_chan, ipc_custom_resp_port) = ipc::channel().unwrap();
+ let custom_msg_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_custom_resp_port);
+
// Ask the router to proxy IPC messages from the image cache thread to us.
let (ipc_image_cache_channel, ipc_image_cache_port) = ipc::channel().unwrap();
let image_cache_port =
@@ -558,6 +568,9 @@ impl ScriptThread {
bluetooth_thread: state.bluetooth_thread,
port: port,
+ custom_message_chan: ipc_custom_resp_chan,
+ custom_message_port: custom_msg_port,
+
chan: MainThreadScriptChan(chan.clone()),
dom_manipulation_task_source: DOMManipulationTaskSource(chan.clone()),
user_interaction_task_source: UserInteractionTaskSource(chan.clone()),
@@ -619,7 +632,8 @@ impl ScriptThread {
/// Handle incoming control messages.
fn handle_msgs(&self) -> bool {
- use self::MixedMessage::{FromScript, FromConstellation, FromScheduler, FromDevtools, FromImageCache};
+ use self::MixedMessage::{FromConstellation, FromDevtools, FromImageCache};
+ use self::MixedMessage::{FromScheduler, FromScript, FromNetwork};
// Handle pending resize events.
// Gather them first to avoid a double mut borrow on self.
@@ -653,6 +667,7 @@ impl ScriptThread {
let mut timer_event_port = sel.handle(&self.timer_event_port);
let mut devtools_port = sel.handle(&self.devtools_port);
let mut image_cache_port = sel.handle(&self.image_cache_port);
+ let mut custom_message_port = sel.handle(&self.custom_message_port);
unsafe {
script_port.add();
control_port.add();
@@ -661,6 +676,7 @@ impl ScriptThread {
devtools_port.add();
}
image_cache_port.add();
+ custom_message_port.add();
}
let ret = sel.wait();
if ret == script_port.id() {
@@ -673,6 +689,8 @@ impl ScriptThread {
FromDevtools(self.devtools_port.recv().unwrap())
} else if ret == image_cache_port.id() {
FromImageCache(self.image_cache_port.recv().unwrap())
+ } else if ret == custom_message_port.id() {
+ FromNetwork(self.custom_message_port.recv().unwrap())
} else {
panic!("unexpected select result")
}
@@ -735,7 +753,10 @@ impl ScriptThread {
Err(_) => match self.timer_event_port.try_recv() {
Err(_) => match self.devtools_port.try_recv() {
Err(_) => match self.image_cache_port.try_recv() {
- Err(_) => break,
+ Err(_) => match self.custom_message_port.try_recv() {
+ Err(_) => break,
+ Ok(ev) => event = FromNetwork(ev)
+ },
Ok(ev) => event = FromImageCache(ev),
},
Ok(ev) => event = FromDevtools(ev),
@@ -761,6 +782,7 @@ impl ScriptThread {
},
FromConstellation(inner_msg) => self.handle_msg_from_constellation(inner_msg),
FromScript(inner_msg) => self.handle_msg_from_script(inner_msg),
+ FromNetwork(inner_msg) => self.handle_msg_from_network(inner_msg),
FromScheduler(inner_msg) => self.handle_timer_event(inner_msg),
FromDevtools(inner_msg) => self.handle_msg_from_devtools(inner_msg),
FromImageCache(inner_msg) => self.handle_msg_from_image_cache(inner_msg),
@@ -820,6 +842,7 @@ impl ScriptThread {
}
},
MixedMessage::FromScheduler(_) => ScriptThreadEventCategory::TimerEvent,
+ MixedMessage::FromNetwork(_) => ScriptThreadEventCategory::NetworkEvent
}
}
@@ -989,6 +1012,12 @@ impl ScriptThread {
msg.responder.unwrap().respond(msg.image_response);
}
+ fn handle_msg_from_network(&self, msg: IpcSender<Option<CustomResponse>>) {
+ // We may detect controlling service workers here
+ // We send None as default
+ let _ = msg.send(None);
+ }
+
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
let context = self.root_browsing_context();
match msg {
@@ -1437,6 +1466,7 @@ impl ScriptThread {
HistoryTraversalTaskSource(history_sender.clone()),
FileReadingTaskSource(file_sender.clone()),
self.image_cache_channel.clone(),
+ self.custom_message_chan.clone(),
self.compositor.borrow_mut().clone(),
self.image_cache_thread.clone(),
self.resource_threads.clone(),
@@ -1905,6 +1935,7 @@ impl ScriptThread {
credentials_flag: true,
referrer_policy: load_data.referrer_policy,
referrer_url: load_data.referrer_url,
+ source: RequestSource::Window(self.custom_message_chan.clone())
}, LoadConsumer::Listener(response_target), None)).unwrap();
self.incomplete_loads.borrow_mut().push(incomplete);