diff options
-rw-r--r-- | components/devtools/actors/worker.rs | 26 | ||||
-rw-r--r-- | components/devtools/lib.rs | 24 | ||||
-rw-r--r-- | components/devtools_traits/lib.rs | 4 | ||||
-rw-r--r-- | components/msg/constellation_msg.rs | 3 | ||||
-rw-r--r-- | components/script/dom/bindings/global.rs | 10 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 3 | ||||
-rw-r--r-- | components/script/dom/window.rs | 12 | ||||
-rw-r--r-- | components/script/dom/worker.rs | 21 | ||||
-rw-r--r-- | components/script/dom/workerglobalscope.rs | 12 | ||||
-rw-r--r-- | components/script/script_task.rs | 16 |
10 files changed, 117 insertions, 14 deletions
diff --git a/components/devtools/actors/worker.rs b/components/devtools/actors/worker.rs new file mode 100644 index 00000000000..947d43523d3 --- /dev/null +++ b/components/devtools/actors/worker.rs @@ -0,0 +1,26 @@ +/* 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 actor::{Actor, ActorRegistry}; +use rustc_serialize::json; +use std::net::TcpStream; +use msg::constellation_msg::WorkerId; + +pub struct WorkerActor { + pub name: String, + pub id: WorkerId, +} + +impl Actor for WorkerActor { + fn name(&self) -> String { + self.name.clone() + } + fn handle_message(&self, + _: &ActorRegistry, + _: &str, + _: &json::Object, + _: &mut TcpStream) -> Result<bool, ()> { + Ok(true) + } +} diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 4ae572e3100..aade2baa41d 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -30,6 +30,7 @@ extern crate util; use actor::{Actor, ActorRegistry}; use actors::console::ConsoleActor; +use actors::worker::WorkerActor; use actors::inspector::InspectorActor; use actors::root::RootActor; use actors::tab::TabActor; @@ -37,7 +38,7 @@ use protocol::JsonPacketStream; use devtools_traits::{ConsoleMessage, DevtoolsControlMsg}; use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg}; -use msg::constellation_msg::PipelineId; +use msg::constellation_msg::{PipelineId, WorkerId}; use util::task::spawn_named; use std::borrow::ToOwned; @@ -55,6 +56,7 @@ mod actors { pub mod inspector; pub mod root; pub mod tab; + pub mod worker; } mod protocol; @@ -107,6 +109,7 @@ fn run_server(sender: Sender<DevtoolsControlMsg>, let mut actor_pipelines: HashMap<PipelineId, String> = HashMap::new(); + /// Process the input from a single devtools client until EOF. fn handle_client(actors: Arc<Mutex<ActorRegistry>>, mut stream: TcpStream) { println!("connection established to {}", stream.peer_addr().unwrap()); @@ -142,12 +145,16 @@ fn run_server(sender: Sender<DevtoolsControlMsg>, // clients can theoretically connect to multiple globals simultaneously. // TODO: move this into the root or tab modules? fn handle_new_global(actors: Arc<Mutex<ActorRegistry>>, - pipeline: PipelineId, + ids: (PipelineId, Option<WorkerId>), scriptSender: Sender<DevtoolScriptControlMsg>, actor_pipelines: &mut HashMap<PipelineId, String>, page_info: DevtoolsPageInfo) { let mut actors = actors.lock().unwrap(); + let (pipeline, worker_id) = ids; + + let mut actor_workers: HashMap<(PipelineId, WorkerId), String> = HashMap::new(); + //TODO: move all this actor creation into a constructor method on TabActor let (tab, console, inspector) = { let console = ConsoleActor { @@ -179,6 +186,15 @@ fn run_server(sender: Sender<DevtoolsControlMsg>, (tab, console, inspector) }; + if let Some(id) = worker_id { + let worker = WorkerActor { + name: actors.new_name("worker"), + id: id, + }; + actor_workers.insert((pipeline, id), worker.name.clone()); + actors.register(box worker); + } + actor_pipelines.insert(pipeline, tab.name.clone()); actors.register(box tab); actors.register(box console); @@ -241,8 +257,8 @@ fn run_server(sender: Sender<DevtoolsControlMsg>, }) } Ok(DevtoolsControlMsg::ServerExitMsg) | Err(RecvError) => break, - Ok(DevtoolsControlMsg::NewGlobal(id, scriptSender, pageinfo)) => - handle_new_global(actors.clone(), id, scriptSender, &mut actor_pipelines, + Ok(DevtoolsControlMsg::NewGlobal(ids, scriptSender, pageinfo)) => + handle_new_global(actors.clone(), ids, scriptSender, &mut actor_pipelines, pageinfo), Ok(DevtoolsControlMsg::SendConsoleMessage(id, console_message)) => handle_console_message(actors.clone(), id, console_message, diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index 209b29d6ec5..eb6601baf18 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -20,7 +20,7 @@ extern crate url; extern crate util; use rustc_serialize::{Decodable, Decoder}; -use msg::constellation_msg::PipelineId; +use msg::constellation_msg::{PipelineId, WorkerId}; use util::str::DOMString; use url::Url; @@ -41,7 +41,7 @@ pub struct DevtoolsPageInfo { /// according to changes in the browser. pub enum DevtoolsControlMsg { AddClient(TcpStream), - NewGlobal(PipelineId, Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo), + NewGlobal((PipelineId, Option<WorkerId>), Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo), SendConsoleMessage(PipelineId, ConsoleMessage), ServerExitMsg } diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index d260d344b2d..86904e0cd47 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -312,6 +312,9 @@ pub enum NavigationDirection { pub struct FrameId(pub uint); #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] +pub struct WorkerId(pub uint); + +#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] pub struct PipelineId(pub uint); #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 3d17778c6b1..25c4cf99d05 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -14,6 +14,8 @@ use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers}; use dom::window::{self, WindowHelpers}; use script_task::ScriptChan; +use msg::constellation_msg::WorkerId; + use net::resource_task::ResourceTask; use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS}; @@ -89,6 +91,14 @@ impl<'a> GlobalRef<'a> { } } + /// Get next worker id. + pub fn get_next_worker_id(&self) -> WorkerId { + match *self { + GlobalRef::Window(ref window) => window.get_next_worker_id(), + GlobalRef::Worker(ref worker) => worker.get_next_worker_id() + } + } + /// Get the URL for this global scope. pub fn get_url(&self) -> Url { match *self { diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 8d3f5c1684e..fe3129dce07 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -47,7 +47,7 @@ use js::jsval::JSVal; use js::rust::{Cx, rt}; use layout_interface::{LayoutRPC, LayoutChan}; use libc; -use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData}; +use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData, WorkerId}; use net::image_cache_task::ImageCacheTask; use net::storage_task::StorageType; use script_traits::ScriptControlChan; @@ -242,6 +242,7 @@ no_jsmanaged_fields!(PropertyDeclarationBlock); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs no_jsmanaged_fields!(SubpageId, WindowSizeData, PipelineId); +no_jsmanaged_fields!(WorkerId); no_jsmanaged_fields!(QuirksMode); no_jsmanaged_fields!(Cx); no_jsmanaged_fields!(rt); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index bb7a5563d0f..ce7dc34e77d 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -36,7 +36,7 @@ use timers::{IsInterval, TimerId, TimerManager, TimerCallback}; use devtools_traits::DevtoolsControlChan; use msg::compositor_msg::ScriptListener; -use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData}; +use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId}; use net::image_cache_task::ImageCacheTask; use net::resource_task::ResourceTask; use net::storage_task::{StorageTask, StorageType}; @@ -98,6 +98,8 @@ pub struct Window { local_storage: MutNullableJS<Storage>, timers: TimerManager, + next_worker_id: Cell<WorkerId>, + /// For providing instructions to an optional devtools server. devtools_chan: Option<DevtoolsControlChan>, @@ -171,6 +173,13 @@ impl Window { self.script_chan.clone() } + pub fn get_next_worker_id(&self) -> WorkerId { + let worker_id = self.next_worker_id.get(); + let WorkerId(id_num) = worker_id; + self.next_worker_id.set(WorkerId(id_num + 1)); + worker_id + } + pub fn pipeline(&self) -> PipelineId { self.id } @@ -814,6 +823,7 @@ impl Window { session_storage: Default::default(), local_storage: Default::default(), timers: TimerManager::new(), + next_worker_id: Cell::new(WorkerId(0)), id: id, parent_info: parent_info, dom_static: GlobalStaticData::new(), diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index d764fff259e..274d4c1d906 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -4,6 +4,7 @@ use dom::bindings::codegen::Bindings::WorkerBinding; use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast}; use dom::bindings::error::{Fallible, ErrorResult}; @@ -14,6 +15,7 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflectable, reflect_dom_object}; +use dom::window::WindowHelpers; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use dom::errorevent::ErrorEvent; use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers}; @@ -21,6 +23,8 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; use dom::messageevent::MessageEvent; use script_task::{ScriptChan, ScriptMsg, Runnable}; +use devtools_traits::{DevtoolsControlMsg, DevtoolsPageInfo}; + use util::str::DOMString; use js::jsapi::JSContext; @@ -71,6 +75,23 @@ impl Worker { let worker = Worker::new(global, sender.clone()).root(); let worker_ref = Trusted::new(global.get_cx(), worker.r(), global.script_chan()); + + if let GlobalRef::Window(window) = global { + if let Some(ref chan) = window.devtools_chan() { + let pipeline_id = window.Window().root().r().pipeline(); + let (devtools_sender, _) = channel(); + let title = format!("Worker for {}", worker_url); + let page_info = DevtoolsPageInfo { + title: title, + url: worker_url.clone(), + }; + let worker_id = global.get_next_worker_id(); + chan.send( + DevtoolsControlMsg::NewGlobal((pipeline_id, Some(worker_id)), devtools_sender.clone(), page_info) + ).unwrap(); + } + } + DedicatedWorkerGlobalScope::run_worker_scope( worker_url, worker_ref, resource_task, global.script_chan(), sender, receiver); diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 1a8e8b89e1e..e0d8ae7aaa0 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -19,6 +19,8 @@ use dom::window::{base64_atob, base64_btoa}; use script_task::{ScriptChan, TimerSource}; use timers::{IsInterval, TimerId, TimerManager, TimerCallback}; +use msg::constellation_msg::WorkerId; + use net::resource_task::{ResourceTask, load_whole_resource}; use util::str::DOMString; @@ -28,6 +30,7 @@ use js::rust::Cx; use std::default::Default; use std::rc::Rc; +use std::cell::Cell; use url::{Url, UrlParser}; #[derive(Copy, PartialEq)] @@ -41,6 +44,7 @@ pub struct WorkerGlobalScope { eventtarget: EventTarget, worker_url: Url, js_context: Rc<Cx>, + next_worker_id: Cell<WorkerId>, resource_task: ResourceTask, location: MutNullableJS<WorkerLocation>, navigator: MutNullableJS<WorkerNavigator>, @@ -55,6 +59,7 @@ impl WorkerGlobalScope { resource_task: ResourceTask) -> WorkerGlobalScope { WorkerGlobalScope { eventtarget: EventTarget::new_inherited(EventTargetTypeId::WorkerGlobalScope(type_id)), + next_worker_id: Cell::new(WorkerId(0)), worker_url: worker_url, js_context: cx, resource_task: resource_task, @@ -81,6 +86,13 @@ impl WorkerGlobalScope { pub fn get_url<'a>(&'a self) -> &'a Url { &self.worker_url } + + pub fn get_next_worker_id(&self) -> WorkerId { + let worker_id = self.next_worker_id.get(); + let WorkerId(id_num) = worker_id; + self.next_worker_id.set(WorkerId(id_num + 1)); + worker_id + } } impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 42db9aaf155..e5463285200 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -57,7 +57,7 @@ use script_traits::ScriptTaskFactory; use msg::compositor_msg::ReadyState::{FinishedLoading, Loading, PerformingLayout}; use msg::compositor_msg::{LayerId, ScriptListener}; use msg::constellation_msg::{ConstellationChan}; -use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent}; +use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId}; use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; use msg::constellation_msg::Msg as ConstellationMsg; use net::image_cache_task::ImageCacheTask; @@ -1114,20 +1114,24 @@ impl ScriptTask { chan.send(ConstellationMsg::LoadComplete).unwrap(); // Notify devtools that a new script global exists. + self.notify_devtools(document.r().Title(), final_url, (incomplete.pipeline_id, None)); + + page_remover.neuter(); + } + + fn notify_devtools(&self, title: DOMString, url: Url, ids: (PipelineId, Option<WorkerId>)) { match self.devtools_chan { None => {} Some(ref chan) => { let page_info = DevtoolsPageInfo { - title: document.r().Title(), - url: final_url + title: title, + url: url, }; - chan.send(DevtoolsControlMsg::NewGlobal(incomplete.pipeline_id, + chan.send(DevtoolsControlMsg::NewGlobal(ids, self.devtools_sender.clone(), page_info)).unwrap(); } } - - page_remover.neuter(); } fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: JSRef<Element>) { |