mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
adding interface for custom responses
This commit is contained in:
parent
bcea0ada27
commit
3766cd1673
17 changed files with 663 additions and 146 deletions
|
@ -8,8 +8,8 @@
|
|||
use dom::bindings::js::JS;
|
||||
use dom::document::Document;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::AsyncResponseTarget;
|
||||
use net_traits::{PendingAsyncLoad, CoreResourceThread, LoadContext};
|
||||
use net_traits::{RequestSource, AsyncResponseTarget};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use url::Url;
|
||||
|
@ -130,20 +130,27 @@ impl DocumentLoader {
|
|||
|
||||
/// Create a new pending network request, which can be initiated at some point in
|
||||
/// the future.
|
||||
pub fn prepare_async_load(&mut self, load: LoadType, referrer: &Document) -> PendingAsyncLoad {
|
||||
pub fn prepare_async_load(&mut self,
|
||||
load: LoadType,
|
||||
referrer: &Document) -> PendingAsyncLoad {
|
||||
let context = load.to_load_context();
|
||||
let url = load.url().clone();
|
||||
self.add_blocking_load(load);
|
||||
let client_chan = referrer.window().custom_message_chan();
|
||||
PendingAsyncLoad::new(context,
|
||||
(*self.resource_thread).clone(),
|
||||
url,
|
||||
self.pipeline,
|
||||
referrer.get_referrer_policy(),
|
||||
Some(referrer.url().clone()))
|
||||
Some(referrer.url().clone()),
|
||||
RequestSource::Window(client_chan))
|
||||
}
|
||||
|
||||
/// Create and initiate a new network request.
|
||||
pub fn load_async(&mut self, load: LoadType, listener: AsyncResponseTarget, referrer: &Document) {
|
||||
pub fn load_async(&mut self,
|
||||
load: LoadType,
|
||||
listener: AsyncResponseTarget,
|
||||
referrer: &Document) {
|
||||
let pending = self.prepare_async_load(load, referrer);
|
||||
pending.load_async(listener)
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ use ipc_channel::ipc::IpcSender;
|
|||
use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
|
||||
use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
|
||||
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
|
||||
use msg::constellation_msg::{PanicMsg, PipelineId};
|
||||
use net_traits::CoreResourceThread;
|
||||
use msg::constellation_msg::{PipelineId, PanicMsg};
|
||||
use net_traits::{CoreResourceThread, RequestSource};
|
||||
use profile_traits::{mem, time};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_thread::{MainThreadScriptChan, ScriptThread};
|
||||
|
@ -65,6 +65,14 @@ impl<'a> GlobalRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// gets the custom message channel associated with global object
|
||||
pub fn request_source(&self) -> RequestSource {
|
||||
match *self {
|
||||
GlobalRef::Window(ref window) => RequestSource::Window(window.custom_message_chan()),
|
||||
GlobalRef::Worker(ref worker) => RequestSource::Worker(worker.custom_message_chan()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the `PipelineId` for this global scope.
|
||||
pub fn pipeline(&self) -> PipelineId {
|
||||
match *self {
|
||||
|
|
|
@ -16,7 +16,8 @@ use dom::bindings::refcounted::LiveDOMReferences;
|
|||
use dom::bindings::reflector::Reflectable;
|
||||
use dom::bindings::structuredclone::StructuredCloneData;
|
||||
use dom::messageevent::MessageEvent;
|
||||
use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress, WorkerMessageHandler};
|
||||
use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress};
|
||||
use dom::worker::{WorkerScriptLoadOrigin, WorkerMessageHandler};
|
||||
use dom::workerglobalscope::WorkerGlobalScope;
|
||||
use dom::workerglobalscope::WorkerGlobalScopeInit;
|
||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||
|
@ -26,7 +27,7 @@ use js::jsapi::{JSAutoCompartment, JSContext, RootedValue};
|
|||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::{LoadContext, load_whole_resource};
|
||||
use net_traits::{LoadContext, load_whole_resource, CustomResponse};
|
||||
use rand::random;
|
||||
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
||||
|
@ -133,6 +134,7 @@ enum MixedMessage {
|
|||
FromWorker((TrustedWorkerAddress, WorkerScriptMsg)),
|
||||
FromScheduler((TrustedWorkerAddress, TimerEvent)),
|
||||
FromDevtools(DevtoolScriptControlMsg),
|
||||
FromNetwork(IpcSender<Option<CustomResponse>>),
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dedicatedworkerglobalscope
|
||||
|
@ -215,18 +217,18 @@ impl DedicatedWorkerGlobalScope {
|
|||
worker: TrustedWorkerAddress,
|
||||
parent_sender: Box<ScriptChan + Send>,
|
||||
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
||||
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>) {
|
||||
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
||||
worker_load_origin: WorkerScriptLoadOrigin) {
|
||||
let serialized_worker_url = worker_url.to_string();
|
||||
let name = format!("WebWorker for {}", serialized_worker_url);
|
||||
let panic_chan = init.panic_chan.clone();
|
||||
spawn_named_with_send_on_panic(name, SCRIPT | IN_WORKER, move || {
|
||||
let roots = RootCollection::new();
|
||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||
|
||||
let (url, source) = match load_whole_resource(LoadContext::Script,
|
||||
&init.core_resource_thread,
|
||||
worker_url,
|
||||
None) {
|
||||
&worker_load_origin) {
|
||||
Err(_) => {
|
||||
println!("error loading script {}", serialized_worker_url);
|
||||
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
|
||||
|
@ -316,17 +318,20 @@ impl DedicatedWorkerGlobalScope {
|
|||
let worker_port = &self.receiver;
|
||||
let timer_event_port = &self.timer_event_port;
|
||||
let devtools_port = scope.from_devtools_receiver();
|
||||
let msg_port = scope.custom_message_port();
|
||||
|
||||
let sel = Select::new();
|
||||
let mut worker_handle = sel.handle(worker_port);
|
||||
let mut timer_event_handle = sel.handle(timer_event_port);
|
||||
let mut devtools_handle = sel.handle(devtools_port);
|
||||
let mut msg_port_handle = sel.handle(msg_port);
|
||||
unsafe {
|
||||
worker_handle.add();
|
||||
timer_event_handle.add();
|
||||
if scope.from_devtools_sender().is_some() {
|
||||
devtools_handle.add();
|
||||
}
|
||||
msg_port_handle.add();
|
||||
}
|
||||
let ret = sel.wait();
|
||||
if ret == worker_handle.id() {
|
||||
|
@ -335,6 +340,8 @@ impl DedicatedWorkerGlobalScope {
|
|||
Ok(MixedMessage::FromScheduler(try!(timer_event_port.recv())))
|
||||
} else if ret == devtools_handle.id() {
|
||||
Ok(MixedMessage::FromDevtools(try!(devtools_port.recv())))
|
||||
} else if ret == msg_port_handle.id() {
|
||||
Ok(MixedMessage::FromNetwork(try!(msg_port.recv())))
|
||||
} else {
|
||||
panic!("unexpected select result!")
|
||||
}
|
||||
|
@ -397,6 +404,10 @@ impl DedicatedWorkerGlobalScope {
|
|||
let _ar = AutoWorkerReset::new(self, linked_worker);
|
||||
self.handle_script_event(msg);
|
||||
},
|
||||
MixedMessage::FromNetwork(network_sender) => {
|
||||
// We send None as of now
|
||||
let _ = network_sender.send(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1354,7 +1354,7 @@ impl Document {
|
|||
|
||||
pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget) {
|
||||
let mut loader = self.loader.borrow_mut();
|
||||
loader.load_async(load, listener, self)
|
||||
loader.load_async(load, listener, self);
|
||||
}
|
||||
|
||||
pub fn finish_load(&self, load: LoadType) {
|
||||
|
|
|
@ -45,10 +45,10 @@ use libc;
|
|||
use msg::constellation_msg::{LoadData, PanicMsg, PipelineId, SubpageId};
|
||||
use msg::constellation_msg::{WindowSizeData, WindowSizeType};
|
||||
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
||||
use net_traits::ResourceThreads;
|
||||
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
|
||||
use net_traits::storage_thread::StorageType;
|
||||
use net_traits::{ResourceThreads, CustomResponseSender};
|
||||
use num_traits::ToPrimitive;
|
||||
use profile_traits::mem;
|
||||
use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
|
||||
|
@ -148,6 +148,8 @@ pub struct Window {
|
|||
image_cache_thread: ImageCacheThread,
|
||||
#[ignore_heap_size_of = "channels are hard"]
|
||||
image_cache_chan: ImageCacheChan,
|
||||
#[ignore_heap_size_of = "channels are hard"]
|
||||
custom_message_chan: IpcSender<CustomResponseSender>,
|
||||
#[ignore_heap_size_of = "TODO(#6911) newtypes containing unmeasurable types are hard"]
|
||||
compositor: IpcSender<ScriptToCompositorMsg>,
|
||||
browsing_context: MutNullableHeap<JS<BrowsingContext>>,
|
||||
|
@ -303,6 +305,10 @@ impl Window {
|
|||
self.image_cache_chan.clone()
|
||||
}
|
||||
|
||||
pub fn custom_message_chan(&self) -> IpcSender<CustomResponseSender> {
|
||||
self.custom_message_chan.clone()
|
||||
}
|
||||
|
||||
pub fn get_next_worker_id(&self) -> WorkerId {
|
||||
let worker_id = self.next_worker_id.get();
|
||||
let WorkerId(id_num) = worker_id;
|
||||
|
@ -1443,6 +1449,7 @@ impl Window {
|
|||
history_task_source: HistoryTraversalTaskSource,
|
||||
file_task_source: FileReadingTaskSource,
|
||||
image_cache_chan: ImageCacheChan,
|
||||
custom_message_chan: IpcSender<CustomResponseSender>,
|
||||
compositor: IpcSender<ScriptToCompositorMsg>,
|
||||
image_cache_thread: ImageCacheThread,
|
||||
resource_threads: ResourceThreads,
|
||||
|
@ -1480,6 +1487,7 @@ impl Window {
|
|||
history_traversal_task_source: history_task_source,
|
||||
file_reading_task_source: file_task_source,
|
||||
image_cache_chan: image_cache_chan,
|
||||
custom_message_chan: custom_message_chan,
|
||||
console: Default::default(),
|
||||
crypto: Default::default(),
|
||||
compositor: compositor,
|
||||
|
|
|
@ -24,10 +24,13 @@ use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
|
|||
use js::jsapi::{JSAutoCompartment, JS_RequestInterruptCallback};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||
use net_traits::{RequestSource, LoadOrigin};
|
||||
use script_thread::Runnable;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::mpsc::{Sender, channel};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use url::Url;
|
||||
use util::str::DOMString;
|
||||
|
||||
pub type TrustedWorkerAddress = Trusted<Worker>;
|
||||
|
@ -45,6 +48,29 @@ pub struct Worker {
|
|||
runtime: Arc<Mutex<Option<SharedRt>>>
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WorkerScriptLoadOrigin {
|
||||
referrer_url: Option<Url>,
|
||||
referrer_policy: Option<ReferrerPolicy>,
|
||||
request_source: RequestSource,
|
||||
pipeline_id: Option<PipelineId>
|
||||
}
|
||||
|
||||
impl LoadOrigin for WorkerScriptLoadOrigin {
|
||||
fn referrer_url(&self) -> Option<Url> {
|
||||
self.referrer_url.clone()
|
||||
}
|
||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||
self.referrer_policy.clone()
|
||||
}
|
||||
fn request_source(&self) -> RequestSource {
|
||||
self.request_source.clone()
|
||||
}
|
||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||
self.pipeline_id.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Worker {
|
||||
fn new_inherited(sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
||||
closing: Arc<AtomicBool>) -> Worker {
|
||||
|
@ -82,6 +108,13 @@ impl Worker {
|
|||
let worker_ref = Trusted::new(worker.r());
|
||||
let worker_id = global.get_next_worker_id();
|
||||
|
||||
let worker_load_origin = WorkerScriptLoadOrigin {
|
||||
referrer_url: None,
|
||||
referrer_policy: None,
|
||||
request_source: global.request_source(),
|
||||
pipeline_id: Some(global.pipeline())
|
||||
};
|
||||
|
||||
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
||||
let optional_sender = match global.devtools_chan() {
|
||||
Some(ref chan) => {
|
||||
|
@ -114,7 +147,7 @@ impl Worker {
|
|||
|
||||
DedicatedWorkerGlobalScope::run_worker_scope(
|
||||
init, worker_url, global.pipeline(), devtools_receiver, worker.runtime.clone(), worker_ref,
|
||||
global.script_chan(), sender, receiver);
|
||||
global.script_chan(), sender, receiver, worker_load_origin);
|
||||
|
||||
Ok(worker)
|
||||
}
|
||||
|
|
|
@ -17,12 +17,13 @@ use dom::eventtarget::EventTarget;
|
|||
use dom::window::{base64_atob, base64_btoa};
|
||||
use dom::workerlocation::WorkerLocation;
|
||||
use dom::workernavigator::WorkerNavigator;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use msg::constellation_msg::{PanicMsg, PipelineId};
|
||||
use net_traits::{LoadContext, CoreResourceThread, load_whole_resource};
|
||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy, PanicMsg};
|
||||
use net_traits::{LoadContext, CoreResourceThread, load_whole_resource, RequestSource, LoadOrigin, CustomResponseSender};
|
||||
use profile_traits::{mem, time};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_traits::ScriptMsg as ConstellationMsg;
|
||||
|
@ -101,6 +102,12 @@ pub struct WorkerGlobalScope {
|
|||
|
||||
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
||||
panic_chan: IpcSender<PanicMsg>,
|
||||
|
||||
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
||||
custom_msg_chan: IpcSender<CustomResponseSender>,
|
||||
|
||||
#[ignore_heap_size_of = "Defined in std"]
|
||||
custom_msg_port: Receiver<CustomResponseSender>,
|
||||
}
|
||||
|
||||
impl WorkerGlobalScope {
|
||||
|
@ -110,7 +117,8 @@ impl WorkerGlobalScope {
|
|||
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||
timer_event_chan: IpcSender<TimerEvent>)
|
||||
-> WorkerGlobalScope {
|
||||
|
||||
let (msg_chan, msg_port) = ipc::channel().unwrap();
|
||||
let custom_msg_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(msg_port);
|
||||
WorkerGlobalScope {
|
||||
eventtarget: EventTarget::new_inherited(),
|
||||
next_worker_id: Cell::new(WorkerId(0)),
|
||||
|
@ -133,6 +141,8 @@ impl WorkerGlobalScope {
|
|||
constellation_chan: init.constellation_chan,
|
||||
scheduler_chan: init.scheduler_chan,
|
||||
panic_chan: init.panic_chan,
|
||||
custom_msg_chan: msg_chan,
|
||||
custom_msg_port: custom_msg_port
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,6 +192,14 @@ impl WorkerGlobalScope {
|
|||
self.runtime.cx()
|
||||
}
|
||||
|
||||
pub fn custom_message_chan(&self) -> IpcSender<CustomResponseSender> {
|
||||
self.custom_msg_chan.clone()
|
||||
}
|
||||
|
||||
pub fn custom_message_port(&self) -> &Receiver<CustomResponseSender> {
|
||||
&self.custom_msg_port
|
||||
}
|
||||
|
||||
pub fn is_closing(&self) -> bool {
|
||||
self.closing.load(Ordering::SeqCst)
|
||||
}
|
||||
|
@ -210,6 +228,21 @@ impl WorkerGlobalScope {
|
|||
}
|
||||
}
|
||||
|
||||
impl LoadOrigin for WorkerGlobalScope {
|
||||
fn referrer_url(&self) -> Option<Url> {
|
||||
None
|
||||
}
|
||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||
None
|
||||
}
|
||||
fn request_source(&self) -> RequestSource {
|
||||
RequestSource::None
|
||||
}
|
||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||
Some(self.pipeline())
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
|
||||
fn Self_(&self) -> Root<WorkerGlobalScope> {
|
||||
|
@ -236,7 +269,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
|||
|
||||
let mut rval = RootedValue::new(self.runtime.cx(), UndefinedValue());
|
||||
for url in urls {
|
||||
let (url, source) = match load_whole_resource(LoadContext::Script, &self.core_resource_thread, url, None) {
|
||||
let (url, source) = match load_whole_resource(LoadContext::Script, &self.core_resource_thread, url, self) {
|
||||
Err(_) => return Err(Error::Network),
|
||||
Ok((metadata, bytes)) => {
|
||||
(metadata.final_url, String::from_utf8(bytes).unwrap())
|
||||
|
|
|
@ -44,9 +44,10 @@ use ipc_channel::router::ROUTER;
|
|||
use js::jsapi::JS_ClearPendingException;
|
||||
use js::jsapi::{JSContext, JS_ParseJSON, RootedValue};
|
||||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||
use net_traits::CoreResourceMsg::Load;
|
||||
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError};
|
||||
use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread};
|
||||
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError, RequestSource};
|
||||
use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread, LoadOrigin};
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use parse::html::{ParseContext, parse_html};
|
||||
use parse::xml::{self, parse_xml};
|
||||
|
@ -295,6 +296,26 @@ impl XMLHttpRequest {
|
|||
}
|
||||
}
|
||||
|
||||
impl LoadOrigin for XMLHttpRequest {
|
||||
fn referrer_url(&self) -> Option<Url> {
|
||||
None
|
||||
}
|
||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||
None
|
||||
}
|
||||
fn request_source(&self) -> RequestSource {
|
||||
if self.sync.get() {
|
||||
RequestSource::None
|
||||
} else {
|
||||
self.global().r().request_source()
|
||||
}
|
||||
}
|
||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||
let global = self.global();
|
||||
Some(global.r().pipeline())
|
||||
}
|
||||
}
|
||||
|
||||
impl XMLHttpRequestMethods for XMLHttpRequest {
|
||||
// https://xhr.spec.whatwg.org/#handler-xhr-onreadystatechange
|
||||
event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange);
|
||||
|
@ -572,14 +593,11 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
|
||||
// Step 5
|
||||
let global = self.global();
|
||||
let pipeline_id = global.r().pipeline();
|
||||
//TODO - set referrer_policy/referrer_url in load_data
|
||||
let mut load_data =
|
||||
LoadData::new(LoadContext::Browsing,
|
||||
self.request_url.borrow().clone().unwrap(),
|
||||
Some(pipeline_id),
|
||||
None,
|
||||
None);
|
||||
self);
|
||||
if load_data.url.origin().ne(&global.r().get_url().origin()) {
|
||||
load_data.credentials_flag = self.WithCredentials();
|
||||
}
|
||||
|
|
|
@ -65,8 +65,8 @@ use msg::webdriver_msg::WebDriverScriptCommand;
|
|||
use net_traits::LoadData as NetLoadData;
|
||||
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
|
||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata};
|
||||
use net_traits::{ResourceThreads, IpcSend};
|
||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata, ResourceThreads};
|
||||
use net_traits::{RequestSource, CustomResponse, CustomResponseSender, IpcSend};
|
||||
use network_listener::NetworkListener;
|
||||
use parse::ParserRoot;
|
||||
use parse::html::{ParseContext, parse_html};
|
||||
|
@ -205,6 +205,7 @@ enum MixedMessage {
|
|||
FromDevtools(DevtoolScriptControlMsg),
|
||||
FromImageCache(ImageCacheResult),
|
||||
FromScheduler(TimerEvent),
|
||||
FromNetwork(IpcSender<Option<CustomResponse>>),
|
||||
}
|
||||
|
||||
/// Messages used to control the script event loop
|
||||
|
@ -321,6 +322,12 @@ 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,
|
||||
|
@ -537,6 +544,9 @@ 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 =
|
||||
|
@ -559,6 +569,9 @@ 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()),
|
||||
|
@ -620,7 +633,8 @@ impl ScriptThread {
|
|||
|
||||
/// Handle incoming control messages.
|
||||
fn handle_msgs(&self) -> bool {
|
||||
use self::MixedMessage::{FromScript, FromConstellation, FromScheduler, FromDevtools, FromImageCache};
|
||||
use self::MixedMessage::{FromConstellation, FromDevtools, FromImageCache};
|
||||
use self::MixedMessage::{FromScheduler, FromScript, FromNetwork};
|
||||
|
||||
// Handle pending resize events.
|
||||
// Gather them first to avoid a double mut borrow on self.
|
||||
|
@ -654,6 +668,7 @@ 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();
|
||||
|
@ -662,6 +677,7 @@ impl ScriptThread {
|
|||
devtools_port.add();
|
||||
}
|
||||
image_cache_port.add();
|
||||
custom_message_port.add();
|
||||
}
|
||||
let ret = sel.wait();
|
||||
if ret == script_port.id() {
|
||||
|
@ -674,6 +690,8 @@ 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")
|
||||
}
|
||||
|
@ -736,7 +754,10 @@ 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(_) => break,
|
||||
Err(_) => match self.custom_message_port.try_recv() {
|
||||
Err(_) => break,
|
||||
Ok(ev) => event = FromNetwork(ev)
|
||||
},
|
||||
Ok(ev) => event = FromImageCache(ev),
|
||||
},
|
||||
Ok(ev) => event = FromDevtools(ev),
|
||||
|
@ -762,6 +783,7 @@ 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),
|
||||
|
@ -821,6 +843,7 @@ impl ScriptThread {
|
|||
}
|
||||
},
|
||||
MixedMessage::FromScheduler(_) => ScriptThreadEventCategory::TimerEvent,
|
||||
MixedMessage::FromNetwork(_) => ScriptThreadEventCategory::NetworkEvent
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -990,6 +1013,12 @@ 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 {
|
||||
|
@ -1439,6 +1468,7 @@ impl ScriptThread {
|
|||
HistoryTraversalTaskSource(history_sender.clone()),
|
||||
FileReadingTaskSource(file_sender.clone()),
|
||||
self.image_cache_channel.clone(),
|
||||
self.custom_message_chan.clone(),
|
||||
self.compositor.borrow_mut().clone(),
|
||||
self.image_cache_thread.clone(),
|
||||
self.resource_threads.clone(),
|
||||
|
@ -1907,6 +1937,7 @@ impl ScriptThread {
|
|||
credentials_flag: true,
|
||||
referrer_policy: load_data.referrer_policy,
|
||||
referrer_url: load_data.referrer_url,
|
||||
source: RequestSource::Window(self.custom_message_chan.clone())
|
||||
}, LoadConsumer::Listener(response_target), None)).unwrap();
|
||||
|
||||
self.incomplete_loads.borrow_mut().push(incomplete);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue