diff options
Diffstat (limited to 'src/components/script/script_task.rs')
-rw-r--r-- | src/components/script/script_task.rs | 197 |
1 files changed, 95 insertions, 102 deletions
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 9d9897dfc54..c1c3a717f1a 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -29,7 +29,6 @@ use layout_interface::{Reflow, ReflowDocumentDamage, ReflowForDisplay, ReflowGoa use layout_interface::ContentChangedDocumentDamage; use layout_interface; -use extra::url::Url; use geom::point::Point2D; use geom::size::Size2D; use js::global::DEBUG_FNS; @@ -51,11 +50,12 @@ use servo_util::task::send_on_failure; use servo_util::namespace::Null; use std::cast; use std::cell::{RefCell, Ref, RefMut}; -use std::comm::{Port, Chan, Empty, Disconnected, Data}; +use std::comm::{channel, Sender, Receiver, Empty, Disconnected, Data}; use std::mem::replace; use std::ptr; use std::rc::Rc; use std::task; +use url::Url; use serialize::{Encoder, Encodable}; @@ -91,7 +91,7 @@ pub struct NewLayoutInfo { /// Encapsulates external communication with the script task. #[deriving(Clone)] -pub struct ScriptChan(Chan<ScriptMsg>); +pub struct ScriptChan(Sender<ScriptMsg>); impl<S: Encoder> Encodable<S> for ScriptChan { fn encode(&self, _s: &mut S) { @@ -100,8 +100,8 @@ impl<S: Encoder> Encodable<S> for ScriptChan { impl ScriptChan { /// Creates a new script chan. - pub fn new() -> (Port<ScriptMsg>, ScriptChan) { - let (port, chan) = Chan::new(); + pub fn new() -> (Receiver<ScriptMsg>, ScriptChan) { + let (chan, port) = channel(); (port, ScriptChan(chan)) } } @@ -121,7 +121,7 @@ pub struct Page { layout_chan: LayoutChan, /// The port that we will use to join layout. If this is `None`, then layout is not running. - layout_join_port: RefCell<Option<Port<()>>>, + layout_join_port: RefCell<Option<Receiver<()>>>, /// What parts of the document are dirty, if any. damage: RefCell<Option<DocumentDamage>>, @@ -149,7 +149,7 @@ pub struct Page { impl<S: Encoder> Encodable<S> for Page { fn encode(&self, s: &mut S) { let fragment_node = self.fragment_node.borrow(); - fragment_node.get().encode(s); + fragment_node.encode(s); } } @@ -188,7 +188,7 @@ impl PageTree { } fn page<'a>(&'a self) -> &'a Page { - self.page.borrow() + &*self.page } pub fn find<'a> (&'a mut self, id: PipelineId) -> Option<&'a mut PageTree> { @@ -276,8 +276,7 @@ impl Page { /// Adds the given damage. pub fn damage(&self, level: DocumentDamageLevel) { - let frame = self.frame(); - let root = match *frame.get() { + let root = match *self.frame() { None => return, Some(ref frame) => frame.document.get().GetDocumentElement() }; @@ -285,8 +284,8 @@ impl Page { None => {}, Some(root) => { let root: JS<Node> = NodeCast::from(&root); - let mut damage = self.damage.borrow_mut(); - match *damage.get() { + let mut damage = *self.damage.borrow_mut(); + match damage { None => {} Some(ref mut damage) => { // FIXME(pcwalton): This is wrong. We should trace up to the nearest ancestor. @@ -296,7 +295,7 @@ impl Page { } } - *damage.get() = Some(DocumentDamage { + *self.damage.borrow_mut() = Some(DocumentDamage { root: root.to_trusted_node_address(), level: level, }) @@ -305,16 +304,15 @@ impl Page { } pub fn get_url(&self) -> Url { - let url = self.url(); - url.get().get_ref().ref0().clone() + self.url().get_ref().ref0().clone() } /// Sends a ping to layout and waits for the response. The response will arrive when the /// layout task has finished any pending request messages. pub fn join_layout(&self) { let mut layout_join_port = self.layout_join_port.borrow_mut(); - if layout_join_port.get().is_some() { - let join_port = replace(layout_join_port.get(), None); + if layout_join_port.is_some() { + let join_port = replace(&mut *layout_join_port, None); match join_port { Some(ref join_port) => { match join_port.try_recv() { @@ -338,7 +336,7 @@ impl Page { /// Sends the given query to layout. pub fn query_layout<T: Send>(&self, query: LayoutQuery, - response_port: Port<T>) + response_port: Receiver<T>) -> T { self.join_layout(); let LayoutChan(ref chan) = self.layout_chan; @@ -357,8 +355,7 @@ impl Page { goal: ReflowGoal, script_chan: ScriptChan, compositor: &ScriptListener) { - let frame = self.frame(); - let root = match *frame.get() { + let root = match *self.frame() { None => return, Some(ref frame) => { frame.document.get().GetDocumentElement() @@ -377,12 +374,12 @@ impl Page { compositor.set_ready_state(PerformingLayout); // Layout will let us know when it's done. - let (join_port, join_chan) = Chan::new(); + let (join_chan, join_port) = channel(); let mut layout_join_port = self.layout_join_port.borrow_mut(); - *layout_join_port.get() = Some(join_port); + *layout_join_port = Some(join_port); let mut last_reflow_id = self.last_reflow_id.borrow_mut(); - *last_reflow_id.get() += 1; + *last_reflow_id += 1; let root: JS<Node> = NodeCast::from(&root); let mut damage = self.damage.borrow_mut(); @@ -393,11 +390,11 @@ impl Page { document_root: root.to_trusted_node_address(), url: self.get_url(), goal: goal, - window_size: *window_size.get(), + window_size: *window_size, script_chan: script_chan, script_join_chan: join_chan, - damage: replace(damage.get(), None).unwrap(), - id: *last_reflow_id.get(), + damage: replace(&mut *damage, None).unwrap(), + id: *last_reflow_id, }; let LayoutChan(ref chan) = self.layout_chan; @@ -414,8 +411,8 @@ impl Page { // Note that the order that these variables are initialized is _not_ arbitrary. Switching // them around can -- and likely will -- lead to things breaking. - js_context.borrow().set_default_options_and_version(); - js_context.borrow().set_logging_error_reporter(); + js_context.set_default_options_and_version(); + js_context.set_logging_error_reporter(); let compartment = match js_context.new_compartment_with_global(global) { Ok(c) => c, @@ -423,11 +420,11 @@ impl Page { }; unsafe { - JS_InhibitGC(js_context.borrow().ptr); + JS_InhibitGC(js_context.deref().ptr); } let mut js_info = self.mut_js_info(); - *js_info.get() = Some(JSPageInfo { + *js_info = Some(JSPageInfo { dom_static: GlobalStaticData(), js_compartment: compartment, js_context: js_context, @@ -467,7 +464,7 @@ pub struct ScriptTask { resource_task: ResourceTask, /// The port on which the script task receives messages (load URL, exit, etc.) - port: Port<ScriptMsg>, + port: Receiver<ScriptMsg>, /// A channel to hand out when some other task needs to be able to respond to a message from /// the script task. chan: ScriptChan, @@ -488,7 +485,7 @@ impl ScriptTask { pub fn new(id: PipelineId, compositor: ~ScriptListener, layout_chan: LayoutChan, - port: Port<ScriptMsg>, + port: Receiver<ScriptMsg>, chan: ScriptChan, constellation_chan: ConstellationChan, resource_task: ResourceTask, @@ -525,7 +522,7 @@ impl ScriptTask { id: PipelineId, compositor: ~C, layout_chan: LayoutChan, - port: Port<ScriptMsg>, + port: Receiver<ScriptMsg>, chan: ScriptChan, constellation_chan: ConstellationChan, failure_msg: Failure, @@ -545,7 +542,7 @@ impl ScriptTask { resource_task, image_cache_task, window_size); - script_task.borrow().start(); + script_task.start(); }); } @@ -557,13 +554,12 @@ impl ScriptTask { { let mut page_tree = self.page_tree.borrow_mut(); - for page in page_tree.get().iter() { + for page in page_tree.iter() { // Only process a resize if layout is idle. - let page = page.borrow(); let layout_join_port = page.layout_join_port.borrow(); - if layout_join_port.get().is_none() { + if layout_join_port.is_none() { let mut resize_event = page.resize_event.borrow_mut(); - match resize_event.get().take() { + match resize_event.take() { Some(size) => resizes.push((page.id, size)), None => () } @@ -585,9 +581,9 @@ impl ScriptTask { match event { ResizeMsg(id, size) => { let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.get().find(id).expect("resize sent to nonexistent pipeline").page(); + let page = page_tree.find(id).expect("resize sent to nonexistent pipeline").page(); let mut resize_event = page.resize_event.borrow_mut(); - *resize_event.get() = Some(size); + *resize_event = Some(size); } _ => { sequential.push(event); @@ -629,12 +625,12 @@ impl ScriptTask { } = new_layout_info; let mut page_tree = self.page_tree.borrow_mut(); - let parent_page_tree = page_tree.get().find(old_id).expect("ScriptTask: received a layout + let parent_page_tree = page_tree.find(old_id).expect("ScriptTask: received a layout whose parent has a PipelineId which does not correspond to a pipeline in the script task's page tree. This is a bug."); let new_page_tree = { let window_size = parent_page_tree.page().window_size.borrow(); - PageTree::new(new_id, layout_chan, *window_size.get()) + PageTree::new(new_id, layout_chan, *window_size) }; parent_page_tree.inner.push(new_page_tree); } @@ -642,10 +638,10 @@ impl ScriptTask { /// Handles a timer that fired. fn handle_fire_timer_msg(&self, id: PipelineId, timer_data: ~TimerData) { let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.get().find(id).expect("ScriptTask: received fire timer msg for a + let page = page_tree.find(id).expect("ScriptTask: received fire timer msg for a pipeline ID not associated with this script task. This is a bug.").page(); let frame = page.frame(); - let mut window = frame.get().get_ref().window.clone(); + let mut window = frame.get_ref().window.clone(); let timer_handle = window.get_mut().active_timers.pop(&timer_data.handle); if timer_handle.is_none() { @@ -656,12 +652,12 @@ impl ScriptTask { let this_value = if timer_data.args.len() > 0 { fail!("NYI") } else { - js_info.get().get_ref().js_compartment.borrow().global_obj + js_info.get_ref().js_compartment.global_obj }; // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. let rval = NullValue(); - let cx = js_info.get().get_ref().js_context.borrow().ptr; + let cx = js_info.get_ref().js_context.deref().ptr; with_gc_enabled(cx, || { unsafe { JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval); @@ -673,13 +669,13 @@ impl ScriptTask { fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: uint) { debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id); let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.get().find(pipeline_id).expect( + let page = page_tree.find(pipeline_id).expect( "ScriptTask: received a load message for a layout channel that is not associated \ with this script task. This is a bug.").page(); let last_reflow_id = page.last_reflow_id.borrow(); - if *last_reflow_id.get() == reflow_id { + if *last_reflow_id == reflow_id { let mut layout_join_port = page.layout_join_port.borrow_mut(); - *layout_join_port.get() = None; + *layout_join_port = None; } self.compositor.set_ready_state(FinishedLoading); } @@ -694,14 +690,14 @@ impl ScriptTask { /// Window was resized, but this script was not active, so don't reflow yet fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: Size2D<uint>) { let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.get().find(id).expect("Received resize message for PipelineId not associated + let page = page_tree.find(id).expect("Received resize message for PipelineId not associated with a page in the page tree. This is a bug.").page(); let mut window_size = page.window_size.borrow_mut(); - *window_size.get() = new_size; + *window_size = new_size; let mut page_url = page.mut_url(); - let last_loaded_url = replace(page_url.get(), None); + let last_loaded_url = replace(&mut *page_url, None); for url in last_loaded_url.iter() { - *page_url.get() = Some((url.ref0().clone(), true)); + *page_url = Some((url.ref0().clone(), true)); } } @@ -724,22 +720,20 @@ impl ScriptTask { fn handle_exit_pipeline_msg(&self, id: PipelineId) -> bool { // If root is being exited, shut down all pages let mut page_tree = self.page_tree.borrow_mut(); - if page_tree.get().page().id == id { - for page in page_tree.get().iter() { - let page = page.borrow(); + if page_tree.page().id == id { + for page in page_tree.iter() { debug!("shutting down layout for root page {:?}", page.id); - shut_down_layout(page) + shut_down_layout(&*page) } return true } // otherwise find just the matching page and exit all sub-pages - match page_tree.get().remove(id) { + match page_tree.remove(id) { Some(ref mut page_tree) => { for page in page_tree.iter() { - let page = page.borrow(); debug!("shutting down layout for page {:?}", page.id); - shut_down_layout(page) + shut_down_layout(&*page) } false } @@ -757,18 +751,18 @@ impl ScriptTask { debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id); let mut page_tree = self.page_tree.borrow_mut(); - let page_tree = page_tree.get().find(pipeline_id).expect("ScriptTask: received a load + let page_tree = page_tree.find(pipeline_id).expect("ScriptTask: received a load message for a layout channel that is not associated with this script task. This is a bug."); let page = page_tree.page(); { let mut page_url = page.mut_url(); - let last_loaded_url = replace(page_url.get(), None); + let last_loaded_url = replace(&mut *page_url, None); for loaded in last_loaded_url.iter() { let (ref loaded, needs_reflow) = *loaded; if *loaded == url { - *page_url.get() = Some((loaded.clone(), false)); + *page_url = Some((loaded.clone(), false)); if needs_reflow { page.damage(ContentChangedDocumentDamage); page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor); @@ -780,7 +774,7 @@ impl ScriptTask { let cx = self.js_runtime.cx(); // Create the window and document objects. - let window = Window::new(cx.borrow().ptr, + let window = Window::new(cx.deref().ptr, page_tree.page.clone(), self.chan.clone(), self.compositor.dup(), @@ -789,7 +783,7 @@ impl ScriptTask { { let mut js_info = page.mut_js_info(); - RegisterBindings::Register(js_info.get().get_mut_ref()); + RegisterBindings::Register(js_info.get_mut_ref()); } self.compositor.set_ready_state(Loading); @@ -809,7 +803,7 @@ impl ScriptTask { { // Create the root frame. let mut frame = page.mut_frame(); - *frame.get() = Some(Frame { + *frame = Some(Frame { document: document.clone(), window: window.clone(), }); @@ -857,7 +851,7 @@ impl ScriptTask { { // No more reflow required let mut page_url = page.mut_url(); - *page_url.get() = Some((url.clone(), false)); + *page_url = Some((url.clone(), false)); } // Receive the JavaScript scripts. @@ -868,11 +862,10 @@ impl ScriptTask { // Define debug functions. let cx = { let js_info = page.js_info(); - let js_info = js_info.get().get_ref(); - let compartment = js_info.js_compartment.borrow(); - assert!(compartment.define_functions(DEBUG_FNS).is_ok()); + let js_info = js_info.get_ref(); + assert!(js_info.js_compartment.define_functions(DEBUG_FNS).is_ok()); - js_info.js_context.borrow().ptr + js_info.js_context.deref().ptr }; // Evaluate every script in the document. @@ -880,15 +873,15 @@ impl ScriptTask { with_gc_enabled(cx, || { let (cx, global_obj) = { let js_info = page.js_info(); - (js_info.get().get_ref().js_context.clone(), - js_info.get().get_ref().js_compartment.borrow().global_obj) + (js_info.get_ref().js_context.clone(), + js_info.get_ref().js_compartment.global_obj) }; //FIXME: this should have some kind of error handling, or explicitly // drop an exception on the floor. - assert!(cx.borrow().evaluate_script(global_obj, - file.data.clone(), - file.url.to_str(), - 1).is_ok()); + assert!(cx.evaluate_script(global_obj, + file.data.clone(), + file.url.to_str(), + 1).is_ok()); }); } @@ -903,7 +896,7 @@ impl ScriptTask { let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event); let mut fragment_node = page.fragment_node.borrow_mut(); - *fragment_node.get() = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid)); + *fragment_node = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid)); let ConstellationChan(ref chan) = self.constellation_chan; chan.send(LoadCompleteMsg(page.id, url)); @@ -911,7 +904,7 @@ impl ScriptTask { fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> { let frame = page.frame(); - let document = frame.get().get_ref().document.clone(); + let document = frame.get_ref().document.clone(); match document.get().GetElementById(fragid.to_owned()) { Some(node) => Some(node), None => { @@ -928,7 +921,7 @@ impl ScriptTask { } fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &Page, node: JS<Element>) { - let (port, chan) = Chan::new(); + let (chan, port) = channel(); let node: JS<Node> = NodeCast::from(&node); let ContentBoxResponse(rect) = page.query_layout(ContentBoxQuery(node.to_trusted_node_address(), chan), port); @@ -946,7 +939,7 @@ impl ScriptTask { /// TODO: Actually perform DOM event dispatch. fn handle_event(&self, pipeline_id: PipelineId, event: Event_) { let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.get().find(pipeline_id).expect("ScriptTask: received an event + let page = page_tree.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.").page(); @@ -956,25 +949,25 @@ impl ScriptTask { { let mut window_size = page.window_size.borrow_mut(); - *window_size.get() = Size2D(new_width, new_height); + *window_size = Size2D(new_width, new_height); } { let frame = page.frame(); - if frame.get().is_some() { + if frame.is_some() { page.damage(ReflowDocumentDamage); page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor) } } let mut fragment_node = page.fragment_node.borrow_mut(); - match fragment_node.get().take() { + match fragment_node.take() { Some(node) => self.scroll_fragment_point(pipeline_id, page, node), None => {} } let frame = page.frame(); - match *frame.get() { + match *frame { Some(ref frame) => { // http://dev.w3.org/csswg/cssom-view/#resizing-viewports // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize @@ -997,7 +990,7 @@ impl ScriptTask { debug!("script got reflow event"); let frame = page.frame(); - if frame.get().is_some() { + if frame.is_some() { page.damage(MatchSelectorsDocumentDamage); page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor) } @@ -1007,18 +1000,18 @@ impl ScriptTask { debug!("ClickEvent: clicked at {:?}", point); let frame = page.frame(); - let document = frame.get().get_ref().document.clone(); + let document = frame.get_ref().document.clone(); let root = document.get().GetDocumentElement(); if root.is_none() { return; } - let (port, chan) = Chan::new(); + let (chan, port) = channel(); let root: JS<Node> = NodeCast::from(&root.unwrap()); match page.query_layout(HitTestQuery(root.to_trusted_node_address(), point, chan), port) { Ok(HitTestResponse(node_address)) => { debug!("node address is {:?}", node_address); let mut node: JS<Node> = - NodeHelpers::from_untrusted_node_address(self.js_runtime.borrow().ptr, + NodeHelpers::from_untrusted_node_address(self.js_runtime.deref().ptr, node_address); debug!("clicked on {:s}", node.debug_str()); @@ -1045,21 +1038,21 @@ impl ScriptTask { MouseUpEvent(..) => {} MouseMoveEvent(point) => { let frame = page.frame(); - let document = frame.get().get_ref().document.clone(); + let document = frame.get_ref().document.clone(); let root = document.get().GetDocumentElement(); if root.is_none() { return; } let root: JS<Node> = NodeCast::from(&root.unwrap()); - let (port, chan) = Chan::new(); + let (chan, port) = channel(); match page.query_layout(MouseOverQuery(root.to_trusted_node_address(), point, chan), port) { Ok(MouseOverResponse(node_address)) => { let mut target_list: ~[JS<Node>] = ~[]; let mut target_compare = false; - let mut mouse_over_targets = self.mouse_over_targets.borrow_mut(); - match *mouse_over_targets.get() { + let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut(); + match *mouse_over_targets { Some(ref mut mouse_over_targets) => { for node in mouse_over_targets.mut_iter() { node.set_hover_state(false); @@ -1071,7 +1064,7 @@ impl ScriptTask { for node_address in node_address.iter() { let mut node: JS<Node> = NodeHelpers::from_untrusted_node_address( - self.js_runtime.borrow().ptr, *node_address); + self.js_runtime.deref().ptr, *node_address); // Traverse node generations until a node that is an element is // found. while !node.is_element() { @@ -1084,7 +1077,7 @@ impl ScriptTask { if node.is_element() { node.set_hover_state(true); - match *mouse_over_targets.get() { + match *mouse_over_targets { Some(ref mouse_over_targets) => { if !target_compare { target_compare = !mouse_over_targets.contains(&node); @@ -1095,7 +1088,7 @@ impl ScriptTask { target_list.push(node); } } - match *mouse_over_targets.get() { + match *mouse_over_targets { Some(ref mouse_over_targets) => { if mouse_over_targets.len() != target_list.len() { target_compare = true; @@ -1105,11 +1098,11 @@ impl ScriptTask { } if target_compare { - if mouse_over_targets.get().is_some() { + if mouse_over_targets.is_some() { page.damage(MatchSelectorsDocumentDamage); page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor); } - *mouse_over_targets.get() = Some(target_list); + *mouse_over_targets = Some(target_list); } }, Err(()) => {}, @@ -1146,7 +1139,7 @@ fn shut_down_layout(page: &Page) { page.join_layout(); // Tell the layout task to begin shutting down. - let (response_port, response_chan) = Chan::new(); + let (response_chan, response_port) = channel(); let LayoutChan(ref chan) = page.layout_chan; chan.send(layout_interface::PrepareToExitMsg(response_chan)); response_port.recv(); @@ -1156,12 +1149,12 @@ fn shut_down_layout(page: &Page) { let mut js_info = page.mut_js_info(); unsafe { - JS_AllowGC(js_info.get().get_ref().js_context.borrow().ptr); + JS_AllowGC(js_info.get_ref().js_context.deref().ptr); } let mut frame = page.mut_frame(); - *frame.get() = None; - *js_info.get() = None; + *frame = None; + *js_info = None; // Destroy the layout task. If there were node leaks, layout will now crash safely. chan.send(layout_interface::ExitNowMsg); |