mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00: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::collections::hashmap::HashMap;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::io::TcpStream;
|
||||
use std::mem::{transmute, transmute_copy};
|
||||
use std::raw::TraitObject;
|
||||
|
@ -69,6 +70,8 @@ impl<'a> AnyRefExt<'a> for &'a Actor {
|
|||
/// A list of known, owned actors.
|
||||
pub struct ActorRegistry {
|
||||
actors: HashMap<String, Box<Actor+Send+Sized>>,
|
||||
new_actors: RefCell<Vec<Box<Actor+Send+Sized>>>,
|
||||
next: Cell<u32>,
|
||||
}
|
||||
|
||||
impl ActorRegistry {
|
||||
|
@ -76,14 +79,28 @@ impl ActorRegistry {
|
|||
pub fn new() -> ActorRegistry {
|
||||
ActorRegistry {
|
||||
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.
|
||||
pub fn register(&mut self, actor: Box<Actor+Send+Sized>) {
|
||||
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
|
||||
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
|
||||
|
@ -104,7 +121,7 @@ impl ActorRegistry {
|
|||
|
||||
/// 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.
|
||||
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();
|
||||
match self.actors.find(&to.to_string()) {
|
||||
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)]
|
||||
struct ActorTraits {
|
||||
sources: bool
|
||||
sources: bool,
|
||||
highlightable: bool,
|
||||
customHighlighters: Vec<String>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
|
@ -40,7 +42,6 @@ struct RootActorMsg {
|
|||
}
|
||||
|
||||
pub struct RootActor {
|
||||
pub next: u32,
|
||||
pub tabs: Vec<String>,
|
||||
}
|
||||
|
||||
|
@ -90,6 +91,8 @@ impl RootActor {
|
|||
applicationType: "browser".to_string(),
|
||||
traits: ActorTraits {
|
||||
sources: true,
|
||||
highlightable: true,
|
||||
customHighlighters: vec!("BoxModelHighlighter".to_string()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,20 @@ struct ReconfigureReply {
|
|||
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)]
|
||||
pub struct TabActorMsg {
|
||||
actor: String,
|
||||
|
@ -43,12 +57,15 @@ pub struct TabActorMsg {
|
|||
url: String,
|
||||
outerWindowID: uint,
|
||||
consoleActor: String,
|
||||
inspectorActor: String,
|
||||
}
|
||||
|
||||
pub struct TabActor {
|
||||
pub name: String,
|
||||
pub title: String,
|
||||
pub url: String,
|
||||
pub console: String,
|
||||
pub inspector: String,
|
||||
}
|
||||
|
||||
impl Actor for TabActor {
|
||||
|
@ -90,6 +107,16 @@ impl Actor for TabActor {
|
|||
stream.write_json_packet(&msg);
|
||||
true
|
||||
}
|
||||
|
||||
"listFrames" => {
|
||||
let msg = ListFramesReply {
|
||||
from: self.name(),
|
||||
frames: vec!(),
|
||||
};
|
||||
stream.write_json_packet(&msg);
|
||||
true
|
||||
}
|
||||
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +129,8 @@ impl TabActor {
|
|||
title: self.title.clone(),
|
||||
url: self.url.clone(),
|
||||
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 servo_msg = "msg";
|
||||
|
||||
use actor::ActorRegistry;
|
||||
use actor::{Actor, ActorRegistry};
|
||||
use actors::console::ConsoleActor;
|
||||
use actors::inspector::InspectorActor;
|
||||
use actors::root::RootActor;
|
||||
use actors::tab::TabActor;
|
||||
use protocol::JsonPacketSender;
|
||||
|
@ -36,6 +37,7 @@ use protocol::JsonPacketSender;
|
|||
use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg};
|
||||
use servo_msg::constellation_msg::PipelineId;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::comm;
|
||||
use std::comm::{Disconnected, Empty};
|
||||
use std::io::{TcpListener, TcpStream};
|
||||
|
@ -49,8 +51,9 @@ mod actor;
|
|||
/// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/
|
||||
mod actors {
|
||||
pub mod console;
|
||||
pub mod tab;
|
||||
pub mod inspector;
|
||||
pub mod root;
|
||||
pub mod tab;
|
||||
}
|
||||
mod protocol;
|
||||
|
||||
|
@ -76,7 +79,6 @@ fn run_server(port: Receiver<DevtoolsControlMsg>) {
|
|||
let mut registry = ActorRegistry::new();
|
||||
|
||||
let root = box RootActor {
|
||||
next: 0,
|
||||
tabs: vec!(),
|
||||
};
|
||||
|
||||
|
@ -136,27 +138,36 @@ fn run_server(port: Receiver<DevtoolsControlMsg>) {
|
|||
sender: Sender<DevtoolScriptControlMsg>) {
|
||||
let mut actors = actors.lock();
|
||||
|
||||
let (tab, console) = {
|
||||
let root = actors.find_mut::<RootActor>("root");
|
||||
|
||||
let tab = TabActor {
|
||||
name: format!("tab{}", root.next),
|
||||
title: "".to_string(),
|
||||
url: "about:blank".to_string(),
|
||||
};
|
||||
//TODO: move all this actor creation into a constructor method on TabActor
|
||||
let (tab, console, inspector) = {
|
||||
let console = ConsoleActor {
|
||||
name: format!("console{}", root.next),
|
||||
name: actors.new_name("console"),
|
||||
script_chan: sender,
|
||||
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());
|
||||
(tab, console)
|
||||
(tab, console, inspector)
|
||||
};
|
||||
|
||||
actors.register(box tab);
|
||||
actors.register(box console);
|
||||
actors.register(box inspector);
|
||||
}
|
||||
|
||||
//TODO: figure out some system that allows us to watch for new connections,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue