diff options
author | Harrison G <Harrison.Gould16@Gmail.com> | 2015-08-08 15:08:45 -0400 |
---|---|---|
committer | Harrison G <Harrison.Gould16@Gmail.com> | 2015-08-09 11:45:16 -0400 |
commit | e0f007a940b5d0799f904d12ff46fece45736fc9 (patch) | |
tree | 638549c48782a26e9cade8b545216f541157c2fa | |
parent | 6a8bc8528498c0cbb2e50567d765a989cde2d115 (diff) | |
download | servo-e0f007a940b5d0799f904d12ff46fece45736fc9.tar.gz servo-e0f007a940b5d0799f904d12ff46fece45736fc9.zip |
Closes #6724 (Allows object evaluation in devtools)
The purpose of this is to fix how objects were previously evaluated in
the developer tools.
- Before this, evaluating an object such as the `window` would `panic!`
- After this, evaluating an object such as the `window` outputs `[object
Window]`
A few things to note:
- This commit contains `unsafe` code.
- This does not contain a test because the developer tools cannot be properly tested until #5971 lands.
-rw-r--r-- | components/devtools/actors/console.rs | 13 | ||||
-rw-r--r-- | components/devtools/actors/object.rs | 44 | ||||
-rw-r--r-- | components/devtools/lib.rs | 6 | ||||
-rw-r--r-- | components/devtools_traits/lib.rs | 2 | ||||
-rw-r--r-- | components/script/devtools.rs | 17 |
5 files changed, 71 insertions, 11 deletions
diff --git a/components/devtools/actors/console.rs b/components/devtools/actors/console.rs index 641dc9345d9..9eca96d6272 100644 --- a/components/devtools/actors/console.rs +++ b/components/devtools/actors/console.rs @@ -8,6 +8,7 @@ //! inspection, JS evaluation, autocompletion) in Servo. use actor::{Actor, ActorRegistry}; +use actors::object::ObjectActor; use protocol::JsonPacketStream; use devtools_traits::EvaluateJSReply::{NullValue, VoidValue, NumberValue}; @@ -92,7 +93,7 @@ impl Actor for ConsoleActor { } fn handle_message(&self, - _registry: &ActorRegistry, + registry: &ActorRegistry, msg_type: &str, msg: &json::Object, stream: &mut TcpStream) -> Result<bool, ()> { @@ -210,12 +211,14 @@ impl Actor for ConsoleActor { } } StringValue(s) => s.to_json(), - ActorValue(s) => { - //TODO: make initial ActorValue message include these properties. + ActorValue { class, uuid } => { + //TODO: make initial ActorValue message include these properties? let mut m = BTreeMap::new(); + let actor = ObjectActor::new(registry, uuid); + m.insert("type".to_string(), "object".to_string().to_json()); - m.insert("class".to_string(), "???".to_string().to_json()); - m.insert("actor".to_string(), s.to_json()); + m.insert("class".to_string(), class.to_json()); + m.insert("actor".to_string(), actor.to_json()); m.insert("extensible".to_string(), true.to_json()); m.insert("frozen".to_string(), false.to_json()); m.insert("sealed".to_string(), false.to_json()); diff --git a/components/devtools/actors/object.rs b/components/devtools/actors/object.rs new file mode 100644 index 00000000000..d6103a5ed3f --- /dev/null +++ b/components/devtools/actors/object.rs @@ -0,0 +1,44 @@ +/* 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/. */ + +use actor::{Actor, ActorRegistry}; +use rustc_serialize::json; +use std::net::TcpStream; + +pub struct ObjectActor { + pub name: String, + pub uuid: String, +} + +impl Actor for ObjectActor { + fn name(&self) -> String { + self.name.clone() + } + fn handle_message(&self, + _: &ActorRegistry, + _: &str, + _: &json::Object, + _: &mut TcpStream) -> Result<bool, ()> { + Ok(false) + } +} + +impl ObjectActor { + pub fn new(registry: &ActorRegistry, uuid: String) -> String { + if !registry.script_actor_registered(uuid.clone()) { + let name = registry.new_name("object"); + let actor = ObjectActor { + name: name.clone(), + uuid: uuid.clone(), + }; + + registry.register_script_actor(uuid, name.clone()); + registry.register_later(box actor); + + name + } else { + registry.script_to_actor(uuid) + } + } +} diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index c791a9c46f2..d36268901af 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -40,6 +40,7 @@ use actors::console::ConsoleActor; use actors::network_event::{NetworkEventActor, EventActor, ResponseStartMsg}; use actors::framerate::FramerateActor; use actors::inspector::InspectorActor; +use actors::object::ObjectActor; use actors::root::RootActor; use actors::tab::TabActor; use actors::timeline::TimelineActor; @@ -68,13 +69,14 @@ mod actor; mod actors { pub mod console; pub mod framerate; - pub mod memory; pub mod inspector; + pub mod memory; + pub mod network_event; + pub mod object; pub mod root; pub mod tab; pub mod timeline; pub mod worker; - pub mod network_event; } mod protocol; diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index 16218f911dc..599abab609b 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -77,7 +77,7 @@ pub enum EvaluateJSReply { BooleanValue(bool), NumberValue(f64), StringValue(String), - ActorValue(String), + ActorValue { class: String, uuid: String }, } #[derive(Deserialize, Serialize)] diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 3307eb20dc3..2211df2931b 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -20,11 +20,14 @@ use page::{IterablePage, Page}; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; use script_task::{get_page, ScriptTask}; -use js::jsapi::RootedValue; +use js::jsapi::{ObjectClassName, RootedObject, RootedValue}; use js::jsval::UndefinedValue; - +use std::ffi::CStr; use std::rc::Rc; +use std::str; +use uuid::Uuid; +#[allow(unsafe_code)] pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<EvaluateJSReply>) { let cx = global.get_cx(); let mut rval = RootedValue::new(cx, UndefinedValue()); @@ -43,7 +46,15 @@ pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<Eva EvaluateJSReply::NullValue } else { assert!(rval.ptr.is_object()); - panic!("object values unimplemented") + + let obj = RootedObject::new(cx, rval.ptr.to_object()); + let class_name = unsafe { CStr::from_ptr(ObjectClassName(cx, obj.handle())) }; + let class_name = str::from_utf8(class_name.to_bytes()).unwrap(); + + EvaluateJSReply::ActorValue { + class: class_name.to_owned(), + uuid: Uuid::new_v4().to_string(), + } }).unwrap(); } |