mirror of
https://github.com/servo/servo.git
synced 2025-07-24 07:40:27 +01:00
Persuading devtools to communicate with the workers; r=jdm
This commit is contained in:
parent
4de6e699b2
commit
79b65402d7
7 changed files with 161 additions and 56 deletions
|
@ -12,6 +12,7 @@ use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
|
||||||
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||||
use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods};
|
use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods};
|
||||||
use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods};
|
use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods};
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::node::{Node, NodeHelpers};
|
use dom::node::{Node, NodeHelpers};
|
||||||
use dom::window::{WindowHelpers, ScriptHelpers};
|
use dom::window::{WindowHelpers, ScriptHelpers};
|
||||||
use dom::document::DocumentHelpers;
|
use dom::document::DocumentHelpers;
|
||||||
|
@ -24,18 +25,10 @@ use js::jsval::UndefinedValue;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<EvaluateJSReply>) {
|
||||||
pub fn handle_evaluate_js(
|
let cx = global.get_cx();
|
||||||
page: &Rc<Page>,
|
|
||||||
pipeline: PipelineId,
|
|
||||||
eval: String,
|
|
||||||
reply: IpcSender<EvaluateJSReply>
|
|
||||||
) {
|
|
||||||
let page = get_page(&*page, pipeline);
|
|
||||||
let window = page.window();
|
|
||||||
let cx = window.r().get_cx();
|
|
||||||
let mut rval = RootedValue::new(cx, UndefinedValue());
|
let mut rval = RootedValue::new(cx, UndefinedValue());
|
||||||
window.r().evaluate_js_on_global_with_result(&eval, rval.handle_mut());
|
global.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
|
||||||
|
|
||||||
reply.send(if rval.ptr.is_undefined() {
|
reply.send(if rval.ptr.is_undefined() {
|
||||||
EvaluateJSReply::VoidValue
|
EvaluateJSReply::VoidValue
|
||||||
|
@ -43,8 +36,7 @@ pub fn handle_evaluate_js(
|
||||||
EvaluateJSReply::BooleanValue(rval.ptr.to_boolean())
|
EvaluateJSReply::BooleanValue(rval.ptr.to_boolean())
|
||||||
} else if rval.ptr.is_double() || rval.ptr.is_int32() {
|
} else if rval.ptr.is_double() || rval.ptr.is_int32() {
|
||||||
EvaluateJSReply::NumberValue(
|
EvaluateJSReply::NumberValue(
|
||||||
FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap()
|
FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap())
|
||||||
)
|
|
||||||
} else if rval.ptr.is_string() {
|
} else if rval.ptr.is_string() {
|
||||||
//FIXME: use jsstring_to_str when jsval grows to_jsstring
|
//FIXME: use jsstring_to_str when jsval grows to_jsstring
|
||||||
EvaluateJSReply::StringValue(
|
EvaluateJSReply::StringValue(
|
||||||
|
@ -165,10 +157,8 @@ pub fn handle_modify_attribute(page: &Rc<Page>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_wants_live_notifications(page: &Rc<Page>, pipeline_id: PipelineId, send_notifications: bool) {
|
pub fn handle_wants_live_notifications(global: &GlobalRef, send_notifications: bool) {
|
||||||
let page = get_page(&*page, pipeline_id);
|
global.set_devtools_wants_updates(send_notifications);
|
||||||
let window = page.window();
|
|
||||||
window.r().set_devtools_wants_updates(send_notifications);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_set_timeline_markers(page: &Rc<Page>,
|
pub fn handle_set_timeline_markers(page: &Rc<Page>,
|
||||||
|
|
|
@ -13,7 +13,7 @@ use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::document::DocumentHelpers;
|
use dom::document::DocumentHelpers;
|
||||||
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
|
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
|
||||||
use dom::window::{self, WindowHelpers};
|
use dom::window::{self, WindowHelpers, ScriptHelpers};
|
||||||
use devtools_traits::ScriptToDevtoolsControlMsg;
|
use devtools_traits::ScriptToDevtoolsControlMsg;
|
||||||
use script_task::{ScriptChan, ScriptPort, ScriptMsg, ScriptTask};
|
use script_task::{ScriptChan, ScriptPort, ScriptMsg, ScriptTask};
|
||||||
|
|
||||||
|
@ -24,8 +24,7 @@ use profile_traits::mem;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
||||||
use js::jsapi::{GetGlobalForObjectCrossCompartment};
|
use js::jsapi::{GetGlobalForObjectCrossCompartment};
|
||||||
use js::jsapi::{JSContext, JSObject};
|
use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
|
||||||
use js::jsapi::{JS_GetClass};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
/// A freely-copyable reference to a rooted global object.
|
/// A freely-copyable reference to a rooted global object.
|
||||||
|
@ -165,6 +164,23 @@ impl<'a> GlobalRef<'a> {
|
||||||
GlobalRef::Worker(ref worker) => worker.process_event(msg),
|
GlobalRef::Worker(ref worker) => worker.process_event(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Evaluate the JS messages on the `RootedValue` of this global
|
||||||
|
pub fn evaluate_js_on_global_with_result(&self, code: &str, rval: MutableHandleValue) {
|
||||||
|
match *self {
|
||||||
|
GlobalRef::Window(window) => window.evaluate_js_on_global_with_result(code, rval),
|
||||||
|
GlobalRef::Worker(worker) => worker.evaluate_js_on_global_with_result(code, rval),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the `bool` value to indicate whether developer tools has requested
|
||||||
|
/// updates from the global
|
||||||
|
pub fn set_devtools_wants_updates(&self, send_updates: bool) {
|
||||||
|
match *self {
|
||||||
|
GlobalRef::Window(window) => window.set_devtools_wants_updates(send_updates),
|
||||||
|
GlobalRef::Worker(worker) => worker.set_devtools_wants_updates(send_updates),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Reflectable for GlobalRef<'a> {
|
impl<'a> Reflectable for GlobalRef<'a> {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use devtools;
|
||||||
use dom::bindings::cell::DOMRefCell;
|
use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding;
|
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding;
|
||||||
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods;
|
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods;
|
||||||
|
@ -26,7 +27,7 @@ use script_task::StackRootTLS;
|
||||||
|
|
||||||
use msg::constellation_msg::{ConstellationChan, PipelineId};
|
use msg::constellation_msg::{ConstellationChan, PipelineId};
|
||||||
|
|
||||||
use devtools_traits::ScriptToDevtoolsControlMsg;
|
use devtools_traits::{ScriptToDevtoolsControlMsg, DevtoolScriptControlMsg};
|
||||||
|
|
||||||
use net_traits::{load_whole_resource, ResourceTask};
|
use net_traits::{load_whole_resource, ResourceTask};
|
||||||
use profile_traits::mem::{self, Reporter, ReporterRequest};
|
use profile_traits::mem::{self, Reporter, ReporterRequest};
|
||||||
|
@ -34,7 +35,7 @@ use util::task::spawn_named;
|
||||||
use util::task_state;
|
use util::task_state;
|
||||||
use util::task_state::{SCRIPT, IN_WORKER};
|
use util::task_state::{SCRIPT, IN_WORKER};
|
||||||
|
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender, IpcReceiver};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use js::jsapi::{JSContext, RootedValue, HandleValue};
|
use js::jsapi::{JSContext, RootedValue, HandleValue};
|
||||||
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
|
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
|
||||||
|
@ -45,7 +46,7 @@ use url::Url;
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
use std::sync::mpsc::{Sender, Receiver, channel, Select};
|
||||||
|
|
||||||
/// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with
|
/// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with
|
||||||
/// every message. While this SendableWorkerScriptChan is alive, the associated Worker object
|
/// every message. While this SendableWorkerScriptChan is alive, the associated Worker object
|
||||||
|
@ -110,6 +111,8 @@ impl DedicatedWorkerGlobalScope {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||||
|
devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||||
|
devtools_port: Receiver<DevtoolScriptControlMsg>,
|
||||||
runtime: Rc<Runtime>,
|
runtime: Rc<Runtime>,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
|
@ -119,8 +122,8 @@ impl DedicatedWorkerGlobalScope {
|
||||||
-> DedicatedWorkerGlobalScope {
|
-> DedicatedWorkerGlobalScope {
|
||||||
DedicatedWorkerGlobalScope {
|
DedicatedWorkerGlobalScope {
|
||||||
workerglobalscope: WorkerGlobalScope::new_inherited(
|
workerglobalscope: WorkerGlobalScope::new_inherited(
|
||||||
WorkerGlobalScopeTypeId::DedicatedGlobalScope, worker_url,
|
WorkerGlobalScopeTypeId::DedicatedGlobalScope, worker_url, runtime, resource_task,
|
||||||
runtime, resource_task, mem_profiler_chan, devtools_chan, constellation_chan),
|
mem_profiler_chan, devtools_chan, devtools_sender, devtools_port, constellation_chan),
|
||||||
id: id,
|
id: id,
|
||||||
receiver: receiver,
|
receiver: receiver,
|
||||||
own_sender: own_sender,
|
own_sender: own_sender,
|
||||||
|
@ -133,6 +136,8 @@ impl DedicatedWorkerGlobalScope {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||||
|
devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||||
|
devtools_port: Receiver<DevtoolScriptControlMsg>,
|
||||||
runtime: Rc<Runtime>,
|
runtime: Rc<Runtime>,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
|
@ -141,17 +146,20 @@ impl DedicatedWorkerGlobalScope {
|
||||||
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
|
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
|
||||||
-> Root<DedicatedWorkerGlobalScope> {
|
-> Root<DedicatedWorkerGlobalScope> {
|
||||||
let scope = box DedicatedWorkerGlobalScope::new_inherited(
|
let scope = box DedicatedWorkerGlobalScope::new_inherited(
|
||||||
worker_url, id, mem_profiler_chan, devtools_chan, runtime.clone(), resource_task,
|
worker_url, id, mem_profiler_chan, devtools_chan, devtools_sender, devtools_port,
|
||||||
constellation_chan, parent_sender, own_sender, receiver);
|
runtime.clone(), resource_task, constellation_chan, parent_sender, own_sender, receiver);
|
||||||
DedicatedWorkerGlobalScopeBinding::Wrap(runtime.cx(), scope)
|
DedicatedWorkerGlobalScopeBinding::Wrap(runtime.cx(), scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DedicatedWorkerGlobalScope {
|
impl DedicatedWorkerGlobalScope {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn run_worker_scope(worker_url: Url,
|
pub fn run_worker_scope(worker_url: Url,
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||||
|
devtools_ipc_chan: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||||
|
devtools_ipc_port: IpcReceiver<DevtoolScriptControlMsg>,
|
||||||
worker: TrustedWorkerAddress,
|
worker: TrustedWorkerAddress,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
|
@ -180,11 +188,16 @@ impl DedicatedWorkerGlobalScope {
|
||||||
let runtime = Rc::new(ScriptTask::new_rt_and_cx());
|
let runtime = Rc::new(ScriptTask::new_rt_and_cx());
|
||||||
let serialized_url = url.serialize();
|
let serialized_url = url.serialize();
|
||||||
let parent_sender_for_reporter = parent_sender.clone();
|
let parent_sender_for_reporter = parent_sender.clone();
|
||||||
|
|
||||||
|
let (devtools_mpsc_chan, devtools_mpsc_port) = channel();
|
||||||
|
ROUTER.route_ipc_receiver_to_mpsc_sender(devtools_ipc_port, devtools_mpsc_chan);
|
||||||
|
|
||||||
let global = DedicatedWorkerGlobalScope::new(
|
let global = DedicatedWorkerGlobalScope::new(
|
||||||
url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(),
|
url, id, mem_profiler_chan.clone(), devtools_chan, devtools_ipc_chan, devtools_mpsc_port,
|
||||||
resource_task, constellation_chan, parent_sender, own_sender, receiver);
|
runtime.clone(), resource_task, constellation_chan, parent_sender, own_sender, receiver);
|
||||||
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
|
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
|
||||||
// registration (#6631), so we instead use a random number and cross our fingers.
|
// registration (#6631), so we instead use a random number and cross our fingers.
|
||||||
|
let scope = WorkerGlobalScopeCast::from_ref(global.r());
|
||||||
let reporter_name = format!("worker-reporter-{}", random::<u64>());
|
let reporter_name = format!("worker-reporter-{}", random::<u64>());
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -216,13 +229,58 @@ impl DedicatedWorkerGlobalScope {
|
||||||
Reporter(reporter_sender)));
|
Reporter(reporter_sender)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MixedMessage {
|
||||||
|
FromWorker((TrustedWorkerAddress, ScriptMsg)),
|
||||||
|
FromDevtools(DevtoolScriptControlMsg),
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match global.r().receiver.recv() {
|
let worker_port = &global.r().receiver;
|
||||||
Ok((linked_worker, msg)) => {
|
let devtools_port = scope.devtools_port();
|
||||||
|
|
||||||
|
let event = {
|
||||||
|
let sel = Select::new();
|
||||||
|
let mut worker_handle = sel.handle(worker_port);
|
||||||
|
let mut devtools_handle = sel.handle(devtools_port);
|
||||||
|
unsafe {
|
||||||
|
worker_handle.add();
|
||||||
|
if scope.devtools_sender().is_some() {
|
||||||
|
devtools_handle.add();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ret = sel.wait();
|
||||||
|
if ret == worker_handle.id() {
|
||||||
|
match worker_port.recv() {
|
||||||
|
Ok(stuff) => MixedMessage::FromWorker(stuff),
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
|
} else if ret == devtools_handle.id() {
|
||||||
|
match devtools_port.recv() {
|
||||||
|
Ok(stuff) => MixedMessage::FromDevtools(stuff),
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("unexpected select result!")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match event {
|
||||||
|
MixedMessage::FromDevtools(msg) => {
|
||||||
|
let global_ref = GlobalRef::Worker(scope);
|
||||||
|
match msg {
|
||||||
|
DevtoolScriptControlMsg::EvaluateJS(_pipe_id, string, sender) =>
|
||||||
|
devtools::handle_evaluate_js(&global_ref, string, sender),
|
||||||
|
DevtoolScriptControlMsg::GetCachedMessages(pipe_id, message_types, sender) =>
|
||||||
|
devtools::handle_get_cached_messages(pipe_id, message_types, sender),
|
||||||
|
DevtoolScriptControlMsg::WantsLiveNotifications(_pipe_id, bool_val) =>
|
||||||
|
devtools::handle_wants_live_notifications(&global_ref, bool_val),
|
||||||
|
_ => debug!("got an unusable devtools control message inside the worker!"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MixedMessage::FromWorker((linked_worker, msg)) => {
|
||||||
let _ar = AutoWorkerReset::new(global.r(), linked_worker);
|
let _ar = AutoWorkerReset::new(global.r(), linked_worker);
|
||||||
global.r().handle_event(msg);
|
global.r().handle_event(msg);
|
||||||
}
|
},
|
||||||
Err(_) => break,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,23 +77,28 @@ impl Worker {
|
||||||
let worker = Worker::new(global, sender.clone());
|
let worker = Worker::new(global, sender.clone());
|
||||||
let worker_ref = Trusted::new(global.get_cx(), worker.r(), global.script_chan());
|
let worker_ref = Trusted::new(global.get_cx(), worker.r(), global.script_chan());
|
||||||
|
|
||||||
if let Some(ref chan) = global.devtools_chan() {
|
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
||||||
let pipeline_id = global.pipeline();
|
let optional_sender = match global.devtools_chan() {
|
||||||
let (devtools_sender, _) = ipc::channel().unwrap();
|
Some(ref chan) => {
|
||||||
let title = format!("Worker for {}", worker_url);
|
let pipeline_id = global.pipeline();
|
||||||
let page_info = DevtoolsPageInfo {
|
let title = format!("Worker for {}", worker_url);
|
||||||
title: title,
|
let page_info = DevtoolsPageInfo {
|
||||||
url: worker_url.clone(),
|
title: title,
|
||||||
};
|
url: worker_url.clone(),
|
||||||
let worker_id = global.get_next_worker_id();
|
};
|
||||||
chan.send(ScriptToDevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)),
|
let worker_id = global.get_next_worker_id();
|
||||||
devtools_sender.clone(),
|
chan.send(ScriptToDevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)),
|
||||||
page_info)).unwrap();
|
devtools_sender.clone(),
|
||||||
}
|
page_info)).unwrap();
|
||||||
|
Some(devtools_sender)
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
DedicatedWorkerGlobalScope::run_worker_scope(
|
DedicatedWorkerGlobalScope::run_worker_scope(
|
||||||
worker_url, global.pipeline(), global.mem_profiler_chan(), global.devtools_chan(),
|
worker_url, global.pipeline(), global.mem_profiler_chan(), global.devtools_chan(),
|
||||||
worker_ref, resource_task, constellation_chan, global.script_chan(), sender, receiver);
|
optional_sender, devtools_receiver, worker_ref, resource_task,
|
||||||
|
constellation_chan, global.script_chan(), sender, receiver);
|
||||||
|
|
||||||
Ok(worker)
|
Ok(worker)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use dom::window::{base64_atob, base64_btoa};
|
||||||
use script_task::{ScriptChan, TimerSource, ScriptPort, ScriptMsg};
|
use script_task::{ScriptChan, TimerSource, ScriptPort, ScriptMsg};
|
||||||
use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
|
use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
|
||||||
|
|
||||||
use devtools_traits::ScriptToDevtoolsControlMsg;
|
use devtools_traits::{ScriptToDevtoolsControlMsg, DevtoolScriptControlMsg};
|
||||||
|
|
||||||
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
|
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
|
@ -35,6 +35,7 @@ use url::{Url, UrlParser};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
|
||||||
#[derive(JSTraceable, Copy, Clone, PartialEq)]
|
#[derive(JSTraceable, Copy, Clone, PartialEq)]
|
||||||
pub enum WorkerGlobalScopeTypeId {
|
pub enum WorkerGlobalScopeTypeId {
|
||||||
|
@ -56,6 +57,19 @@ pub struct WorkerGlobalScope {
|
||||||
timers: TimerManager,
|
timers: TimerManager,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||||
|
|
||||||
|
/// Optional `IpcSender` for sending the `DevtoolScriptControlMsg`
|
||||||
|
/// to the server from within the worker
|
||||||
|
devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||||
|
|
||||||
|
/// This `Receiver` will be ignored later if the corresponding
|
||||||
|
/// `IpcSender` doesn't exist
|
||||||
|
devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||||
|
|
||||||
|
/// A flag to indicate whether the developer tools has requested live updates
|
||||||
|
/// from the worker
|
||||||
|
devtools_wants_updates: Cell<bool>,
|
||||||
|
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +80,8 @@ impl WorkerGlobalScope {
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||||
|
devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||||
|
devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||||
constellation_chan: ConstellationChan)
|
constellation_chan: ConstellationChan)
|
||||||
-> WorkerGlobalScope {
|
-> WorkerGlobalScope {
|
||||||
WorkerGlobalScope {
|
WorkerGlobalScope {
|
||||||
|
@ -81,6 +97,9 @@ impl WorkerGlobalScope {
|
||||||
timers: TimerManager::new(),
|
timers: TimerManager::new(),
|
||||||
mem_profiler_chan: mem_profiler_chan,
|
mem_profiler_chan: mem_profiler_chan,
|
||||||
devtools_chan: devtools_chan,
|
devtools_chan: devtools_chan,
|
||||||
|
devtools_sender: devtools_sender,
|
||||||
|
devtools_receiver: devtools_receiver,
|
||||||
|
devtools_wants_updates: Cell::new(false),
|
||||||
constellation_chan: constellation_chan,
|
constellation_chan: constellation_chan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +112,14 @@ impl WorkerGlobalScope {
|
||||||
self.devtools_chan.clone()
|
self.devtools_chan.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn devtools_sender(&self) -> Option<IpcSender<DevtoolScriptControlMsg>> {
|
||||||
|
self.devtools_sender.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn devtools_port(&self) -> &Receiver<DevtoolScriptControlMsg> {
|
||||||
|
&self.devtools_receiver
|
||||||
|
}
|
||||||
|
|
||||||
pub fn constellation_chan(&self) -> ConstellationChan {
|
pub fn constellation_chan(&self) -> ConstellationChan {
|
||||||
self.constellation_chan.clone()
|
self.constellation_chan.clone()
|
||||||
}
|
}
|
||||||
|
@ -251,6 +278,7 @@ pub trait WorkerGlobalScopeHelpers {
|
||||||
fn new_script_pair(self) -> (Box<ScriptChan+Send>, Box<ScriptPort+Send>);
|
fn new_script_pair(self) -> (Box<ScriptChan+Send>, Box<ScriptPort+Send>);
|
||||||
fn process_event(self, msg: ScriptMsg);
|
fn process_event(self, msg: ScriptMsg);
|
||||||
fn get_cx(self) -> *mut JSContext;
|
fn get_cx(self) -> *mut JSContext;
|
||||||
|
fn set_devtools_wants_updates(self, value: bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WorkerGlobalScopeHelpers for &'a WorkerGlobalScope {
|
impl<'a> WorkerGlobalScopeHelpers for &'a WorkerGlobalScope {
|
||||||
|
@ -297,5 +325,8 @@ impl<'a> WorkerGlobalScopeHelpers for &'a WorkerGlobalScope {
|
||||||
fn get_cx(self) -> *mut JSContext {
|
fn get_cx(self) -> *mut JSContext {
|
||||||
self.runtime.cx()
|
self.runtime.cx()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
fn set_devtools_wants_updates(self, value: bool) {
|
||||||
|
self.devtools_wants_updates.set(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -120,4 +120,3 @@ pub fn init() {
|
||||||
|
|
||||||
perform_platform_specific_initialization();
|
perform_platform_specific_initialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, NodeCast, EventCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, NodeCast, EventCast};
|
||||||
use dom::bindings::conversions::FromJSValConvertible;
|
use dom::bindings::conversions::FromJSValConvertible;
|
||||||
use dom::bindings::conversions::StringificationBehavior;
|
use dom::bindings::conversions::StringificationBehavior;
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, RootCollection, trace_roots};
|
use dom::bindings::js::{JS, RootCollection, trace_roots};
|
||||||
use dom::bindings::js::{RootCollectionPtr, Root, RootedReference};
|
use dom::bindings::js::{RootCollectionPtr, Root, RootedReference};
|
||||||
use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference, trace_refcounted_objects};
|
use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference, trace_refcounted_objects};
|
||||||
|
@ -136,7 +137,7 @@ struct InProgressLoad {
|
||||||
window_size: Option<WindowSizeData>,
|
window_size: Option<WindowSizeData>,
|
||||||
/// Channel to the layout task associated with this pipeline.
|
/// Channel to the layout task associated with this pipeline.
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
/// The current viewport clipping rectangle applying to this pipelie, if any.
|
/// The current viewport clipping rectangle applying to this pipeline, if any.
|
||||||
clip_rect: Option<Rect<f32>>,
|
clip_rect: Option<Rect<f32>>,
|
||||||
/// The requested URL of the load.
|
/// The requested URL of the load.
|
||||||
url: Url,
|
url: Url,
|
||||||
|
@ -843,8 +844,11 @@ impl ScriptTask {
|
||||||
fn handle_msg_from_devtools(&self, msg: DevtoolScriptControlMsg) {
|
fn handle_msg_from_devtools(&self, msg: DevtoolScriptControlMsg) {
|
||||||
let page = self.root_page();
|
let page = self.root_page();
|
||||||
match msg {
|
match msg {
|
||||||
DevtoolScriptControlMsg::EvaluateJS(id, s, reply) =>
|
DevtoolScriptControlMsg::EvaluateJS(id, s, reply) => {
|
||||||
devtools::handle_evaluate_js(&page, id, s, reply),
|
let window = get_page(&page, id).window();
|
||||||
|
let global_ref = GlobalRef::Window(window.r());
|
||||||
|
devtools::handle_evaluate_js(&global_ref, s, reply)
|
||||||
|
},
|
||||||
DevtoolScriptControlMsg::GetRootNode(id, reply) =>
|
DevtoolScriptControlMsg::GetRootNode(id, reply) =>
|
||||||
devtools::handle_get_root_node(&page, id, reply),
|
devtools::handle_get_root_node(&page, id, reply),
|
||||||
DevtoolScriptControlMsg::GetDocumentElement(id, reply) =>
|
DevtoolScriptControlMsg::GetDocumentElement(id, reply) =>
|
||||||
|
@ -857,8 +861,11 @@ impl ScriptTask {
|
||||||
devtools::handle_get_cached_messages(pipeline_id, message_types, reply),
|
devtools::handle_get_cached_messages(pipeline_id, message_types, reply),
|
||||||
DevtoolScriptControlMsg::ModifyAttribute(id, node_id, modifications) =>
|
DevtoolScriptControlMsg::ModifyAttribute(id, node_id, modifications) =>
|
||||||
devtools::handle_modify_attribute(&page, id, node_id, modifications),
|
devtools::handle_modify_attribute(&page, id, node_id, modifications),
|
||||||
DevtoolScriptControlMsg::WantsLiveNotifications(pipeline_id, to_send) =>
|
DevtoolScriptControlMsg::WantsLiveNotifications(id, to_send) => {
|
||||||
devtools::handle_wants_live_notifications(&page, pipeline_id, to_send),
|
let window = get_page(&page, id).window();
|
||||||
|
let global_ref = GlobalRef::Window(window.r());
|
||||||
|
devtools::handle_wants_live_notifications(&global_ref, to_send)
|
||||||
|
},
|
||||||
DevtoolScriptControlMsg::SetTimelineMarkers(_pipeline_id, marker_types, reply) =>
|
DevtoolScriptControlMsg::SetTimelineMarkers(_pipeline_id, marker_types, reply) =>
|
||||||
devtools::handle_set_timeline_markers(&page, self, marker_types, reply),
|
devtools::handle_set_timeline_markers(&page, self, marker_types, reply),
|
||||||
DevtoolScriptControlMsg::DropTimelineMarkers(_pipeline_id, marker_types) =>
|
DevtoolScriptControlMsg::DropTimelineMarkers(_pipeline_id, marker_types) =>
|
||||||
|
@ -1828,7 +1835,6 @@ fn shut_down_layout(page_tree: &Rc<Page>, exit_type: PipelineExitType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> {
|
pub fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> {
|
||||||
page.find(pipeline_id).expect("ScriptTask: received an event \
|
page.find(pipeline_id).expect("ScriptTask: received an event \
|
||||||
message for a layout channel that is not associated with this script task.\
|
message for a layout channel that is not associated with this script task.\
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue