mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Add console message support to devtools. Does not actually cause logging to occur in the remote console.
This commit is contained in:
parent
149053c2a7
commit
6699738cae
7 changed files with 112 additions and 16 deletions
|
@ -15,3 +15,6 @@ path = "../msg"
|
||||||
|
|
||||||
[dependencies.util]
|
[dependencies.util]
|
||||||
path = "../util"
|
path = "../util"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
time = "*"
|
|
@ -25,6 +25,7 @@ extern crate devtools_traits;
|
||||||
extern crate "serialize" as rustc_serialize;
|
extern crate "serialize" as rustc_serialize;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate "msg" as servo_msg;
|
extern crate "msg" as servo_msg;
|
||||||
|
extern crate time;
|
||||||
extern crate util;
|
extern crate util;
|
||||||
|
|
||||||
use actor::{Actor, ActorRegistry};
|
use actor::{Actor, ActorRegistry};
|
||||||
|
@ -34,7 +35,8 @@ use actors::root::RootActor;
|
||||||
use actors::tab::TabActor;
|
use actors::tab::TabActor;
|
||||||
use protocol::JsonPacketStream;
|
use protocol::JsonPacketStream;
|
||||||
|
|
||||||
use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg, DevtoolsPageInfo};
|
use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg};
|
||||||
|
use devtools_traits::{DevtoolsPageInfo, SendConsoleMessage, ConsoleMessage};
|
||||||
use servo_msg::constellation_msg::PipelineId;
|
use servo_msg::constellation_msg::PipelineId;
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
|
|
||||||
|
@ -46,6 +48,7 @@ use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
|
||||||
use std::io::{TcpListener, TcpStream};
|
use std::io::{TcpListener, TcpStream};
|
||||||
use std::io::{Acceptor, Listener, TimedOut};
|
use std::io::{Acceptor, Listener, TimedOut};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use time::precise_time_ns;
|
||||||
|
|
||||||
mod actor;
|
mod actor;
|
||||||
/// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/
|
/// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/
|
||||||
|
@ -57,6 +60,20 @@ mod actors {
|
||||||
}
|
}
|
||||||
mod protocol;
|
mod protocol;
|
||||||
|
|
||||||
|
#[derive(RustcEncodable)]
|
||||||
|
struct ConsoleAPICall {
|
||||||
|
from: String,
|
||||||
|
__type__: String,
|
||||||
|
message: ConsoleMsg,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RustcEncodable)]
|
||||||
|
struct ConsoleMsg {
|
||||||
|
logLevel: u32,
|
||||||
|
timestamp: u64,
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// Spin up a devtools server that listens for connections on the specified port.
|
/// Spin up a devtools server that listens for connections on the specified port.
|
||||||
pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> {
|
pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> {
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
|
@ -169,6 +186,41 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
|
||||||
actors.register(box inspector);
|
actors.register(box inspector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_console_message(actors: Arc<Mutex<ActorRegistry>>,
|
||||||
|
id: PipelineId,
|
||||||
|
console_message: ConsoleMessage,
|
||||||
|
actor_pipelines: &HashMap<PipelineId, String>) {
|
||||||
|
let console_actor_name = find_console_actor(actors.clone(), id, actor_pipelines);
|
||||||
|
let actors = actors.lock().unwrap();
|
||||||
|
let console_actor = actors.find::<ConsoleActor>(console_actor_name.as_slice());
|
||||||
|
match console_message {
|
||||||
|
ConsoleMessage::LogMessage(message) => {
|
||||||
|
let msg = ConsoleAPICall {
|
||||||
|
from: console_actor.name.clone(),
|
||||||
|
__type__: "consoleAPICall".to_string(),
|
||||||
|
message: ConsoleMsg {
|
||||||
|
logLevel: 0,
|
||||||
|
timestamp: precise_time_ns(),
|
||||||
|
message: message,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
for stream in console_actor.streams.borrow_mut().iter_mut() {
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_console_actor(actors: Arc<Mutex<ActorRegistry>>,
|
||||||
|
id: PipelineId,
|
||||||
|
actor_pipelines: &HashMap<PipelineId, String>) -> String {
|
||||||
|
let actors = actors.lock().unwrap();
|
||||||
|
let ref tab_actor_name = (*actor_pipelines)[id];
|
||||||
|
let tab_actor = actors.find::<TabActor>(tab_actor_name.as_slice());
|
||||||
|
let console_actor_name = tab_actor.console.clone();
|
||||||
|
return console_actor_name;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: figure out some system that allows us to watch for new connections,
|
//TODO: figure out some system that allows us to watch for new connections,
|
||||||
// shut down existing ones at arbitrary times, and also watch for messages
|
// shut down existing ones at arbitrary times, and also watch for messages
|
||||||
// from multiple script tasks simultaneously. Polling for new connections
|
// from multiple script tasks simultaneously. Polling for new connections
|
||||||
|
@ -180,7 +232,12 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
|
||||||
Err(ref e) if e.kind == TimedOut => {
|
Err(ref e) if e.kind == TimedOut => {
|
||||||
match receiver.try_recv() {
|
match receiver.try_recv() {
|
||||||
Ok(ServerExitMsg) | Err(Disconnected) => break,
|
Ok(ServerExitMsg) | Err(Disconnected) => break,
|
||||||
Ok(NewGlobal(id, sender, pageinfo)) => handle_new_global(actors.clone(), id, sender, &mut actor_pipelines, pageinfo),
|
Ok(NewGlobal(id, sender, pageinfo)) =>
|
||||||
|
handle_new_global(actors.clone(), id,sender, &mut actor_pipelines,
|
||||||
|
pageinfo),
|
||||||
|
Ok(SendConsoleMessage(id, console_message)) =>
|
||||||
|
handle_console_message(actors.clone(), id, console_message,
|
||||||
|
&actor_pipelines),
|
||||||
Err(Empty) => acceptor.set_timeout(Some(POLL_TIMEOUT)),
|
Err(Empty) => acceptor.set_timeout(Some(POLL_TIMEOUT)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ pub struct DevtoolsPageInfo {
|
||||||
/// according to changes in the browser.
|
/// according to changes in the browser.
|
||||||
pub enum DevtoolsControlMsg {
|
pub enum DevtoolsControlMsg {
|
||||||
NewGlobal(PipelineId, Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo),
|
NewGlobal(PipelineId, Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo),
|
||||||
|
SendConsoleMessage(PipelineId, ConsoleMessage),
|
||||||
ServerExitMsg
|
ServerExitMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,3 +124,10 @@ impl Decodable for Modification {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Include options for Warn, Debug, Info, Error messages from Console
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum ConsoleMessage {
|
||||||
|
LogMessage(String),
|
||||||
|
//WarnMessage(String),
|
||||||
|
}
|
||||||
|
|
|
@ -4,31 +4,35 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::ConsoleBinding;
|
use dom::bindings::codegen::Bindings::ConsoleBinding;
|
||||||
use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
|
use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::{JSRef, Temporary};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
|
use devtools_traits::{SendConsoleMessage, ConsoleMessage};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct Console {
|
pub struct Console {
|
||||||
reflector_: Reflector
|
reflector_: Reflector,
|
||||||
|
global: GlobalField,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Console {
|
impl Console {
|
||||||
fn new_inherited() -> Console {
|
fn new_inherited(global: GlobalRef) -> Console {
|
||||||
Console {
|
Console {
|
||||||
reflector_: Reflector::new()
|
reflector_: Reflector::new(),
|
||||||
|
global: GlobalField::from_rooted(&global),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef) -> Temporary<Console> {
|
pub fn new(global: GlobalRef) -> Temporary<Console> {
|
||||||
reflect_dom_object(box Console::new_inherited(), global, ConsoleBinding::Wrap)
|
reflect_dom_object(box Console::new_inherited(global), global, ConsoleBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ConsoleMethods for JSRef<'a, Console> {
|
impl<'a> ConsoleMethods for JSRef<'a, Console> {
|
||||||
fn Log(self, message: DOMString) {
|
fn Log(self, message: DOMString) {
|
||||||
println!("{}", message);
|
println!("{}", message);
|
||||||
|
propagate_console_msg(&self, ConsoleMessage::LogMessage(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Debug(self, message: DOMString) {
|
fn Debug(self, message: DOMString) {
|
||||||
|
@ -58,3 +62,18 @@ impl<'a> ConsoleMethods for JSRef<'a, Console> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn propagate_console_msg(console: &JSRef<Console>, console_message: ConsoleMessage) {
|
||||||
|
let global = console.global.root();
|
||||||
|
match global.r() {
|
||||||
|
GlobalRef::Window(window_ref) => {
|
||||||
|
let pipelineId = window_ref.page().id;
|
||||||
|
console.global.root().r().as_window().page().devtools_chan.as_ref().map(|chan| {
|
||||||
|
chan.send(SendConsoleMessage(pipelineId, console_message.clone())).unwrap();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
GlobalRef::Worker(_) => {
|
||||||
|
// TODO: support worker console logs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::node::{Node, NodeHelpers};
|
use dom::node::{Node, NodeHelpers};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
use devtools_traits::DevtoolsControlChan;
|
||||||
use layout_interface::{
|
use layout_interface::{
|
||||||
ContentBoxResponse, ContentBoxesResponse,
|
ContentBoxResponse, ContentBoxesResponse,
|
||||||
HitTestResponse, LayoutChan, LayoutRPC, MouseOverResponse, Msg, Reflow,
|
HitTestResponse, LayoutChan, LayoutRPC, MouseOverResponse, Msg, Reflow,
|
||||||
|
@ -100,6 +101,9 @@ pub struct Page {
|
||||||
/// A flag to indicate whether the developer tools have requested live updates of
|
/// A flag to indicate whether the developer tools have requested live updates of
|
||||||
/// page changes.
|
/// page changes.
|
||||||
pub devtools_wants_updates: Cell<bool>,
|
pub devtools_wants_updates: Cell<bool>,
|
||||||
|
|
||||||
|
/// For providing instructions to an optional devtools server.
|
||||||
|
pub devtools_chan: Option<DevtoolsControlChan>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PageIterator {
|
pub struct PageIterator {
|
||||||
|
@ -135,7 +139,8 @@ impl Page {
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
storage_task: StorageTask,
|
storage_task: StorageTask,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
js_context: Rc<Cx>) -> Page {
|
js_context: Rc<Cx>,
|
||||||
|
devtools_chan: Option<DevtoolsControlChan>) -> Page {
|
||||||
let js_info = JSPageInfo {
|
let js_info = JSPageInfo {
|
||||||
dom_static: GlobalStaticData::new(),
|
dom_static: GlobalStaticData::new(),
|
||||||
js_context: js_context,
|
js_context: js_context,
|
||||||
|
@ -166,6 +171,7 @@ impl Page {
|
||||||
children: DOMRefCell::new(vec!()),
|
children: DOMRefCell::new(vec!()),
|
||||||
page_clip_rect: Cell::new(MAX_RECT),
|
page_clip_rect: Cell::new(MAX_RECT),
|
||||||
devtools_wants_updates: Cell::new(false),
|
devtools_wants_updates: Cell::new(false),
|
||||||
|
devtools_chan: devtools_chan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -379,7 +379,8 @@ impl ScriptTask {
|
||||||
resource_task.clone(),
|
resource_task.clone(),
|
||||||
storage_task,
|
storage_task,
|
||||||
constellation_chan.clone(),
|
constellation_chan.clone(),
|
||||||
js_context.clone());
|
js_context.clone(),
|
||||||
|
devtools_chan.clone());
|
||||||
|
|
||||||
let (devtools_sender, devtools_receiver) = channel();
|
let (devtools_sender, devtools_receiver) = channel();
|
||||||
ScriptTask {
|
ScriptTask {
|
||||||
|
@ -662,7 +663,8 @@ impl ScriptTask {
|
||||||
parent_page.resource_task.clone(),
|
parent_page.resource_task.clone(),
|
||||||
parent_page.storage_task.clone(),
|
parent_page.storage_task.clone(),
|
||||||
self.constellation_chan.clone(),
|
self.constellation_chan.clone(),
|
||||||
self.js_context.borrow().as_ref().unwrap().clone())
|
self.js_context.borrow().as_ref().unwrap().clone(),
|
||||||
|
self.devtools_chan.clone())
|
||||||
};
|
};
|
||||||
parent_page.children.borrow_mut().push(Rc::new(new_page));
|
parent_page.children.borrow_mut().push(Rc::new(new_page));
|
||||||
}
|
}
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -145,6 +145,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
|
"time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue