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.rs204
1 files changed, 108 insertions, 96 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index e116ace1be4..e3d2766c84c 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -51,8 +51,8 @@ use dom::worker::TrustedWorkerAddress;
use euclid::Rect;
use euclid::point::Point2D;
use gfx_traits::LayerId;
-use hyper::header::{ContentType, HttpDate};
-use hyper::header::{Headers, LastModified};
+use hyper::header::{ContentType, Headers, HttpDate, LastModified};
+use hyper::header::{ReferrerPolicy as ReferrerPolicyHeader};
use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
use ipc_channel::ipc::{self, IpcSender};
@@ -64,13 +64,12 @@ use js::jsapi::{JSTracer, SetWindowProxyClass};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use mem::heap_size_of_self_and_children;
-use msg::constellation_msg::{FrameType, LoadData, PanicMsg, PipelineId, PipelineNamespace};
-use msg::constellation_msg::{SubpageId, WindowSizeType};
-use net_traits::LoadData as NetLoadData;
+use msg::constellation_msg::{FrameType, LoadData, PipelineId, PipelineNamespace};
+use msg::constellation_msg::{SubpageId, WindowSizeType, ReferrerPolicy};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata, ResourceThreads};
-use net_traits::{RequestSource, CustomResponse, CustomResponseSender, IpcSend};
+use net_traits::{IpcSend, LoadData as NetLoadData};
use network_listener::NetworkListener;
use parse::ParserRoot;
use parse::html::{ParseContext, parse_html};
@@ -174,10 +173,10 @@ pub struct RunnableWrapper {
}
impl RunnableWrapper {
- pub fn wrap_runnable<T: Runnable + Send + 'static>(&self, runnable: T) -> Box<Runnable + Send> {
+ pub fn wrap_runnable<T: Runnable + Send + 'static>(&self, runnable: Box<T>) -> Box<Runnable + Send> {
box CancellableRunnable {
cancelled: self.cancelled.clone(),
- inner: box runnable,
+ inner: runnable,
}
}
}
@@ -189,10 +188,16 @@ pub struct CancellableRunnable<T: Runnable + Send> {
}
impl<T: Runnable + Send> Runnable for CancellableRunnable<T> {
+ fn name(&self) -> &'static str { self.inner.name() }
+
fn is_cancelled(&self) -> bool {
self.cancelled.load(Ordering::SeqCst)
}
+ fn main_thread_handler(self: Box<CancellableRunnable<T>>, script_thread: &ScriptThread) {
+ self.inner.main_thread_handler(script_thread);
+ }
+
fn handler(self: Box<CancellableRunnable<T>>) {
self.inner.handler()
}
@@ -210,8 +215,7 @@ enum MixedMessage {
FromScript(MainThreadScriptMsg),
FromDevtools(DevtoolScriptControlMsg),
FromImageCache(ImageCacheResult),
- FromScheduler(TimerEvent),
- FromNetwork(IpcSender<Option<CustomResponse>>),
+ FromScheduler(TimerEvent)
}
/// Messages used to control the script event loop
@@ -336,12 +340,6 @@ pub struct ScriptThread {
/// events in the event queue.
chan: MainThreadScriptChan,
- /// A handle to network event messages
- custom_message_chan: IpcSender<CustomResponseSender>,
-
- /// The port which receives a sender from the network
- custom_message_port: Receiver<CustomResponseSender>,
-
dom_manipulation_task_source: DOMManipulationTaskSource,
user_interaction_task_source: UserInteractionTaskSource,
@@ -395,8 +393,6 @@ pub struct ScriptThread {
timer_event_port: Receiver<TimerEvent>,
content_process_shutdown_chan: IpcSender<()>,
-
- panic_chan: IpcSender<PanicMsg>,
}
/// In the event of thread panic, all data on the stack runs its destructor. However, there
@@ -443,15 +439,15 @@ impl ScriptThreadFactory for ScriptThread {
fn create(state: InitialScriptState,
load_data: LoadData)
-> (Sender<message::Msg>, Receiver<message::Msg>) {
- let panic_chan = state.panic_chan.clone();
let (script_chan, script_port) = channel();
let (sender, receiver) = channel();
let layout_chan = sender.clone();
let pipeline_id = state.id;
- thread::spawn_named_with_send_on_panic(format!("ScriptThread {:?}", state.id),
- thread_state::SCRIPT,
- move || {
+ thread::spawn_named(format!("ScriptThread {:?}", state.id),
+ move || {
+ thread_state::initialize(thread_state::SCRIPT);
+ PipelineId::install(pipeline_id);
PipelineNamespace::install(state.pipeline_namespace_id);
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);
@@ -481,7 +477,7 @@ impl ScriptThreadFactory for ScriptThread {
// This must always be the very last operation performed before the thread completes
failsafe.neuter();
- }, Some(pipeline_id), panic_chan);
+ });
(sender, receiver)
}
@@ -503,10 +499,10 @@ impl ScriptThread {
}
// stores a service worker registration
- pub fn set_registration(scope_url: Url, registration:&ServiceWorkerRegistration) {
+ pub fn set_registration(scope_url: Url, registration:&ServiceWorkerRegistration, pipeline_id: PipelineId) {
SCRIPT_THREAD_ROOT.with(|root| {
let script_thread = unsafe { &*root.get().unwrap() };
- script_thread.handle_serviceworker_registration(scope_url, registration);
+ script_thread.handle_serviceworker_registration(scope_url, registration, pipeline_id);
});
}
@@ -556,9 +552,6 @@ impl ScriptThread {
let (ipc_devtools_sender, ipc_devtools_receiver) = ipc::channel().unwrap();
let devtools_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_devtools_receiver);
- let (ipc_custom_resp_chan, ipc_custom_resp_port) = ipc::channel().unwrap();
- let custom_msg_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_custom_resp_port);
-
// Ask the router to proxy IPC messages from the image cache thread to us.
let (ipc_image_cache_channel, ipc_image_cache_port) = ipc::channel().unwrap();
let image_cache_port =
@@ -569,6 +562,8 @@ impl ScriptThread {
// Ask the router to proxy IPC messages from the control port to us.
let control_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(state.control_port);
+ let boxed_script_sender = MainThreadScriptChan(chan.clone()).clone();
+
ScriptThread {
browsing_context: MutNullableHeap::new(None),
incomplete_loads: DOMRefCell::new(vec!()),
@@ -582,22 +577,19 @@ impl ScriptThread {
bluetooth_thread: state.bluetooth_thread,
port: port,
- custom_message_chan: ipc_custom_resp_chan,
- custom_message_port: custom_msg_port,
chan: MainThreadScriptChan(chan.clone()),
dom_manipulation_task_source: DOMManipulationTaskSource(chan.clone()),
user_interaction_task_source: UserInteractionTaskSource(chan.clone()),
networking_task_source: NetworkingTaskSource(chan.clone()),
- history_traversal_task_source: HistoryTraversalTaskSource(chan.clone()),
- file_reading_task_source: FileReadingTaskSource(chan),
+ history_traversal_task_source: HistoryTraversalTaskSource(chan),
+ file_reading_task_source: FileReadingTaskSource(boxed_script_sender),
control_chan: state.control_chan,
control_port: control_port,
constellation_chan: state.constellation_chan,
time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: state.mem_profiler_chan,
- panic_chan: state.panic_chan,
devtools_chan: state.devtools_chan,
devtools_port: devtools_port,
@@ -645,7 +637,7 @@ impl ScriptThread {
/// Handle incoming control messages.
fn handle_msgs(&self) -> bool {
use self::MixedMessage::{FromConstellation, FromDevtools, FromImageCache};
- use self::MixedMessage::{FromScheduler, FromScript, FromNetwork};
+ use self::MixedMessage::{FromScheduler, FromScript};
// Handle pending resize events.
// Gather them first to avoid a double mut borrow on self.
@@ -679,7 +671,6 @@ impl ScriptThread {
let mut timer_event_port = sel.handle(&self.timer_event_port);
let mut devtools_port = sel.handle(&self.devtools_port);
let mut image_cache_port = sel.handle(&self.image_cache_port);
- let mut custom_message_port = sel.handle(&self.custom_message_port);
unsafe {
script_port.add();
control_port.add();
@@ -688,7 +679,6 @@ impl ScriptThread {
devtools_port.add();
}
image_cache_port.add();
- custom_message_port.add();
}
let ret = sel.wait();
if ret == script_port.id() {
@@ -701,8 +691,6 @@ impl ScriptThread {
FromDevtools(self.devtools_port.recv().unwrap())
} else if ret == image_cache_port.id() {
FromImageCache(self.image_cache_port.recv().unwrap())
- } else if ret == custom_message_port.id() {
- FromNetwork(self.custom_message_port.recv().unwrap())
} else {
panic!("unexpected select result")
}
@@ -770,10 +758,7 @@ impl ScriptThread {
Err(_) => match self.timer_event_port.try_recv() {
Err(_) => match self.devtools_port.try_recv() {
Err(_) => match self.image_cache_port.try_recv() {
- Err(_) => match self.custom_message_port.try_recv() {
- Err(_) => break,
- Ok(ev) => event = FromNetwork(ev)
- },
+ Err(_) => break,
Ok(ev) => event = FromImageCache(ev),
},
Ok(ev) => event = FromDevtools(ev),
@@ -799,7 +784,6 @@ impl ScriptThread {
},
FromConstellation(inner_msg) => self.handle_msg_from_constellation(inner_msg),
FromScript(inner_msg) => self.handle_msg_from_script(inner_msg),
- FromNetwork(inner_msg) => self.handle_msg_from_network(inner_msg),
FromScheduler(inner_msg) => self.handle_timer_event(inner_msg),
FromDevtools(inner_msg) => self.handle_msg_from_devtools(inner_msg),
FromImageCache(inner_msg) => self.handle_msg_from_image_cache(inner_msg),
@@ -858,8 +842,7 @@ impl ScriptThread {
_ => ScriptThreadEventCategory::ScriptEvent
}
},
- MixedMessage::FromScheduler(_) => ScriptThreadEventCategory::TimerEvent,
- MixedMessage::FromNetwork(_) => ScriptThreadEventCategory::NetworkEvent
+ MixedMessage::FromScheduler(_) => ScriptThreadEventCategory::TimerEvent
}
}
@@ -900,22 +883,12 @@ impl ScriptThread {
fn handle_msg_from_constellation(&self, msg: ConstellationControlMsg) {
match msg {
- ConstellationControlMsg::AttachLayout(_) =>
- panic!("should have handled AttachLayout already"),
ConstellationControlMsg::Navigate(pipeline_id, subpage_id, load_data) =>
self.handle_navigate(pipeline_id, Some(subpage_id), load_data),
ConstellationControlMsg::SendEvent(id, event) =>
self.handle_event(id, event),
ConstellationControlMsg::ResizeInactive(id, new_size) =>
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(..) =>
- panic!("should have handled ExitPipeline already"),
ConstellationControlMsg::GetTitle(pipeline_id) =>
self.handle_get_title_msg(pipeline_id),
ConstellationControlMsg::Freeze(pipeline_id) =>
@@ -957,6 +930,12 @@ impl ScriptThread {
self.handle_css_error_reporting(pipeline_id, filename, line, column, msg),
ConstellationControlMsg::Reload(pipeline_id) =>
self.handle_reload(pipeline_id),
+ msg @ ConstellationControlMsg::AttachLayout(..) |
+ msg @ ConstellationControlMsg::Viewport(..) |
+ msg @ ConstellationControlMsg::SetScrollState(..) |
+ msg @ ConstellationControlMsg::Resize(..) |
+ msg @ ConstellationControlMsg::ExitPipeline(..) =>
+ panic!("should have handled {:?} already", msg),
}
}
@@ -982,7 +961,7 @@ impl ScriptThread {
MainThreadScriptMsg::DOMManipulation(task) =>
task.handle_task(self),
MainThreadScriptMsg::UserInteraction(task) =>
- task.handle_task(),
+ task.handle_task(self),
}
}
@@ -1048,12 +1027,6 @@ impl ScriptThread {
msg.responder.unwrap().respond(msg.image_response);
}
- fn handle_msg_from_network(&self, msg: IpcSender<Option<CustomResponse>>) {
- // We may detect controlling service workers here
- // We send None as default
- let _ = msg.send(None);
- }
-
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
let context = self.root_browsing_context();
match msg {
@@ -1100,7 +1073,10 @@ impl ScriptThread {
fn handle_resize(&self, id: PipelineId, size: WindowSizeData, size_type: WindowSizeType) {
if let Some(ref context) = self.find_child_context(id) {
- let window = context.active_window();
+ let window = match context.find(id) {
+ Some(browsing_context) => browsing_context.active_window(),
+ None => return warn!("Message sent to closed pipeline {}.", id),
+ };
window.set_resize_event(size, size_type);
return;
}
@@ -1166,10 +1142,10 @@ impl ScriptThread {
frame_type,
load_data,
paint_chan,
- panic_chan,
pipeline_port,
layout_to_constellation_chan,
content_process_shutdown_chan,
+ layout_threads,
} = new_layout_info;
let layout_pair = channel();
@@ -1182,11 +1158,11 @@ impl ScriptThread {
layout_pair: layout_pair,
pipeline_port: pipeline_port,
constellation_chan: layout_to_constellation_chan,
- panic_chan: panic_chan,
paint_chan: paint_chan,
script_chan: self.control_chan.clone(),
image_cache_thread: self.image_cache_thread.clone(),
content_process_shutdown_chan: content_process_shutdown_chan,
+ layout_threads: layout_threads,
};
let context = self.root_browsing_context();
@@ -1221,9 +1197,7 @@ impl ScriptThread {
// https://html.spec.whatwg.org/multipage/#the-end step 7
let handler = box DocumentProgressHandler::new(Trusted::new(doc));
- self.dom_manipulation_task_source.queue(DOMManipulationTask::Runnable(handler)).unwrap();
-
- self.constellation_chan.send(ConstellationMsg::LoadComplete(pipeline)).unwrap();
+ self.dom_manipulation_task_source.queue(handler, GlobalRef::Window(doc.window())).unwrap();
}
fn collect_reports(&self, reports_chan: ReportsChan) {
@@ -1375,17 +1349,17 @@ impl ScriptThread {
/// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart
fn handle_mozbrowser_event_msg(&self,
parent_pipeline_id: PipelineId,
- subpage_id: SubpageId,
+ subpage_id: Option<SubpageId>,
event: MozBrowserEvent) {
- let borrowed_context = self.root_browsing_context();
-
- let frame_element = borrowed_context.find(parent_pipeline_id).and_then(|context| {
- let doc = context.active_document();
- doc.find_iframe(subpage_id)
- });
-
- if let Some(ref frame_element) = frame_element {
- frame_element.dispatch_mozbrowser_event(event);
+ match self.root_browsing_context().find(parent_pipeline_id) {
+ None => warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id),
+ Some(context) => match subpage_id {
+ None => context.active_window().dispatch_mozbrowser_event(event),
+ Some(subpage_id) => match context.active_document().find_iframe(subpage_id) {
+ None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, subpage_id),
+ Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
+ },
+ },
}
}
@@ -1449,8 +1423,33 @@ impl ScriptThread {
}
}
- fn handle_serviceworker_registration(&self, scope: Url, registration: &ServiceWorkerRegistration) {
- self.registration_map.borrow_mut().insert(scope, JS::from_ref(registration));
+ fn handle_serviceworker_registration(&self,
+ scope: Url,
+ registration: &ServiceWorkerRegistration,
+ pipeline_id: PipelineId) {
+ {
+ let ref mut reg_ref = *self.registration_map.borrow_mut();
+ // according to spec we should replace if an older registration exists for
+ // same scope otherwise just insert the new one
+ let _ = reg_ref.remove(&scope);
+ reg_ref.insert(scope.clone(), JS::from_ref(registration));
+ }
+
+ // send ScopeThings to sw-manager
+ let ref maybe_registration_ref = *self.registration_map.borrow();
+ let maybe_registration = match maybe_registration_ref.get(&scope) {
+ Some(r) => r,
+ None => return
+ };
+ if let Some(context) = self.root_browsing_context().find(pipeline_id) {
+ let window = context.active_window();
+ let global_ref = GlobalRef::Window(window.r());
+ let script_url = maybe_registration.get_installed().get_script_url();
+ let scope_things = ServiceWorkerRegistration::create_scope_things(global_ref, script_url);
+ let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope));
+ } else {
+ warn!("Registration failed for {}", pipeline_id);
+ }
}
/// Handles a request for the window title.
@@ -1579,7 +1578,6 @@ impl ScriptThread {
let UserInteractionTaskSource(ref user_sender) = self.user_interaction_task_source;
let NetworkingTaskSource(ref network_sender) = self.networking_task_source;
let HistoryTraversalTaskSource(ref history_sender) = self.history_traversal_task_source;
- let FileReadingTaskSource(ref file_sender) = self.file_reading_task_source;
let (ipc_timer_event_chan, ipc_timer_event_port) = ipc::channel().unwrap();
ROUTER.route_ipc_receiver_to_mpsc_sender(ipc_timer_event_port,
@@ -1592,9 +1590,8 @@ impl ScriptThread {
UserInteractionTaskSource(user_sender.clone()),
NetworkingTaskSource(network_sender.clone()),
HistoryTraversalTaskSource(history_sender.clone()),
- FileReadingTaskSource(file_sender.clone()),
+ self.file_reading_task_source.clone(),
self.image_cache_channel.clone(),
- self.custom_message_chan.clone(),
self.image_cache_thread.clone(),
self.resource_threads.clone(),
self.bluetooth_thread.clone(),
@@ -1604,7 +1601,6 @@ impl ScriptThread {
self.constellation_chan.clone(),
self.control_chan.clone(),
self.scheduler_chan.clone(),
- self.panic_chan.clone(),
ipc_timer_event_chan,
incomplete.layout_chan,
incomplete.pipeline_id,
@@ -1704,6 +1700,30 @@ impl ScriptThread {
_ => IsHTMLDocument::HTMLDocument,
};
+ let referrer = match metadata.referrer {
+ Some(ref referrer) => Some(referrer.clone().into_string()),
+ None => None,
+ };
+
+ let referrer_policy = if let Some(headers) = metadata.headers {
+ headers.get::<ReferrerPolicyHeader>().map(|h| match *h {
+ ReferrerPolicyHeader::NoReferrer =>
+ ReferrerPolicy::NoReferrer,
+ ReferrerPolicyHeader::NoReferrerWhenDowngrade =>
+ ReferrerPolicy::NoReferrerWhenDowngrade,
+ ReferrerPolicyHeader::SameOrigin =>
+ ReferrerPolicy::SameOrigin,
+ ReferrerPolicyHeader::Origin =>
+ ReferrerPolicy::Origin,
+ ReferrerPolicyHeader::OriginWhenCrossOrigin =>
+ ReferrerPolicy::OriginWhenCrossOrigin,
+ ReferrerPolicyHeader::UnsafeUrl =>
+ ReferrerPolicy::UnsafeUrl,
+ })
+ } else {
+ None
+ };
+
let document = Document::new(window.r(),
Some(&browsing_context),
Some(final_url.clone()),
@@ -1711,7 +1731,9 @@ impl ScriptThread {
content_type,
last_modified,
DocumentSource::FromParser,
- loader);
+ loader,
+ referrer,
+ referrer_policy);
if using_new_context {
browsing_context.init(&document);
} else {
@@ -2079,8 +2101,7 @@ impl ScriptThread {
pipeline_id: Some(id),
credentials_flag: true,
referrer_policy: load_data.referrer_policy,
- referrer_url: load_data.referrer_url,
- source: RequestSource::Window(self.custom_message_chan.clone())
+ referrer_url: load_data.referrer_url
}, LoadConsumer::Listener(response_target), None)).unwrap();
self.incomplete_loads.borrow_mut().push(incomplete);
@@ -2191,15 +2212,6 @@ fn shut_down_layout(context_tree: &BrowsingContext) {
}
}
-// TODO: remove this function, as it's a source of panic.
-pub fn get_browsing_context(context: &BrowsingContext,
- pipeline_id: PipelineId)
- -> Root<BrowsingContext> {
- context.find(pipeline_id).expect("ScriptThread: received an event \
- message for a layout channel that is not associated with this script thread.\
- This is a bug.")
-}
-
fn dom_last_modified(tm: &Tm) -> String {
tm.to_local().strftime("%m/%d/%Y %H:%M:%S").unwrap().to_string()
}