aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_thread.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r--components/script/script_thread.rs66
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, _))) |