aboutsummaryrefslogtreecommitdiffstats
path: root/components/devtools/lib.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2020-04-25 12:21:18 -0400
committerJosh Matthews <josh@joshmatthews.net>2020-04-26 18:11:23 -0400
commit7c48644cad88fc86c4324b554f1b4edf2a3b4db0 (patch)
tree73b1920911ea0971459538e07292817392103784 /components/devtools/lib.rs
parent0540c4a284952145773e3c86d0f57f69a83283f1 (diff)
downloadservo-7c48644cad88fc86c4324b554f1b4edf2a3b4db0.tar.gz
servo-7c48644cad88fc86c4324b554f1b4edf2a3b4db0.zip
Support navigating browsing contexts in the devtools.
Break the association between pipelines and browsing context actors. Now there is one browsing context actor per actual browsing context, and individual actors keep track of known pipelines as necessary. There is also one console/performance/timeline/inspector/etc. actor per browsing context. This also centralizes more information in the browsing context actor. Rather than duplicating state for the active pipeline in actors that need to use it, each actor now remembers the name of its associated browsing context actor and obtains that state whenever it's necessary.
Diffstat (limited to 'components/devtools/lib.rs')
-rw-r--r--components/devtools/lib.rs221
1 files changed, 108 insertions, 113 deletions
diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs
index 661d6ac94e1..6d9bd938e14 100644
--- a/components/devtools/lib.rs
+++ b/components/devtools/lib.rs
@@ -21,29 +21,24 @@ use crate::actor::{Actor, ActorRegistry};
use crate::actors::browsing_context::BrowsingContextActor;
use crate::actors::console::ConsoleActor;
use crate::actors::device::DeviceActor;
-use crate::actors::emulation::EmulationActor;
use crate::actors::framerate::FramerateActor;
-use crate::actors::inspector::InspectorActor;
use crate::actors::network_event::{EventActor, NetworkEventActor, ResponseStartMsg};
use crate::actors::performance::PerformanceActor;
use crate::actors::preference::PreferenceActor;
use crate::actors::process::ProcessActor;
-use crate::actors::profiler::ProfilerActor;
use crate::actors::root::RootActor;
-use crate::actors::stylesheets::StyleSheetsActor;
-use crate::actors::thread::ThreadActor;
-use crate::actors::timeline::TimelineActor;
use crate::actors::worker::WorkerActor;
use crate::protocol::JsonPacketStream;
use crossbeam_channel::{unbounded, Receiver, Sender};
use devtools_traits::{ChromeToDevtoolsControlMsg, ConsoleMessage, DevtoolsControlMsg};
-use devtools_traits::{DevtoolScriptControlMsg, DevtoolsPageInfo, LogLevel, NetworkEvent};
+use devtools_traits::{
+ DevtoolScriptControlMsg, DevtoolsPageInfo, LogLevel, NavigationState, NetworkEvent,
+};
use devtools_traits::{PageError, ScriptToDevtoolsControlMsg, WorkerId};
use embedder_traits::{EmbedderMsg, EmbedderProxy, PromptDefinition, PromptOrigin, PromptResult};
use ipc_channel::ipc::{self, IpcSender};
-use msg::constellation_msg::PipelineId;
+use msg::constellation_msg::{BrowsingContextId, PipelineId};
use std::borrow::ToOwned;
-use std::cell::RefCell;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
use std::net::{Shutdown, TcpListener, TcpStream};
@@ -198,7 +193,8 @@ fn run_server(
let mut accepted_connections: Vec<TcpStream> = Vec::new();
- let mut actor_pipelines: HashMap<PipelineId, String> = HashMap::new();
+ let mut browsing_contexts: HashMap<BrowsingContextId, String> = HashMap::new();
+ let mut pipelines: HashMap<PipelineId, BrowsingContextId> = HashMap::new();
let mut actor_requests: HashMap<String, String> = HashMap::new();
let mut actor_workers: HashMap<(PipelineId, WorkerId), String> = HashMap::new();
@@ -243,91 +239,65 @@ fn run_server(
framerate_actor.add_tick(tick);
}
+ fn handle_navigate(
+ actors: Arc<Mutex<ActorRegistry>>,
+ browsing_contexts: &HashMap<BrowsingContextId, String>,
+ browsing_context: BrowsingContextId,
+ state: NavigationState,
+ ) {
+ let actor_name = browsing_contexts.get(&browsing_context).unwrap();
+ actors
+ .lock()
+ .unwrap()
+ .find::<BrowsingContextActor>(actor_name)
+ .navigate(state);
+ }
+
// We need separate actor representations for each script global that exists;
// clients can theoretically connect to multiple globals simultaneously.
// TODO: move this into the root or target modules?
fn handle_new_global(
actors: Arc<Mutex<ActorRegistry>>,
- ids: (PipelineId, Option<WorkerId>),
+ ids: (Option<BrowsingContextId>, PipelineId, Option<WorkerId>),
script_sender: IpcSender<DevtoolScriptControlMsg>,
- actor_pipelines: &mut HashMap<PipelineId, String>,
+ browsing_contexts: &mut HashMap<BrowsingContextId, String>,
+ pipelines: &mut HashMap<PipelineId, BrowsingContextId>,
actor_workers: &mut HashMap<(PipelineId, WorkerId), String>,
page_info: DevtoolsPageInfo,
) {
let mut actors = actors.lock().unwrap();
- let (pipeline, worker_id) = ids;
-
- //TODO: move all this actor creation into a constructor method on BrowsingContextActor
- let (
- target,
- console,
- emulation,
- inspector,
- timeline,
- profiler,
- performance,
- styleSheets,
- thread,
- ) = {
- let console = ConsoleActor {
- name: actors.new_name("console"),
- script_chan: script_sender.clone(),
- pipeline: pipeline,
- streams: RefCell::new(Vec::new()),
- cached_events: RefCell::new(Vec::new()),
- };
-
- let emulation = EmulationActor::new(actors.new_name("emulation"));
-
- let inspector = InspectorActor {
- name: actors.new_name("inspector"),
- walker: RefCell::new(None),
- pageStyle: RefCell::new(None),
- highlighter: RefCell::new(None),
- script_chan: script_sender.clone(),
- pipeline: pipeline,
- };
-
- let timeline = TimelineActor::new(actors.new_name("timeline"), pipeline, script_sender);
-
- let profiler = ProfilerActor::new(actors.new_name("profiler"));
- let performance = PerformanceActor::new(actors.new_name("performance"));
-
- // the strange switch between styleSheets and stylesheets is due
- // to an inconsistency in devtools. See Bug #1498893 in bugzilla
- let styleSheets = StyleSheetsActor::new(actors.new_name("stylesheets"));
- let thread = ThreadActor::new(actors.new_name("context"));
-
- let DevtoolsPageInfo { title, url } = page_info;
- let target = BrowsingContextActor {
- name: actors.new_name("target"),
- title: String::from(title),
- url: url.into_string(),
- console: console.name(),
- emulation: emulation.name(),
- inspector: inspector.name(),
- timeline: timeline.name(),
- profiler: profiler.name(),
- performance: performance.name(),
- styleSheets: styleSheets.name(),
- thread: thread.name(),
- };
+ let (browsing_context, pipeline, worker_id) = ids;
+
+ let console_name = actors.new_name("console");
+
+ let browsing_context_name = if let Some(browsing_context) = browsing_context {
+ pipelines.insert(pipeline, browsing_context);
+ if let Some(actor) = browsing_contexts.get(&browsing_context) {
+ actor.to_owned()
+ } else {
+ let browsing_context_actor = BrowsingContextActor::new(
+ console_name.clone(),
+ browsing_context,
+ page_info,
+ pipeline,
+ script_sender.clone(),
+ &mut *actors,
+ );
+ let name = browsing_context_actor.name();
+ browsing_contexts.insert(browsing_context, name.clone());
+ actors.register(Box::new(browsing_context_actor));
+ name
+ }
+ } else {
+ "".to_owned()
+ };
- let root = actors.find_mut::<RootActor>("root");
- root.tabs.push(target.name.clone());
-
- (
- target,
- console,
- emulation,
- inspector,
- timeline,
- profiler,
- performance,
- styleSheets,
- thread,
- )
+ // XXXjdm this new actor is useless if it's not a new worker global
+ let console = ConsoleActor {
+ name: console_name,
+ cached_events: Default::default(),
+ browsing_context: browsing_context_name,
};
if let Some(id) = worker_id {
@@ -336,36 +306,39 @@ fn run_server(
console: console.name(),
id: id,
};
+ let root = actors.find_mut::<RootActor>("root");
+ root.tabs.push(worker.name.clone());
+
actor_workers.insert((pipeline, id), worker.name.clone());
actors.register(Box::new(worker));
}
- actor_pipelines.insert(pipeline, target.name.clone());
- actors.register(Box::new(target));
actors.register(Box::new(console));
- actors.register(Box::new(emulation));
- actors.register(Box::new(inspector));
- actors.register(Box::new(timeline));
- actors.register(Box::new(profiler));
- actors.register(Box::new(performance));
- actors.register(Box::new(styleSheets));
- actors.register(Box::new(thread));
}
fn handle_page_error(
actors: Arc<Mutex<ActorRegistry>>,
id: PipelineId,
page_error: PageError,
- actor_pipelines: &HashMap<PipelineId, String>,
+ browsing_contexts: &HashMap<BrowsingContextId, String>,
+ pipelines: &HashMap<PipelineId, BrowsingContextId>,
) {
- let console_actor_name =
- match find_console_actor(actors.clone(), id, None, &HashMap::new(), actor_pipelines) {
- Some(name) => name,
- None => return,
- };
+ let console_actor_name = match find_console_actor(
+ actors.clone(),
+ id,
+ None,
+ &HashMap::new(),
+ browsing_contexts,
+ pipelines,
+ ) {
+ Some(name) => name,
+ None => return,
+ };
let actors = actors.lock().unwrap();
let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
- console_actor.handle_page_error(page_error);
+ let browsing_context_actor =
+ actors.find::<BrowsingContextActor>(&console_actor.browsing_context);
+ console_actor.handle_page_error(page_error, id, &browsing_context_actor);
}
fn handle_console_message(
@@ -373,37 +346,43 @@ fn run_server(
id: PipelineId,
worker_id: Option<WorkerId>,
console_message: ConsoleMessage,
- actor_pipelines: &HashMap<PipelineId, String>,
+ browsing_contexts: &HashMap<BrowsingContextId, String>,
actor_workers: &HashMap<(PipelineId, WorkerId), String>,
+ pipelines: &HashMap<PipelineId, BrowsingContextId>,
) {
let console_actor_name = match find_console_actor(
actors.clone(),
id,
worker_id,
actor_workers,
- actor_pipelines,
+ browsing_contexts,
+ pipelines,
) {
Some(name) => name,
None => return,
};
let actors = actors.lock().unwrap();
let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
- console_actor.handle_console_api(console_message);
+ let browsing_context_actor =
+ actors.find::<BrowsingContextActor>(&console_actor.browsing_context);
+ console_actor.handle_console_api(console_message, id, &browsing_context_actor);
}
fn find_console_actor(
actors: Arc<Mutex<ActorRegistry>>,
- id: PipelineId,
+ pipeline: PipelineId,
worker_id: Option<WorkerId>,
actor_workers: &HashMap<(PipelineId, WorkerId), String>,
- actor_pipelines: &HashMap<PipelineId, String>,
+ browsing_contexts: &HashMap<BrowsingContextId, String>,
+ pipelines: &HashMap<PipelineId, BrowsingContextId>,
) -> Option<String> {
let actors = actors.lock().unwrap();
if let Some(worker_id) = worker_id {
- let actor_name = (*actor_workers).get(&(id, worker_id))?;
+ let actor_name = (*actor_workers).get(&(pipeline, worker_id))?;
Some(actors.find::<WorkerActor>(actor_name).console.clone())
} else {
- let actor_name = (*actor_pipelines).get(&id)?;
+ let id = pipelines.get(&pipeline)?;
+ let actor_name = browsing_contexts.get(id)?;
Some(
actors
.find::<BrowsingContextActor>(actor_name)
@@ -416,9 +395,10 @@ fn run_server(
fn handle_network_event(
actors: Arc<Mutex<ActorRegistry>>,
mut connections: Vec<TcpStream>,
- actor_pipelines: &HashMap<PipelineId, String>,
+ browsing_contexts: &HashMap<BrowsingContextId, String>,
actor_requests: &mut HashMap<String, String>,
actor_workers: &HashMap<(PipelineId, WorkerId), String>,
+ pipelines: &HashMap<PipelineId, BrowsingContextId>,
pipeline_id: PipelineId,
request_id: String,
network_event: NetworkEvent,
@@ -428,7 +408,8 @@ fn run_server(
pipeline_id,
None,
actor_workers,
- actor_pipelines,
+ browsing_contexts,
+ pipelines,
) {
Some(name) => name,
None => return,
@@ -610,10 +591,15 @@ fn run_server(
actors.clone(),
ids,
script_sender,
- &mut actor_pipelines,
+ &mut browsing_contexts,
+ &mut pipelines,
&mut actor_workers,
pageinfo,
),
+ DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::Navigate(
+ browsing_context,
+ state,
+ )) => handle_navigate(actors.clone(), &browsing_contexts, browsing_context, state),
DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ConsoleAPI(
id,
console_message,
@@ -623,13 +609,20 @@ fn run_server(
id,
worker_id,
console_message,
- &actor_pipelines,
+ &browsing_contexts,
&actor_workers,
+ &pipelines,
),
DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ReportPageError(
id,
page_error,
- )) => handle_page_error(actors.clone(), id, page_error, &actor_pipelines),
+ )) => handle_page_error(
+ actors.clone(),
+ id,
+ page_error,
+ &browsing_contexts,
+ &pipelines,
+ ),
DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ReportCSSError(
id,
css_error,
@@ -646,8 +639,9 @@ fn run_server(
id,
None,
console_message,
- &actor_pipelines,
+ &browsing_contexts,
&actor_workers,
+ &pipelines,
)
},
DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::NetworkEvent(
@@ -667,9 +661,10 @@ fn run_server(
handle_network_event(
actors.clone(),
connections,
- &actor_pipelines,
+ &browsing_contexts,
&mut actor_requests,
&actor_workers,
+ &pipelines,
pipeline_id,
request_id,
network_event,