Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add console message support to devtools. Does not actually cause logg…
…ing to occur in the remote console.
  • Loading branch information
srm09 authored and jdm committed Feb 5, 2015
1 parent 149053c commit 6699738
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 16 deletions.
5 changes: 4 additions & 1 deletion components/devtools/Cargo.toml
Expand Up @@ -14,4 +14,7 @@ path = "../devtools_traits"
path = "../msg"

[dependencies.util]
path = "../util"
path = "../util"

[dependencies]
time = "*"
61 changes: 59 additions & 2 deletions components/devtools/lib.rs
Expand Up @@ -25,6 +25,7 @@ extern crate devtools_traits;
extern crate "serialize" as rustc_serialize;
extern crate serialize;
extern crate "msg" as servo_msg;
extern crate time;
extern crate util;

use actor::{Actor, ActorRegistry};
Expand All @@ -34,7 +35,8 @@ use actors::root::RootActor;
use actors::tab::TabActor;
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 util::task::spawn_named;

Expand All @@ -46,6 +48,7 @@ use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener, TimedOut};
use std::sync::{Arc, Mutex};
use time::precise_time_ns;

mod actor;
/// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/
Expand All @@ -57,6 +60,20 @@ mod actors {
}
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.
pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> {
let (sender, receiver) = channel();
Expand Down Expand Up @@ -169,6 +186,41 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
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,
// shut down existing ones at arbitrary times, and also watch for messages
// from multiple script tasks simultaneously. Polling for new connections
Expand All @@ -180,7 +232,12 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
Err(ref e) if e.kind == TimedOut => {
match receiver.try_recv() {
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)),
}
}
Expand Down
8 changes: 8 additions & 0 deletions components/devtools_traits/lib.rs
Expand Up @@ -45,6 +45,7 @@ pub struct DevtoolsPageInfo {
/// according to changes in the browser.
pub enum DevtoolsControlMsg {
NewGlobal(PipelineId, Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo),
SendConsoleMessage(PipelineId, ConsoleMessage),
ServerExitMsg
}

Expand Down Expand Up @@ -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),
}
29 changes: 24 additions & 5 deletions components/script/dom/console.rs
Expand Up @@ -4,31 +4,35 @@

use dom::bindings::codegen::Bindings::ConsoleBinding;
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::utils::{Reflector, reflect_dom_object};
use devtools_traits::{SendConsoleMessage, ConsoleMessage};
use util::str::DOMString;

#[dom_struct]
pub struct Console {
reflector_: Reflector
reflector_: Reflector,
global: GlobalField,
}

impl Console {
fn new_inherited() -> Console {
fn new_inherited(global: GlobalRef) -> Console {
Console {
reflector_: Reflector::new()
reflector_: Reflector::new(),
global: GlobalField::from_rooted(&global),
}
}

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> {
fn Log(self, message: DOMString) {
println!("{}", message);
propagate_console_msg(&self, ConsoleMessage::LogMessage(message));
}

fn Debug(self, message: DOMString) {
Expand Down Expand Up @@ -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
}
}
}
18 changes: 12 additions & 6 deletions components/script/page.rs
Expand Up @@ -11,6 +11,7 @@ use dom::document::{Document, DocumentHelpers};
use dom::element::Element;
use dom::node::{Node, NodeHelpers};
use dom::window::Window;
use devtools_traits::DevtoolsControlChan;
use layout_interface::{
ContentBoxResponse, ContentBoxesResponse,
HitTestResponse, LayoutChan, LayoutRPC, MouseOverResponse, Msg, Reflow,
Expand Down Expand Up @@ -100,6 +101,9 @@ pub struct Page {
/// A flag to indicate whether the developer tools have requested live updates of
/// page changes.
pub devtools_wants_updates: Cell<bool>,

/// For providing instructions to an optional devtools server.
pub devtools_chan: Option<DevtoolsControlChan>,
}

pub struct PageIterator {
Expand Down Expand Up @@ -130,12 +134,13 @@ impl IterablePage for Rc<Page> {

impl Page {
pub fn new(id: PipelineId, subpage_id: Option<SubpageId>,
layout_chan: LayoutChan,
window_size: WindowSizeData,
resource_task: ResourceTask,
storage_task: StorageTask,
constellation_chan: ConstellationChan,
js_context: Rc<Cx>) -> Page {
layout_chan: LayoutChan,
window_size: WindowSizeData,
resource_task: ResourceTask,
storage_task: StorageTask,
constellation_chan: ConstellationChan,
js_context: Rc<Cx>,
devtools_chan: Option<DevtoolsControlChan>) -> Page {
let js_info = JSPageInfo {
dom_static: GlobalStaticData::new(),
js_context: js_context,
Expand Down Expand Up @@ -166,6 +171,7 @@ impl Page {
children: DOMRefCell::new(vec!()),
page_clip_rect: Cell::new(MAX_RECT),
devtools_wants_updates: Cell::new(false),
devtools_chan: devtools_chan,
}
}

Expand Down
6 changes: 4 additions & 2 deletions components/script/script_task.rs
Expand Up @@ -379,7 +379,8 @@ impl ScriptTask {
resource_task.clone(),
storage_task,
constellation_chan.clone(),
js_context.clone());
js_context.clone(),
devtools_chan.clone());

let (devtools_sender, devtools_receiver) = channel();
ScriptTask {
Expand Down Expand Up @@ -662,7 +663,8 @@ impl ScriptTask {
parent_page.resource_task.clone(),
parent_page.storage_task.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));
}
Expand Down
1 change: 1 addition & 0 deletions components/servo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 comments on commit 6699738

@bors-servo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from jdm
at jdm@6699738

@bors-servo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging jdm/servo/consoleapicall = 6699738 into auto

@bors-servo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jdm/servo/consoleapicall = 6699738 merged ok, testing candidate = 0d56080

@bors-servo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors-servo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 0d56080

Please sign in to comment.