mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Implement wire protocol support for DOM inspector.
This commit is contained in:
parent
c31e2f928d
commit
e9c4aa534d
5 changed files with 554 additions and 18 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use std::any::{Any, AnyRefExt, AnyMutRefExt};
|
use std::any::{Any, AnyRefExt, AnyMutRefExt};
|
||||||
use std::collections::hashmap::HashMap;
|
use std::collections::hashmap::HashMap;
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
use std::io::TcpStream;
|
use std::io::TcpStream;
|
||||||
use std::mem::{transmute, transmute_copy};
|
use std::mem::{transmute, transmute_copy};
|
||||||
use std::raw::TraitObject;
|
use std::raw::TraitObject;
|
||||||
|
@ -69,6 +70,8 @@ impl<'a> AnyRefExt<'a> for &'a Actor {
|
||||||
/// A list of known, owned actors.
|
/// A list of known, owned actors.
|
||||||
pub struct ActorRegistry {
|
pub struct ActorRegistry {
|
||||||
actors: HashMap<String, Box<Actor+Send+Sized>>,
|
actors: HashMap<String, Box<Actor+Send+Sized>>,
|
||||||
|
new_actors: RefCell<Vec<Box<Actor+Send+Sized>>>,
|
||||||
|
next: Cell<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActorRegistry {
|
impl ActorRegistry {
|
||||||
|
@ -76,14 +79,28 @@ impl ActorRegistry {
|
||||||
pub fn new() -> ActorRegistry {
|
pub fn new() -> ActorRegistry {
|
||||||
ActorRegistry {
|
ActorRegistry {
|
||||||
actors: HashMap::new(),
|
actors: HashMap::new(),
|
||||||
|
new_actors: RefCell::new(vec!()),
|
||||||
|
next: Cell::new(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a unique name based on a monotonically increasing suffix
|
||||||
|
pub fn new_name(&self, prefix: &str) -> String {
|
||||||
|
let suffix = self.next.get();
|
||||||
|
self.next.set(suffix + 1);
|
||||||
|
format!("{:s}{:u}", prefix, suffix)
|
||||||
|
}
|
||||||
|
|
||||||
/// Add an actor to the registry of known actors that can receive messages.
|
/// Add an actor to the registry of known actors that can receive messages.
|
||||||
pub fn register(&mut self, actor: Box<Actor+Send+Sized>) {
|
pub fn register(&mut self, actor: Box<Actor+Send+Sized>) {
|
||||||
self.actors.insert(actor.name().to_string(), actor);
|
self.actors.insert(actor.name().to_string(), actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_later(&self, actor: Box<Actor+Send+Sized>) {
|
||||||
|
let mut actors = self.new_actors.borrow_mut();
|
||||||
|
actors.push(actor);
|
||||||
|
}
|
||||||
|
|
||||||
/// Find an actor by registered name
|
/// Find an actor by registered name
|
||||||
pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T {
|
pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T {
|
||||||
//FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
|
//FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
|
||||||
|
@ -104,7 +121,7 @@ impl ActorRegistry {
|
||||||
|
|
||||||
/// Attempt to process a message as directed by its `to` property. If the actor is not
|
/// Attempt to process a message as directed by its `to` property. If the actor is not
|
||||||
/// found or does not indicate that it knew how to process the message, ignore the failure.
|
/// found or does not indicate that it knew how to process the message, ignore the failure.
|
||||||
pub fn handle_message(&self, msg: &json::Object, stream: &mut TcpStream) {
|
pub fn handle_message(&mut self, msg: &json::Object, stream: &mut TcpStream) {
|
||||||
let to = msg.find(&"to".to_string()).unwrap().as_string().unwrap();
|
let to = msg.find(&"to".to_string()).unwrap().as_string().unwrap();
|
||||||
match self.actors.find(&to.to_string()) {
|
match self.actors.find(&to.to_string()) {
|
||||||
None => println!("message received for unknown actor \"{:s}\"", to),
|
None => println!("message received for unknown actor \"{:s}\"", to),
|
||||||
|
@ -116,5 +133,10 @@ impl ActorRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut new_actors = self.new_actors.borrow_mut();
|
||||||
|
for &actor in new_actors.iter() {
|
||||||
|
self.actors.insert(actor.name().to_string(), actor);
|
||||||
|
}
|
||||||
|
new_actors.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
472
components/devtools/actors/inspector.rs
Normal file
472
components/devtools/actors/inspector.rs
Normal file
|
@ -0,0 +1,472 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
/// Liberally derived from the [Firefox JS implementation](http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/inspector.js).
|
||||||
|
|
||||||
|
use actor::{Actor, ActorRegistry};
|
||||||
|
use protocol::JsonPacketSender;
|
||||||
|
|
||||||
|
use serialize::json;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::io::TcpStream;
|
||||||
|
|
||||||
|
pub struct InspectorActor {
|
||||||
|
pub name: String,
|
||||||
|
pub walker: RefCell<Option<String>>,
|
||||||
|
pub pageStyle: RefCell<Option<String>>,
|
||||||
|
pub highlighter: RefCell<Option<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct GetHighlighterReply {
|
||||||
|
highligter: HighlighterMsg, // sic.
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct HighlighterMsg {
|
||||||
|
actor: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HighlighterActor {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct ShowBoxModelReply {
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct HideBoxModelReply {
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for HighlighterActor {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_message(&self,
|
||||||
|
_registry: &ActorRegistry,
|
||||||
|
msg_type: &String,
|
||||||
|
_msg: &json::Object,
|
||||||
|
stream: &mut TcpStream) -> bool {
|
||||||
|
match msg_type.as_slice() {
|
||||||
|
"showBoxModel" => {
|
||||||
|
let msg = ShowBoxModelReply {
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
"hideBoxModel" => {
|
||||||
|
let msg = HideBoxModelReply {
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct GetWalkerReply {
|
||||||
|
from: String,
|
||||||
|
walker: WalkerMsg,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct WalkerMsg {
|
||||||
|
actor: String,
|
||||||
|
root: NodeActorMsg,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct AttrMsg {
|
||||||
|
namespace: String,
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct NodeActorMsg {
|
||||||
|
actor: String,
|
||||||
|
baseURI: String,
|
||||||
|
parent: String,
|
||||||
|
nodeType: uint,
|
||||||
|
namespaceURI: String,
|
||||||
|
nodeName: String,
|
||||||
|
numChildren: uint,
|
||||||
|
|
||||||
|
name: String,
|
||||||
|
publicId: String,
|
||||||
|
systemId: String,
|
||||||
|
|
||||||
|
attrs: Vec<AttrMsg>,
|
||||||
|
|
||||||
|
pseudoClassLocks: Vec<String>,
|
||||||
|
|
||||||
|
isDisplayed: bool,
|
||||||
|
|
||||||
|
hasEventListeners: bool,
|
||||||
|
|
||||||
|
isDocumentElement: bool,
|
||||||
|
|
||||||
|
shortValue: String,
|
||||||
|
incompleteValue: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WalkerActor {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct QuerySelectorReply {
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct DocumentElementReply {
|
||||||
|
from: String,
|
||||||
|
node: NodeActorMsg,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct ClearPseudoclassesReply {
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct ChildrenReply {
|
||||||
|
hasFirst: bool,
|
||||||
|
hasLast: bool,
|
||||||
|
nodes: Vec<NodeActorMsg>,
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for WalkerActor {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_message(&self,
|
||||||
|
_registry: &ActorRegistry,
|
||||||
|
msg_type: &String,
|
||||||
|
_msg: &json::Object,
|
||||||
|
stream: &mut TcpStream) -> bool {
|
||||||
|
match msg_type.as_slice() {
|
||||||
|
"querySelector" => {
|
||||||
|
let msg = QuerySelectorReply {
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
"documentElement" => {
|
||||||
|
let msg = DocumentElementReply {
|
||||||
|
from: self.name(),
|
||||||
|
node: NodeActorMsg {
|
||||||
|
actor: "node0".to_string(),
|
||||||
|
baseURI: "".to_string(),
|
||||||
|
parent: "".to_string(),
|
||||||
|
nodeType: 1, //ELEMENT_NODE
|
||||||
|
namespaceURI: "".to_string(),
|
||||||
|
nodeName: "html".to_string(),
|
||||||
|
numChildren: 0,
|
||||||
|
|
||||||
|
name: "".to_string(),
|
||||||
|
publicId: "".to_string(),
|
||||||
|
systemId: "".to_string(),
|
||||||
|
|
||||||
|
attrs: vec!(AttrMsg {
|
||||||
|
namespace: "".to_string(),
|
||||||
|
name: "manifest".to_string(),
|
||||||
|
value: "foo.manifest".to_string(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
pseudoClassLocks: vec!(),
|
||||||
|
|
||||||
|
isDisplayed: true,
|
||||||
|
|
||||||
|
hasEventListeners: false,
|
||||||
|
|
||||||
|
isDocumentElement: true,
|
||||||
|
|
||||||
|
shortValue: "".to_string(),
|
||||||
|
incompleteValue: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
"clearPseudoClassLocks" => {
|
||||||
|
let msg = ClearPseudoclassesReply {
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
"children" => {
|
||||||
|
let msg = ChildrenReply {
|
||||||
|
hasFirst: true,
|
||||||
|
hasLast: true,
|
||||||
|
nodes: vec!(),
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NodeActor {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for NodeActor {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_message(&self,
|
||||||
|
_registry: &ActorRegistry,
|
||||||
|
msg_type: &String,
|
||||||
|
_msg: &json::Object,
|
||||||
|
_stream: &mut TcpStream) -> bool {
|
||||||
|
match msg_type.as_slice() {
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct GetPageStyleReply {
|
||||||
|
from: String,
|
||||||
|
pageStyle: PageStyleMsg,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct PageStyleMsg {
|
||||||
|
actor: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PageStyleActor {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct GetAppliedReply {
|
||||||
|
entries: Vec<AppliedEntry>,
|
||||||
|
rules: Vec<AppliedRule>,
|
||||||
|
sheets: Vec<AppliedSheet>,
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct GetComputedReply {
|
||||||
|
computed: Vec<uint>, //XXX all css props
|
||||||
|
from: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct AppliedEntry {
|
||||||
|
rule: String,
|
||||||
|
pseudoElement: json::Json,
|
||||||
|
isSystem: bool,
|
||||||
|
matchedSelectors: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct AppliedRule {
|
||||||
|
actor: String,
|
||||||
|
__type__: uint,
|
||||||
|
href: String,
|
||||||
|
cssText: String,
|
||||||
|
line: uint,
|
||||||
|
column: uint,
|
||||||
|
parentStyleSheet: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct AppliedSheet {
|
||||||
|
actor: String,
|
||||||
|
href: String,
|
||||||
|
nodeHref: String,
|
||||||
|
disabled: bool,
|
||||||
|
title: String,
|
||||||
|
system: bool,
|
||||||
|
styleSheetIndex: int,
|
||||||
|
ruleCount: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for PageStyleActor {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_message(&self,
|
||||||
|
_registry: &ActorRegistry,
|
||||||
|
msg_type: &String,
|
||||||
|
_msg: &json::Object,
|
||||||
|
stream: &mut TcpStream) -> bool {
|
||||||
|
match msg_type.as_slice() {
|
||||||
|
"getApplied" => {
|
||||||
|
//TODO: query script for relevant applied styles to node (msg.node)
|
||||||
|
let msg = GetAppliedReply {
|
||||||
|
entries: vec!(),
|
||||||
|
rules: vec!(),
|
||||||
|
sheets: vec!(),
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
"getComputed" => {
|
||||||
|
//TODO: query script for relevant computed styles on node (msg.node)
|
||||||
|
let msg = GetComputedReply {
|
||||||
|
computed: vec!(),
|
||||||
|
from: self.name(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: query script for box layout properties of node (msg.node)
|
||||||
|
//"getLayout" => {}
|
||||||
|
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for InspectorActor {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_message(&self,
|
||||||
|
registry: &ActorRegistry,
|
||||||
|
msg_type: &String,
|
||||||
|
_msg: &json::Object,
|
||||||
|
stream: &mut TcpStream) -> bool {
|
||||||
|
match msg_type.as_slice() {
|
||||||
|
"getWalker" => {
|
||||||
|
if self.walker.borrow().is_none() {
|
||||||
|
let walker = WalkerActor {
|
||||||
|
name: registry.new_name("walker"),
|
||||||
|
};
|
||||||
|
let mut walker_name = self.walker.borrow_mut();
|
||||||
|
*walker_name = Some(walker.name());
|
||||||
|
registry.register_later(box walker);
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = NodeActor {
|
||||||
|
name: registry.new_name("node"),
|
||||||
|
};
|
||||||
|
let node_actor_name = node.name();
|
||||||
|
registry.register_later(box node);
|
||||||
|
|
||||||
|
//TODO: query script for actual root node
|
||||||
|
//TODO: extra node actor creation
|
||||||
|
let node = NodeActorMsg {
|
||||||
|
actor: node_actor_name,
|
||||||
|
baseURI: "".to_string(),
|
||||||
|
parent: "".to_string(),
|
||||||
|
nodeType: 1, //ELEMENT_NODE
|
||||||
|
namespaceURI: "".to_string(),
|
||||||
|
nodeName: "html".to_string(),
|
||||||
|
numChildren: 1,
|
||||||
|
|
||||||
|
name: "".to_string(),
|
||||||
|
publicId: "".to_string(),
|
||||||
|
systemId: "".to_string(),
|
||||||
|
|
||||||
|
attrs: vec!(AttrMsg {
|
||||||
|
namespace: "".to_string(),
|
||||||
|
name: "manifest".to_string(),
|
||||||
|
value: "foo.manifest".to_string(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
pseudoClassLocks: vec!(),
|
||||||
|
|
||||||
|
isDisplayed: true,
|
||||||
|
|
||||||
|
hasEventListeners: false,
|
||||||
|
|
||||||
|
isDocumentElement: true,
|
||||||
|
|
||||||
|
shortValue: "".to_string(),
|
||||||
|
incompleteValue: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let msg = GetWalkerReply {
|
||||||
|
from: self.name(),
|
||||||
|
walker: WalkerMsg {
|
||||||
|
actor: self.walker.borrow().clone().unwrap(),
|
||||||
|
root: node,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
"getPageStyle" => {
|
||||||
|
if self.pageStyle.borrow().is_none() {
|
||||||
|
let style = PageStyleActor {
|
||||||
|
name: registry.new_name("pageStyle"),
|
||||||
|
};
|
||||||
|
let mut pageStyle = self.pageStyle.borrow_mut();
|
||||||
|
*pageStyle = Some(style.name());
|
||||||
|
registry.register_later(box style);
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = GetPageStyleReply {
|
||||||
|
from: self.name(),
|
||||||
|
pageStyle: PageStyleMsg {
|
||||||
|
actor: self.pageStyle.borrow().clone().unwrap(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: this is an old message; try adding highlightable to the root traits instead
|
||||||
|
// and support getHighlighter instead
|
||||||
|
//"highlight" => {}
|
||||||
|
"getHighlighter" => {
|
||||||
|
if self.highlighter.borrow().is_none() {
|
||||||
|
let highlighter_actor = HighlighterActor {
|
||||||
|
name: registry.new_name("highlighter"),
|
||||||
|
};
|
||||||
|
let mut highlighter = self.highlighter.borrow_mut();
|
||||||
|
*highlighter = Some(highlighter_actor.name());
|
||||||
|
registry.register_later(box highlighter_actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = GetHighlighterReply {
|
||||||
|
from: self.name(),
|
||||||
|
highligter: HighlighterMsg {
|
||||||
|
actor: self.highlighter.borrow().clone().unwrap(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,9 @@ use std::io::TcpStream;
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
struct ActorTraits {
|
struct ActorTraits {
|
||||||
sources: bool
|
sources: bool,
|
||||||
|
highlightable: bool,
|
||||||
|
customHighlighters: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
|
@ -40,7 +42,6 @@ struct RootActorMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RootActor {
|
pub struct RootActor {
|
||||||
pub next: u32,
|
|
||||||
pub tabs: Vec<String>,
|
pub tabs: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +91,8 @@ impl RootActor {
|
||||||
applicationType: "browser".to_string(),
|
applicationType: "browser".to_string(),
|
||||||
traits: ActorTraits {
|
traits: ActorTraits {
|
||||||
sources: true,
|
sources: true,
|
||||||
|
highlightable: true,
|
||||||
|
customHighlighters: vec!("BoxModelHighlighter".to_string()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,20 @@ struct ReconfigureReply {
|
||||||
from: String
|
from: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct ListFramesReply {
|
||||||
|
from: String,
|
||||||
|
frames: Vec<FrameMsg>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
struct FrameMsg {
|
||||||
|
id: uint,
|
||||||
|
url: String,
|
||||||
|
title: String,
|
||||||
|
parentID: uint,
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct TabActorMsg {
|
pub struct TabActorMsg {
|
||||||
actor: String,
|
actor: String,
|
||||||
|
@ -43,12 +57,15 @@ pub struct TabActorMsg {
|
||||||
url: String,
|
url: String,
|
||||||
outerWindowID: uint,
|
outerWindowID: uint,
|
||||||
consoleActor: String,
|
consoleActor: String,
|
||||||
|
inspectorActor: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TabActor {
|
pub struct TabActor {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub url: String,
|
pub url: String,
|
||||||
|
pub console: String,
|
||||||
|
pub inspector: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for TabActor {
|
impl Actor for TabActor {
|
||||||
|
@ -90,6 +107,16 @@ impl Actor for TabActor {
|
||||||
stream.write_json_packet(&msg);
|
stream.write_json_packet(&msg);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"listFrames" => {
|
||||||
|
let msg = ListFramesReply {
|
||||||
|
from: self.name(),
|
||||||
|
frames: vec!(),
|
||||||
|
};
|
||||||
|
stream.write_json_packet(&msg);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +129,8 @@ impl TabActor {
|
||||||
title: self.title.clone(),
|
title: self.title.clone(),
|
||||||
url: self.url.clone(),
|
url: self.url.clone(),
|
||||||
outerWindowID: 0, //FIXME: this should probably be the pipeline id
|
outerWindowID: 0, //FIXME: this should probably be the pipeline id
|
||||||
consoleActor: "console0".to_string(), //FIXME: this should be the actual actor name
|
consoleActor: self.console.clone(),
|
||||||
|
inspectorActor: self.inspector.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,9 @@ extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate servo_msg = "msg";
|
extern crate servo_msg = "msg";
|
||||||
|
|
||||||
use actor::ActorRegistry;
|
use actor::{Actor, ActorRegistry};
|
||||||
use actors::console::ConsoleActor;
|
use actors::console::ConsoleActor;
|
||||||
|
use actors::inspector::InspectorActor;
|
||||||
use actors::root::RootActor;
|
use actors::root::RootActor;
|
||||||
use actors::tab::TabActor;
|
use actors::tab::TabActor;
|
||||||
use protocol::JsonPacketSender;
|
use protocol::JsonPacketSender;
|
||||||
|
@ -36,6 +37,7 @@ use protocol::JsonPacketSender;
|
||||||
use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg};
|
use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg};
|
||||||
use servo_msg::constellation_msg::PipelineId;
|
use servo_msg::constellation_msg::PipelineId;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::comm;
|
use std::comm;
|
||||||
use std::comm::{Disconnected, Empty};
|
use std::comm::{Disconnected, Empty};
|
||||||
use std::io::{TcpListener, TcpStream};
|
use std::io::{TcpListener, TcpStream};
|
||||||
|
@ -49,8 +51,9 @@ 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/
|
||||||
mod actors {
|
mod actors {
|
||||||
pub mod console;
|
pub mod console;
|
||||||
pub mod tab;
|
pub mod inspector;
|
||||||
pub mod root;
|
pub mod root;
|
||||||
|
pub mod tab;
|
||||||
}
|
}
|
||||||
mod protocol;
|
mod protocol;
|
||||||
|
|
||||||
|
@ -76,7 +79,6 @@ fn run_server(port: Receiver<DevtoolsControlMsg>) {
|
||||||
let mut registry = ActorRegistry::new();
|
let mut registry = ActorRegistry::new();
|
||||||
|
|
||||||
let root = box RootActor {
|
let root = box RootActor {
|
||||||
next: 0,
|
|
||||||
tabs: vec!(),
|
tabs: vec!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -136,27 +138,36 @@ fn run_server(port: Receiver<DevtoolsControlMsg>) {
|
||||||
sender: Sender<DevtoolScriptControlMsg>) {
|
sender: Sender<DevtoolScriptControlMsg>) {
|
||||||
let mut actors = actors.lock();
|
let mut actors = actors.lock();
|
||||||
|
|
||||||
let (tab, console) = {
|
//TODO: move all this actor creation into a constructor method on TabActor
|
||||||
let root = actors.find_mut::<RootActor>("root");
|
let (tab, console, inspector) = {
|
||||||
|
|
||||||
let tab = TabActor {
|
|
||||||
name: format!("tab{}", root.next),
|
|
||||||
title: "".to_string(),
|
|
||||||
url: "about:blank".to_string(),
|
|
||||||
};
|
|
||||||
let console = ConsoleActor {
|
let console = ConsoleActor {
|
||||||
name: format!("console{}", root.next),
|
name: actors.new_name("console"),
|
||||||
script_chan: sender,
|
script_chan: sender,
|
||||||
pipeline: pipeline,
|
pipeline: pipeline,
|
||||||
};
|
};
|
||||||
|
let inspector = InspectorActor {
|
||||||
|
name: actors.new_name("inspector"),
|
||||||
|
walker: RefCell::new(None),
|
||||||
|
pageStyle: RefCell::new(None),
|
||||||
|
highlighter: RefCell::new(None),
|
||||||
|
};
|
||||||
|
//TODO: send along the current page title and URL
|
||||||
|
let tab = TabActor {
|
||||||
|
name: actors.new_name("tab"),
|
||||||
|
title: "".to_string(),
|
||||||
|
url: "about:blank".to_string(),
|
||||||
|
console: console.name(),
|
||||||
|
inspector: inspector.name(),
|
||||||
|
};
|
||||||
|
|
||||||
root.next += 1;
|
let root = actors.find_mut::<RootActor>("root");
|
||||||
root.tabs.push(tab.name.clone());
|
root.tabs.push(tab.name.clone());
|
||||||
(tab, console)
|
(tab, console, inspector)
|
||||||
};
|
};
|
||||||
|
|
||||||
actors.register(box tab);
|
actors.register(box tab);
|
||||||
actors.register(box console);
|
actors.register(box console);
|
||||||
|
actors.register(box inspector);
|
||||||
}
|
}
|
||||||
|
|
||||||
//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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue