aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r--components/script/script_task.rs100
1 files changed, 84 insertions, 16 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 6334dcb26a0..134c629b091 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -24,8 +24,8 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLIFrameElementCast, NodeCast, EventCast};
use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::conversions::StringificationBehavior;
-use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, RootedReference};
-use dom::bindings::js::{RootCollection, RootCollectionPtr, Unrooted};
+use dom::bindings::js::{JS, JSRef, OptionalRootable, RootedReference};
+use dom::bindings::js::{RootCollection, RootCollectionPtr};
use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference};
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::{JSTraceable, trace_collections};
@@ -47,6 +47,7 @@ use devtools;
use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, DevtoolsPageInfo};
use devtools_traits::{DevtoolsControlMsg, DevtoolScriptControlMsg};
+use devtools_traits::{TimelineMarker, TimelineMarkerType, TracingMetadata};
use script_traits::CompositorEvent;
use script_traits::CompositorEvent::{ResizeEvent, ReflowEvent, ClickEvent};
use script_traits::CompositorEvent::{MouseDownEvent, MouseUpEvent};
@@ -86,6 +87,7 @@ use std::ascii::AsciiExt;
use std::any::Any;
use std::borrow::ToOwned;
use std::cell::{Cell, RefCell};
+use std::collections::HashSet;
use std::num::ToPrimitive;
use std::option::Option;
use std::ptr;
@@ -279,6 +281,10 @@ pub struct ScriptTask {
/// no such server exists.
devtools_port: DevtoolsControlPort,
devtools_sender: Sender<DevtoolScriptControlMsg>,
+ /// For sending timeline markers. Will be ignored if
+ /// no devtools server
+ devtools_markers: RefCell<HashSet<TimelineMarkerType>>,
+ devtools_marker_sender: RefCell<Option<Sender<TimelineMarker>>>,
/// The JavaScript runtime.
js_runtime: js::rust::rt,
@@ -317,7 +323,7 @@ impl<'a> Drop for ScriptMemoryFailsafe<'a> {
unsafe {
let page = owner.page.borrow_for_script_deallocation();
for page in page.iter() {
- let window = Unrooted::from_temporary(page.window());
+ let window = page.window_for_script_deallocation();
(*window.unsafe_get()).clear_js_context_for_script_deallocation();
}
*owner.js_context.borrow_for_script_deallocation() = None;
@@ -447,6 +453,8 @@ impl ScriptTask {
devtools_chan: devtools_chan,
devtools_port: devtools_receiver,
devtools_sender: devtools_sender,
+ devtools_markers: RefCell::new(HashSet::new()),
+ devtools_marker_sender: RefCell::new(None),
js_runtime: js_runtime,
js_context: DOMRefCell::new(Some(js_context)),
@@ -700,6 +708,10 @@ impl ScriptTask {
devtools::handle_modify_attribute(&page, id, node_id, modifications),
DevtoolScriptControlMsg::WantsLiveNotifications(pipeline_id, to_send) =>
devtools::handle_wants_live_notifications(&page, pipeline_id, to_send),
+ DevtoolScriptControlMsg::SetTimelineMarkers(_pipeline_id, marker_types, reply) =>
+ devtools::handle_set_timeline_markers(&page, self, marker_types, reply),
+ DevtoolScriptControlMsg::DropTimelineMarkers(_pipeline_id, marker_types) =>
+ devtools::handle_drop_timeline_markers(&page, self, marker_types),
}
}
@@ -811,9 +823,8 @@ impl ScriptTask {
let doc: JSRef<Node> = NodeCast::from_ref(doc.r());
doc.traverse_preorder()
- .filter_map(HTMLIFrameElementCast::to_ref)
- .find(|node| node.subpage_id() == Some(subpage_id))
- .map(Temporary::from_rooted)
+ .filter_map(HTMLIFrameElementCast::to_temporary)
+ .find(|node| node.root().r().subpage_id() == Some(subpage_id))
}).root();
if let Some(frame_element) = frame_element {
@@ -832,9 +843,8 @@ impl ScriptTask {
let doc: JSRef<Node> = NodeCast::from_ref(doc.r());
doc.traverse_preorder()
- .filter_map(HTMLIFrameElementCast::to_ref)
- .find(|node| node.subpage_id() == Some(old_subpage_id))
- .map(Temporary::from_rooted)
+ .filter_map(HTMLIFrameElementCast::to_temporary)
+ .find(|node| node.root().r().subpage_id() == Some(old_subpage_id))
}).root();
frame_element.unwrap().r().update_subpage_id(new_subpage_id);
@@ -952,10 +962,9 @@ impl ScriptTask {
let doc: JSRef<Node> = NodeCast::from_ref(doc.r());
doc.traverse_preorder()
- .filter_map(HTMLIFrameElementCast::to_ref)
- .find(|node| node.subpage_id() == Some(subpage_id))
- .map(ElementCast::from_ref)
- .map(Temporary::from_rooted)
+ .filter_map(HTMLIFrameElementCast::to_temporary)
+ .find(|node| node.root().r().subpage_id() == Some(subpage_id))
+ .map(ElementCast::from_temporary)
})
})
}).root();
@@ -1153,8 +1162,14 @@ impl ScriptTask {
///
/// TODO: Actually perform DOM event dispatch.
fn handle_event(&self, pipeline_id: PipelineId, event: CompositorEvent) {
+
match event {
ResizeEvent(new_size) => {
+ let _marker;
+ if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
+ _marker = AutoDOMEventMarker::new(self);
+ }
+
self.handle_resize_event(pipeline_id, new_size);
}
@@ -1182,6 +1197,10 @@ impl ScriptTask {
}
ClickEvent(button, point) => {
+ let _marker;
+ if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
+ _marker = AutoDOMEventMarker::new(self);
+ }
let page = get_page(&self.root_page(), pipeline_id);
let document = page.document().root();
document.r().handle_click_event(self.js_runtime.ptr, button, point);
@@ -1190,6 +1209,10 @@ impl ScriptTask {
MouseDownEvent(..) => {}
MouseUpEvent(..) => {}
MouseMoveEvent(point) => {
+ let _marker;
+ if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
+ _marker = AutoDOMEventMarker::new(self);
+ }
let page = get_page(&self.root_page(), pipeline_id);
let document = page.document().root();
let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();
@@ -1198,6 +1221,10 @@ impl ScriptTask {
}
KeyEvent(key, state, modifiers) => {
+ let _marker;
+ if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
+ _marker = AutoDOMEventMarker::new(self);
+ }
let page = get_page(&self.root_page(), pipeline_id);
let document = page.document().root();
document.r().dispatch_key_event(
@@ -1218,9 +1245,8 @@ impl ScriptTask {
let doc: JSRef<Node> = NodeCast::from_ref(doc.r());
doc.traverse_preorder()
- .filter_map(HTMLIFrameElementCast::to_ref)
- .find(|node| node.subpage_id() == Some(subpage_id))
- .map(Temporary::from_rooted)
+ .filter_map(HTMLIFrameElementCast::to_temporary)
+ .find(|node| node.root().r().subpage_id() == Some(subpage_id))
}).root();
if let Some(iframe) = iframe.r() {
iframe.navigate_child_browsing_context(load_data.url);
@@ -1315,6 +1341,26 @@ impl ScriptTask {
self.incomplete_loads.borrow_mut().push(incomplete);
}
+
+ fn need_emit_timeline_marker(&self, timeline_type: TimelineMarkerType) -> bool {
+ self.devtools_markers.borrow().contains(&timeline_type)
+ }
+
+ fn emit_timeline_marker(&self, marker: TimelineMarker) {
+ let sender = self.devtools_marker_sender.borrow();
+ let sender = sender.as_ref().expect("There is no marker sender");
+ sender.send(marker);
+ }
+
+ pub fn set_devtools_timeline_marker(&self, marker: TimelineMarkerType, reply: Sender<TimelineMarker>) {
+ *self.devtools_marker_sender.borrow_mut() = Some(reply);
+ self.devtools_markers.borrow_mut().insert(marker);
+ }
+
+ pub fn drop_devtools_timeline_markers(&self) {
+ self.devtools_markers.borrow_mut().clear();
+ *self.devtools_marker_sender.borrow_mut() = None;
+ }
}
impl Drop for ScriptTask {
@@ -1325,6 +1371,28 @@ impl Drop for ScriptTask {
}
}
+struct AutoDOMEventMarker<'a> {
+ script_task: &'a ScriptTask
+}
+
+impl<'a> AutoDOMEventMarker<'a> {
+ fn new(script_task: &'a ScriptTask) -> AutoDOMEventMarker<'a> {
+ let marker = TimelineMarker::new("DOMEvent".to_owned(), TracingMetadata::IntervalStart);
+ script_task.emit_timeline_marker(marker);
+ AutoDOMEventMarker {
+ script_task: script_task
+ }
+ }
+}
+
+#[unsafe_destructor]
+impl<'a> Drop for AutoDOMEventMarker<'a> {
+ fn drop(&mut self) {
+ let marker = TimelineMarker::new("DOMEvent".to_owned(), TracingMetadata::IntervalEnd);
+ self.script_task.emit_timeline_marker(marker);
+ }
+}
+
/// Shuts down layout for the given page tree.
fn shut_down_layout(page_tree: &Rc<Page>, exit_type: PipelineExitType) {
let mut channels = vec!();