diff options
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r-- | components/script/script_thread.rs | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 20a8602a249..35ae783f5ff 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -40,6 +40,8 @@ use dom::element::Element; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::htmlanchorelement::HTMLAnchorElement; use dom::node::{Node, NodeDamage, window_from_node}; +use dom::serviceworker::TrustedServiceWorkerAddress; +use dom::serviceworkerregistration::ServiceWorkerRegistration; use dom::servohtmlparser::ParserContext; use dom::uievent::UIEvent; use dom::window::{ReflowReason, ScriptHelpers, Window}; @@ -86,9 +88,8 @@ use script_traits::{ScriptThreadFactory, TimerEvent, TimerEventRequest, TimerSou use script_traits::{TouchEventType, TouchId}; use std::borrow::ToOwned; use std::cell::{Cell, RefCell}; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::option::Option; -use std::ptr; use std::rc::Rc; use std::result::Result; use std::sync::atomic::{Ordering, AtomicBool}; @@ -265,6 +266,12 @@ impl ScriptPort for Receiver<(TrustedWorkerAddress, MainThreadScriptMsg)> { } } +impl ScriptPort for Receiver<(TrustedServiceWorkerAddress, CommonScriptMsg)> { + fn recv(&self) -> Result<CommonScriptMsg, ()> { + self.recv().map(|(_, msg)| msg).map_err(|_| ()) + } +} + /// Encapsulates internal communication of shared messages within the script thread. #[derive(JSTraceable)] pub struct SendableMainThreadScriptChan(pub Sender<CommonScriptMsg>); @@ -309,6 +316,8 @@ pub struct ScriptThread { browsing_context: MutNullableHeap<JS<BrowsingContext>>, /// A list of data pertaining to loads that have not yet received a network response incomplete_loads: DOMRefCell<Vec<InProgressLoad>>, + /// A map to store service worker registrations for a given origin + registration_map: DOMRefCell<HashMap<Url, JS<ServiceWorkerRegistration>>>, /// A handle to the image cache thread. image_cache_thread: ImageCacheThread, /// A handle to the resource thread. This is an `Arc` to avoid running out of file descriptors if @@ -479,14 +488,22 @@ pub unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext, } impl ScriptThread { - pub fn page_fetch_complete(id: &PipelineId, subpage: Option<&SubpageId>, metadata: Option<Metadata>) - -> Option<ParserRoot> { + pub fn page_headers_available(id: &PipelineId, subpage: Option<&SubpageId>, metadata: Option<Metadata>) + -> Option<ParserRoot> { SCRIPT_THREAD_ROOT.with(|root| { let script_thread = unsafe { &*root.borrow().unwrap() }; - script_thread.handle_page_fetch_complete(id, subpage, metadata) + script_thread.handle_page_headers_available(id, subpage, metadata) }) } + // stores a service worker registration + pub fn set_registration(scope_url: Url, registration:&ServiceWorkerRegistration) { + SCRIPT_THREAD_ROOT.with(|root| { + let script_thread = unsafe { &*root.borrow().unwrap() }; + script_thread.handle_serviceworker_registration(scope_url, registration); + }); + } + pub fn parsing_complete(id: PipelineId) { SCRIPT_THREAD_ROOT.with(|root| { let script_thread = unsafe { &*root.borrow().unwrap() }; @@ -549,6 +566,7 @@ impl ScriptThread { ScriptThread { browsing_context: MutNullableHeap::new(None), incomplete_loads: DOMRefCell::new(vec!()), + registration_map: DOMRefCell::new(HashMap::new()), image_cache_thread: state.image_cache_thread, image_cache_channel: ImageCacheChan(ipc_image_cache_channel), @@ -708,6 +726,11 @@ impl ScriptThread { self.handle_viewport(id, rect); }) } + FromConstellation(ConstellationControlMsg::SetScrollState(id, scroll_offset)) => { + self.profile_event(ScriptThreadEventCategory::SetScrollState, || { + self.handle_set_scroll_state(id, &scroll_offset); + }) + } FromConstellation(ConstellationControlMsg::TickAllAnimations( pipeline_id)) => { if !animation_ticks.contains(&pipeline_id) { @@ -850,6 +873,9 @@ impl ScriptThread { ScriptThreadEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent, ScriptThreadEventCategory::Resize => ProfilerCategory::ScriptResize, ScriptThreadEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent, + ScriptThreadEventCategory::SetScrollState => { + ProfilerCategory::ScriptSetScrollState + } ScriptThreadEventCategory::UpdateReplacedElement => { ProfilerCategory::ScriptUpdateReplacedElement } @@ -858,6 +884,7 @@ impl ScriptThread { ScriptThreadEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent, ScriptThreadEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent, ScriptThreadEventCategory::WorkerEvent => ProfilerCategory::ScriptWorkerEvent, + ScriptThreadEventCategory::ServiceWorkerEvent => ProfilerCategory::ScriptServiceWorkerEvent }; profile(profiler_cat, None, self.time_profiler_chan.clone(), f) } else { @@ -877,6 +904,8 @@ impl ScriptThread { self.handle_resize_inactive_msg(id, new_size), ConstellationControlMsg::Viewport(..) => panic!("should have handled Viewport already"), + ConstellationControlMsg::SetScrollState(..) => + panic!("should have handled SetScrollState already"), ConstellationControlMsg::Resize(..) => panic!("should have handled Resize already"), ConstellationControlMsg::ExitPipeline(..) => @@ -1077,6 +1106,19 @@ impl ScriptThread { panic!("Page rect message sent to nonexistent pipeline"); } + fn handle_set_scroll_state(&self, id: PipelineId, scroll_state: &Point2D<f32>) { + let context = self.browsing_context.get(); + if let Some(context) = context { + if let Some(inner_context) = context.find(id) { + let window = inner_context.active_window(); + window.update_viewport_for_scroll(-scroll_state.x, -scroll_state.y); + return + } + } + + panic!("Set scroll state message message sent to nonexistent pipeline: {:?}", id); + } + fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) { let NewLayoutInfo { containing_pipeline_id, @@ -1299,8 +1341,8 @@ impl ScriptThread { /// We have received notification that the response associated with a load has completed. /// Kick off the document and frame tree creation process using the result. - fn handle_page_fetch_complete(&self, id: &PipelineId, subpage: Option<&SubpageId>, - metadata: Option<Metadata>) -> Option<ParserRoot> { + fn handle_page_headers_available(&self, id: &PipelineId, subpage: Option<&SubpageId>, + metadata: Option<Metadata>) -> Option<ParserRoot> { let idx = self.incomplete_loads.borrow().iter().position(|load| { load.pipeline_id == *id && load.parent_info.as_ref().map(|info| &info.1) == subpage }); @@ -1318,6 +1360,10 @@ impl ScriptThread { } } + fn handle_serviceworker_registration(&self, scope: Url, registration: &ServiceWorkerRegistration) { + self.registration_map.borrow_mut().insert(scope, JS::from_ref(registration)); + } + /// Handles a request for the window title. fn handle_get_title_msg(&self, pipeline_id: PipelineId) { let context = get_browsing_context(&self.root_browsing_context(), pipeline_id); @@ -1550,9 +1596,9 @@ impl ScriptThread { } }); - let loader = DocumentLoader::new_with_thread(Arc::new(self.resource_threads.sender()), - Some(browsing_context.pipeline()), - Some(incomplete.url.clone())); + let loader = DocumentLoader::new_with_threads(self.resource_threads.clone(), + Some(browsing_context.pipeline()), + Some(incomplete.url.clone())); let is_html_document = match metadata.content_type { Some(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _))) | |