diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/devtools.rs | 106 | ||||
-rw-r--r-- | components/script/lib.rs | 1 | ||||
-rw-r--r-- | components/script/script_task.rs | 96 |
3 files changed, 119 insertions, 84 deletions
diff --git a/components/script/devtools.rs b/components/script/devtools.rs new file mode 100644 index 00000000000..8d7a5d35bad --- /dev/null +++ b/components/script/devtools.rs @@ -0,0 +1,106 @@ +/* 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 devtools_traits; +use devtools_traits::{EvaluateJSReply, NodeInfo, Modification}; +use dom::bindings::conversions; +use dom::bindings::conversions::FromJSValConvertible; +use dom::bindings::js::{JSRef, Temporary, OptionalRootable}; +use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; +use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; +use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods}; +use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods}; +use dom::node::{Node, NodeHelpers}; +use dom::window::{WindowHelpers}; +use dom::element::Element; +use dom::document::DocumentHelpers; +use page::Page; +use servo_msg::constellation_msg::PipelineId; +use script_task::get_page; +use std::rc::Rc; + + +pub fn handle_evaluate_js(page: &Rc<Page>, pipeline: PipelineId, eval: String, reply: Sender<EvaluateJSReply>){ + let page = get_page(&*page, pipeline); + let frame = page.frame(); + let window = frame.as_ref().unwrap().window.root(); + let cx = window.get_cx(); + let rval = window.evaluate_js_with_result(eval.as_slice()); + + reply.send(if rval.is_undefined() { + devtools_traits::VoidValue + } else if rval.is_boolean() { + devtools_traits::BooleanValue(rval.to_boolean()) + } else if rval.is_double() { + devtools_traits::NumberValue(FromJSValConvertible::from_jsval(cx, rval, ()).unwrap()) + } else if rval.is_string() { + //FIXME: use jsstring_to_str when jsval grows to_jsstring + devtools_traits::StringValue(FromJSValConvertible::from_jsval(cx, rval, conversions::Default).unwrap()) + } else { + //FIXME: jsvals don't have an is_int32/is_number yet + assert!(rval.is_object_or_null()); + panic!("object values unimplemented") + }); +} + +pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) { + let page = get_page(&*page, pipeline); + let frame = page.frame(); + let document = frame.as_ref().unwrap().document.root(); + + let node: JSRef<Node> = NodeCast::from_ref(*document); + reply.send(node.summarize()); +} + +pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) { + let page = get_page(&*page, pipeline); + let frame = page.frame(); + let document = frame.as_ref().unwrap().document.root(); + let document_element = document.GetDocumentElement().root().unwrap(); + + let node: JSRef<Node> = NodeCast::from_ref(*document_element); + reply.send(node.summarize()); +} + +fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Temporary<Node> { + let page = get_page(&*page, pipeline); + let frame = page.frame(); + let document = frame.as_ref().unwrap().document.root(); + let node: JSRef<Node> = NodeCast::from_ref(*document); + + for candidate in node.traverse_preorder() { + if candidate.get_unique_id().as_slice() == node_id.as_slice() { + return Temporary::from_rooted(candidate); + } + } + + panic!("couldn't find node with unique id {:s}", node_id) +} + +pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) { + let parent = find_node_by_unique_id(&*page, pipeline, node_id).root(); + let children = parent.children().map(|child| child.summarize()).collect(); + reply.send(children); +} + +pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<(f32, f32)>) { + let node = find_node_by_unique_id(&*page, pipeline, node_id).root(); + let elem: JSRef<Element> = ElementCast::to_ref(*node).expect("should be getting layout of element"); + let rect = elem.GetBoundingClientRect().root(); + reply.send((rect.Width(), rect.Height())); +} + +pub fn handle_modify_attribute(page: &Rc<Page>, pipeline: PipelineId, node_id: String, modifications: Vec<Modification>) { + let node = find_node_by_unique_id(&*page, pipeline, node_id).root(); + let elem: JSRef<Element> = ElementCast::to_ref(*node).expect("should be getting layout of element"); + + for modification in modifications.iter(){ + match modification.newValue { + Some(ref string) => { + let _ = elem.SetAttribute(modification.attributeName.clone(), string.clone()); + }, + None => elem.RemoveAttribute(modification.attributeName.clone()), + } + } +} diff --git a/components/script/lib.rs b/components/script/lib.rs index 1e524ec7a62..3470cd63652 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -223,3 +223,4 @@ pub mod page; pub mod script_task; mod timers; pub mod textinput; +mod devtools; diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 35d51589d85..fdd4795ab25 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -7,13 +7,10 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyStateValues}; -use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; -use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; -use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, EventCast, ElementCast}; -use dom::bindings::conversions; +use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, EventCast}; use dom::bindings::conversions::{FromJSValConvertible, Empty}; use dom::bindings::global; use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalRootable}; @@ -36,11 +33,11 @@ use layout_interface::{ScriptLayoutChan, LayoutChan, NoQuery, ReflowForDisplay}; use layout_interface; use page::{Page, IterablePage, Frame}; use timers::TimerId; +use devtools; -use devtools_traits; -use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, NewGlobal, NodeInfo, GetRootNode}; -use devtools_traits::{DevtoolScriptControlMsg, EvaluateJS, EvaluateJSReply, GetDocumentElement}; -use devtools_traits::{GetChildren, GetLayout}; +use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, NewGlobal, GetRootNode}; +use devtools_traits::{DevtoolScriptControlMsg, EvaluateJS, GetDocumentElement}; +use devtools_traits::{GetChildren, GetLayout, ModifyAttribute}; use script_traits::{CompositorEvent, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent}; use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory}; use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, ViewportMsg, SendEventMsg}; @@ -553,11 +550,12 @@ impl ScriptTask { FromScript(DOMMessage(..)) => panic!("unexpected message"), FromScript(WorkerPostMessage(addr, data, nbytes)) => Worker::handle_message(addr, data, nbytes), FromScript(WorkerRelease(addr)) => Worker::handle_release(addr), - FromDevtools(EvaluateJS(id, s, reply)) => self.handle_evaluate_js(id, s, reply), - FromDevtools(GetRootNode(id, reply)) => self.handle_get_root_node(id, reply), - FromDevtools(GetDocumentElement(id, reply)) => self.handle_get_document_element(id, reply), - FromDevtools(GetChildren(id, node_id, reply)) => self.handle_get_children(id, node_id, reply), - FromDevtools(GetLayout(id, node_id, reply)) => self.handle_get_layout(id, node_id, reply), + FromDevtools(EvaluateJS(id, s, reply)) => devtools::handle_evaluate_js(&*self.page.borrow(), id, s, reply), + FromDevtools(GetRootNode(id, reply)) => devtools::handle_get_root_node(&*self.page.borrow(), id, reply), + FromDevtools(GetDocumentElement(id, reply)) => devtools::handle_get_document_element(&*self.page.borrow(), id, reply), + FromDevtools(GetChildren(id, node_id, reply)) => devtools::handle_get_children(&*self.page.borrow(), id, node_id, reply), + FromDevtools(GetLayout(id, node_id, reply)) => devtools::handle_get_layout(&*self.page.borrow(), id, node_id, reply), + FromDevtools(ModifyAttribute(id, node_id, modifications)) => devtools::handle_modify_attribute(&*self.page.borrow(), id, node_id, modifications), } } @@ -569,76 +567,6 @@ impl ScriptTask { true } - fn handle_evaluate_js(&self, pipeline: PipelineId, eval: String, reply: Sender<EvaluateJSReply>) { - let page = get_page(&*self.page.borrow(), pipeline); - let frame = page.frame(); - let window = frame.as_ref().unwrap().window.root(); - let cx = window.get_cx(); - let rval = window.evaluate_js_with_result(eval.as_slice()); - - reply.send(if rval.is_undefined() { - devtools_traits::VoidValue - } else if rval.is_boolean() { - devtools_traits::BooleanValue(rval.to_boolean()) - } else if rval.is_double() { - devtools_traits::NumberValue(FromJSValConvertible::from_jsval(cx, rval, ()).unwrap()) - } else if rval.is_string() { - //FIXME: use jsstring_to_str when jsval grows to_jsstring - devtools_traits::StringValue(FromJSValConvertible::from_jsval(cx, rval, conversions::Default).unwrap()) - } else { - //FIXME: jsvals don't have an is_int32/is_number yet - assert!(rval.is_object_or_null()); - panic!("object values unimplemented") - }); - } - - fn handle_get_root_node(&self, pipeline: PipelineId, reply: Sender<NodeInfo>) { - let page = get_page(&*self.page.borrow(), pipeline); - let frame = page.frame(); - let document = frame.as_ref().unwrap().document.root(); - - let node: JSRef<Node> = NodeCast::from_ref(*document); - reply.send(node.summarize()); - } - - fn handle_get_document_element(&self, pipeline: PipelineId, reply: Sender<NodeInfo>) { - let page = get_page(&*self.page.borrow(), pipeline); - let frame = page.frame(); - let document = frame.as_ref().unwrap().document.root(); - let document_element = document.GetDocumentElement().root().unwrap(); - - let node: JSRef<Node> = NodeCast::from_ref(*document_element); - reply.send(node.summarize()); - } - - fn find_node_by_unique_id(&self, pipeline: PipelineId, node_id: String) -> Temporary<Node> { - let page = get_page(&*self.page.borrow(), pipeline); - let frame = page.frame(); - let document = frame.as_ref().unwrap().document.root(); - let node: JSRef<Node> = NodeCast::from_ref(*document); - - for candidate in node.traverse_preorder() { - if candidate.get_unique_id().as_slice() == node_id.as_slice() { - return Temporary::from_rooted(candidate); - } - } - - panic!("couldn't find node with unique id {:s}", node_id) - } - - fn handle_get_children(&self, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) { - let parent = self.find_node_by_unique_id(pipeline, node_id).root(); - let children = parent.children().map(|child| child.summarize()).collect(); - reply.send(children); - } - - fn handle_get_layout(&self, pipeline: PipelineId, node_id: String, reply: Sender<(f32, f32)>) { - let node = self.find_node_by_unique_id(pipeline, node_id).root(); - let elem: JSRef<Element> = ElementCast::to_ref(*node).expect("should be getting layout of element"); - let rect = elem.GetBoundingClientRect().root(); - reply.send((rect.Width(), rect.Height())); - } - fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) { let NewLayoutInfo { old_pipeline_id, @@ -1210,7 +1138,7 @@ fn shut_down_layout(page_tree: &Rc<Page>, rt: *mut JSRuntime) { } -fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> { +pub fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> { page.find(pipeline_id).expect("ScriptTask: received an event \ message for a layout channel that is not associated with this script task.\ This is a bug.") |