aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/attr.rs10
-rw-r--r--components/script/dom/node.rs63
-rw-r--r--components/script/lib.rs1
-rw-r--r--components/script/script_task.rs50
4 files changed, 121 insertions, 3 deletions
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs
index be419eb2a61..ebad173edda 100644
--- a/components/script/dom/attr.rs
+++ b/components/script/dom/attr.rs
@@ -2,6 +2,7 @@
* 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::AttrInfo;
use dom::bindings::codegen::Bindings::AttrBinding;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::InheritTypes::NodeCast;
@@ -149,6 +150,7 @@ pub trait AttrHelpers {
fn set_value(&self, set_type: AttrSettingType, value: AttrValue);
fn value<'a>(&'a self) -> Ref<'a, AttrValue>;
fn local_name<'a>(&'a self) -> &'a Atom;
+ fn summarize(&self) -> AttrInfo;
}
impl<'a> AttrHelpers for JSRef<'a, Attr> {
@@ -184,6 +186,14 @@ impl<'a> AttrHelpers for JSRef<'a, Attr> {
fn local_name<'a>(&'a self) -> &'a Atom {
&self.local_name
}
+
+ fn summarize(&self) -> AttrInfo {
+ AttrInfo {
+ namespace: self.GetNamespaceURI().unwrap_or("".to_string()),
+ name: self.Name(),
+ value: self.Value(),
+ }
+ }
}
pub trait AttrHelpersForLayout {
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 50af3e637ae..e58f0e888a6 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -4,12 +4,15 @@
//! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements.
+use devtools_traits::NodeInfo;
use dom::attr::{Attr, AttrHelpers};
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
+use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
use dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
+use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
use dom::bindings::codegen::InheritTypes::{CommentCast, DocumentCast, DocumentTypeCast};
use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast, ElementDerived};
@@ -36,7 +39,7 @@ use dom::element::{HTMLInputElementTypeId, HTMLSelectElementTypeId};
use dom::element::{HTMLTextAreaElementTypeId, HTMLOptGroupElementTypeId};
use dom::element::{HTMLOptionElementTypeId, HTMLFieldSetElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
-use dom::nodelist::{NodeList};
+use dom::nodelist::NodeList;
use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
use dom::virtualmethods::{VirtualMethods, vtable_for};
@@ -59,6 +62,7 @@ use std::mem;
use style;
use style::ComputedValues;
use sync::Arc;
+use uuid;
use serialize::{Encoder, Encodable};
@@ -105,6 +109,8 @@ pub struct Node {
/// Must be sent back to the layout task to be destroyed when this
/// node is finalized.
pub layout_data: LayoutDataRef,
+
+ unique_id: RefCell<String>,
}
impl<S: Encoder<E>, E> Encodable<S, E> for LayoutDataRef {
@@ -419,6 +425,9 @@ pub trait NodeHelpers<'m, 'n> {
fn query_selector_all(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>>;
fn remove_self(&self);
+
+ fn get_unique_id(&self) -> String;
+ fn summarize(&self) -> NodeInfo;
}
impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> {
@@ -687,6 +696,56 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> {
None => ()
}
}
+
+ fn get_unique_id(&self) -> String {
+ self.unique_id.borrow().clone()
+ }
+
+ fn summarize(&self) -> NodeInfo {
+ if self.unique_id.borrow().as_slice() == "" {
+ let mut unique_id = self.unique_id.borrow_mut();
+ *unique_id = uuid::Uuid::new_v4().to_simple_str();
+ }
+
+ NodeInfo {
+ uniqueId: self.unique_id.borrow().clone(),
+ baseURI: self.GetBaseURI().unwrap_or("".to_string()),
+ parent: self.GetParentNode().root().map(|node| node.unique_id.borrow().clone()).unwrap_or("".to_string()),
+ nodeType: self.NodeType() as uint,
+ namespaceURI: "".to_string(), //FIXME
+ nodeName: self.NodeName(),
+ numChildren: self.ChildNodes().root().Length() as uint,
+
+ //FIXME doctype nodes only
+ name: "".to_string(),
+ publicId: "".to_string(),
+ systemId: "".to_string(),
+
+ attrs: if self.is_element() {
+ let mut summarized = vec!();
+ let elem: &JSRef<Element> = ElementCast::to_ref(self).unwrap();
+ let attrs = elem.Attributes().root();
+ let mut i = 0;
+ while i < attrs.Length() {
+ let attr = attrs.Item(i).unwrap().root();
+ summarized.push(attr.summarize());
+ i += 1;
+ }
+ summarized
+ } else {
+ vec!()
+ },
+
+ isDocumentElement:
+ self.owner_doc().root()
+ .GetDocumentElement()
+ .map(|elem| NodeCast::from_ref(&*elem.root()) == self)
+ .unwrap_or(false),
+
+ shortValue: self.GetNodeValue().unwrap_or("".to_string()), //FIXME: truncate
+ incompleteValue: false, //FIXME: reflect truncation
+ }
+ }
}
/// If the given untrusted node address represents a valid DOM node in the given runtime,
@@ -991,6 +1050,8 @@ impl Node {
flags: Traceable::new(RefCell::new(NodeFlags::new(type_id))),
layout_data: LayoutDataRef::new(),
+
+ unique_id: RefCell::new("".to_string()),
}
}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index d7c13cc06a1..4318f4b3f21 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -40,6 +40,7 @@ extern crate style;
extern crate sync;
extern crate servo_msg = "msg";
extern crate url;
+extern crate uuid;
pub mod cors;
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 2feb088201c..e49350a1942 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -5,6 +5,7 @@
//! The script task is the task that owns the DOM in memory, runs JavaScript, and spawns parsing
//! and layout tasks.
+use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, EventCast};
use dom::bindings::conversions;
use dom::bindings::conversions::{FromJSValConvertible, Empty};
@@ -33,8 +34,9 @@ use layout_interface;
use page::{Page, IterablePage, Frame};
use devtools_traits;
-use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, NewGlobal};
-use devtools_traits::{DevtoolScriptControlMsg, EvaluateJS, EvaluateJSReply};
+use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, NewGlobal, NodeInfo, GetRootNode};
+use devtools_traits::{DevtoolScriptControlMsg, EvaluateJS, EvaluateJSReply, GetDocumentElement};
+use devtools_traits::{GetChildren};
use script_traits::{CompositorEvent, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent};
use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory};
use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, SendEventMsg, ResizeInactiveMsg};
@@ -501,6 +503,9 @@ impl ScriptTask {
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),
}
}
@@ -530,6 +535,47 @@ impl ScriptTask {
});
}
+ 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.get_ref().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.get_ref().document.root();
+ let document_element = document.GetDocumentElement().root().unwrap();
+
+ let node: &JSRef<Node> = NodeCast::from_ref(&*document_element);
+ reply.send(node.summarize());
+ }
+
+ fn handle_get_children(&self, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) {
+ let page = get_page(&*self.page.borrow(), pipeline);
+ let frame = page.frame();
+ let document = frame.get_ref().document.root();
+ let node: &JSRef<Node> = NodeCast::from_ref(&*document);
+
+ let mut children = vec!();
+ let mut found_parent = false;
+ for candidate in node.traverse_preorder() {
+ if candidate.get_unique_id().as_slice() == node_id.as_slice() {
+ found_parent = true;
+ for kid in candidate.children() {
+ children.push(kid.summarize());
+ }
+ break;
+ }
+ }
+
+ assert!(found_parent);
+ reply.send(children);
+ }
+
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) {
debug!("Script: new layout: {:?}", new_layout_info);
let NewLayoutInfo {