diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/body.rs | 33 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 35 | ||||
-rw-r--r-- | components/script/dom/bindings/global.rs | 15 | ||||
-rw-r--r-- | components/script/dom/browsingcontext.rs | 71 | ||||
-rw-r--r-- | components/script/dom/console.rs | 7 | ||||
-rw-r--r-- | components/script/dom/eventtarget.rs | 56 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 47 | ||||
-rw-r--r-- | components/script/dom/request.rs | 22 | ||||
-rw-r--r-- | components/script/dom/response.rs | 29 | ||||
-rw-r--r-- | components/script/dom/serviceworkerregistration.rs | 1 | ||||
-rw-r--r-- | components/script/fetch.rs | 13 | ||||
-rw-r--r-- | components/script/lib.rs | 3 | ||||
-rw-r--r-- | components/script/script_thread.rs | 11 | ||||
-rw-r--r-- | components/script/serviceworker_manager.rs | 2 |
14 files changed, 185 insertions, 160 deletions
diff --git a/components/script/body.rs b/components/script/body.rs index 814a62c30eb..276d6425d2f 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -24,8 +24,8 @@ use std::rc::Rc; use std::str; use url::form_urlencoded; +#[derive(Copy, Clone, JSTraceable, HeapSizeOf)] pub enum BodyType { - ArrayBuffer, Blob, FormData, Json, @@ -48,14 +48,32 @@ pub fn consume_body<T: BodyOperations + Reflectable>(object: &T, body_type: Body if object.get_body_used() || object.is_locked() { promise.reject_error(promise.global().r().get_cx(), Error::Type( "The response's stream is disturbed or locked".to_string())); + return promise; } + object.set_body_promise(&promise, body_type); + // Steps 2-4 // TODO: Body does not yet have a stream. + consume_body_with_promise(object, body_type, &promise); + + promise +} + +// https://fetch.spec.whatwg.org/#concept-body-consume-body +#[allow(unrooted_must_root)] +pub fn consume_body_with_promise<T: BodyOperations + Reflectable>(object: &T, + body_type: BodyType, + promise: &Promise) { // Step 5 + let body = match object.take_body() { + Some(body) => body, + None => return, + }; + let pkg_data_results = run_package_data_algorithm(object, - object.take_body(), + body, body_type, object.get_mime_type()); @@ -71,20 +89,15 @@ pub fn consume_body<T: BodyOperations + Reflectable>(object: &T, body_type: Body }, Err(err) => promise.reject_error(cx, err), } - promise } // https://fetch.spec.whatwg.org/#concept-body-package-data #[allow(unsafe_code)] fn run_package_data_algorithm<T: BodyOperations + Reflectable>(object: &T, - bytes: Option<Vec<u8>>, + bytes: Vec<u8>, body_type: BodyType, mime_type: Ref<Vec<u8>>) -> Fallible<FetchedData> { - let bytes = match bytes { - Some(b) => b, - _ => vec![], - }; let cx = object.global().r().get_cx(); let mime = &*mime_type; match body_type { @@ -92,7 +105,6 @@ fn run_package_data_algorithm<T: BodyOperations + Reflectable>(object: &T, BodyType::Json => run_json_data_algorithm(cx, bytes), BodyType::Blob => run_blob_data_algorithm(object.global().r(), bytes, mime), BodyType::FormData => run_form_data_algorithm(object.global().r(), bytes, mime), - _ => Err(Error::Type("Unable to process body type".to_string())) } } @@ -158,6 +170,9 @@ fn run_form_data_algorithm(root: GlobalRef, bytes: Vec<u8>, mime: &[u8]) -> Fall pub trait BodyOperations { fn get_body_used(&self) -> bool; + fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType); + /// Returns `Some(_)` if the body is complete, `None` if there is more to + /// come. fn take_body(&self) -> Option<Vec<u8>>; fn is_locked(&self) -> bool; fn get_mime_type(&self) -> Ref<Vec<u8>>; diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 7c6b2fe3718..4ea45ef9ded 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1984,15 +1984,15 @@ def DOMClassTypeId(desc): inner = "" if desc.hasDescendants(): if desc.interface.getExtendedAttribute("Abstract"): - return "::dom::bindings::codegen::InheritTypes::TopTypeId::Abstract" + return "::dom::bindings::codegen::InheritTypes::TopTypeId { abstract_: () }" name = desc.interface.identifier.name inner = "(::dom::bindings::codegen::InheritTypes::%sTypeId::%s)" % (name, name) elif len(protochain) == 1: - return "::dom::bindings::codegen::InheritTypes::TopTypeId::Alone" + return "::dom::bindings::codegen::InheritTypes::TopTypeId { alone: () }" reversed_protochain = list(reversed(protochain)) for (child, parent) in zip(reversed_protochain, reversed_protochain[1:]): inner = "(::dom::bindings::codegen::InheritTypes::%sTypeId::%s%s)" % (parent, child, inner) - return "::dom::bindings::codegen::InheritTypes::TopTypeId::%s%s" % (protochain[0], inner) + return "::dom::bindings::codegen::InheritTypes::TopTypeId { %s: %s }" % (protochain[0].lower(), inner) def DOMClass(descriptor): @@ -6931,18 +6931,26 @@ class GlobalGenRoots(): typeIdCode = [] topTypeVariants = [ - ("ID used by abstract interfaces.", "Abstract"), - ("ID used by interfaces that are not castable.", "Alone"), + ("ID used by abstract interfaces.", "pub abstract_: ()"), + ("ID used by interfaces that are not castable.", "pub alone: ()"), ] topTypeVariants += [ - ("ID used by interfaces that derive from %s." % typeName, "%s(%sTypeId)" % (typeName, typeName)) + ("ID used by interfaces that derive from %s." % typeName, + "pub %s: %sTypeId" % (typeName.lower(), typeName)) for typeName in topTypes ] topTypeVariantsAsStrings = [CGGeneric("/// %s\n%s," % variant) for variant in topTypeVariants] typeIdCode.append(CGWrapper(CGIndenter(CGList(topTypeVariantsAsStrings, "\n"), 4), - pre="#[derive(Clone, Copy, Debug)]\npub enum TopTypeId {\n", + pre="#[derive(Copy)]\npub union TopTypeId {\n", post="\n}\n\n")) + typeIdCode.append(CGGeneric("""\ +impl Clone for TopTypeId { + fn clone(&self) -> Self { *self } +} + +""")) + def type_id_variant(name): # If `name` is present in the hierarchy keys', that means some other interfaces # derive from it and this enum variant should have an argument with its own @@ -6962,17 +6970,16 @@ class GlobalGenRoots(): typeIdCode.append(CGGeneric("""\ impl %(base)s { pub fn type_id(&self) -> &'static %(base)sTypeId { - let domclass = unsafe { - get_dom_class(self.reflector().get_jsobject().get()).unwrap() - }; - match domclass.type_id { - TopTypeId::%(base)s(ref type_id) => type_id, - _ => unreachable!(), + unsafe { + &get_dom_class(self.reflector().get_jsobject().get()) + .unwrap() + .type_id + .%(field)s } } } -""" % {'base': base})) +""" % {'base': base, 'field': base.lower()})) curr = CGList(imports + typeIdCode + allprotos) curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 5d679cce2e9..e0341ceeb68 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -125,12 +125,7 @@ impl<'a> GlobalRef<'a> { /// Get the `ResourceThreads` for this global scope. pub fn resource_threads(&self) -> ResourceThreads { match *self { - GlobalRef::Window(ref window) => { - let doc = window.Document(); - let doc = doc.r(); - let loader = doc.loader(); - loader.resource_threads().clone() - } + GlobalRef::Window(ref window) => window.resource_threads().clone(), GlobalRef::Worker(ref worker) => worker.resource_threads().clone(), } } @@ -140,14 +135,6 @@ impl<'a> GlobalRef<'a> { self.resource_threads().sender() } - /// Get the worker's id. - pub fn get_worker_id(&self) -> Option<WorkerId> { - match *self { - GlobalRef::Window(_) => None, - GlobalRef::Worker(ref worker) => Some(worker.get_worker_id()), - } - } - /// Get next worker id. pub fn get_next_worker_id(&self) -> WorkerId { match *self { diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs index 36179279967..9f867157fab 100644 --- a/components/script/dom/browsingcontext.rs +++ b/components/script/dom/browsingcontext.rs @@ -3,12 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::cell::DOMRefCell; -use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; -use dom::bindings::js::{JS, Root, RootedReference}; +use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{Reflectable, MutReflectable, Reflector}; -use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::WindowProxyHandler; use dom::bindings::utils::get_array_index_from_id; @@ -28,9 +26,12 @@ use js::jsapi::{ObjectOpResult, PropertyDescriptor}; use js::jsval::{UndefinedValue, PrivateValue}; use msg::constellation_msg::PipelineId; use std::cell::Cell; -use url::Url; #[dom_struct] +// NOTE: the browsing context for a window is managed in two places: +// here, in script, but also in the constellation. The constellation +// manages the session history, which in script is accessed through +// History objects, messaging the constellation. pub struct BrowsingContext { reflector: Reflector, @@ -40,15 +41,15 @@ pub struct BrowsingContext { /// Indicates if reflow is required when reloading. needs_reflow: Cell<bool>, - /// Stores this context's session history - history: DOMRefCell<Vec<SessionHistoryEntry>>, - - /// The index of the active session history entry - active_index: Cell<usize>, - /// Stores the child browsing contexts (ex. iframe browsing context) children: DOMRefCell<Vec<JS<BrowsingContext>>>, + /// The current active document. + /// Note that the session history is stored in the constellation, + /// in the script thread we just track the current active document. + active_document: MutNullableHeap<JS<Document>>, + + /// The containing iframe element, if this is a same-origin iframe frame_element: Option<JS<Element>>, } @@ -58,9 +59,8 @@ impl BrowsingContext { reflector: Reflector::new(), id: id, needs_reflow: Cell::new(true), - history: DOMRefCell::new(vec![]), - active_index: Cell::new(0), children: DOMRefCell::new(vec![]), + active_document: Default::default(), frame_element: frame_element.map(JS::from_ref), } } @@ -90,29 +90,16 @@ impl BrowsingContext { } } - pub fn init(&self, document: &Document) { - assert!(self.history.borrow().is_empty()); - assert_eq!(self.active_index.get(), 0); - self.history.borrow_mut().push(SessionHistoryEntry::new(document, document.url().clone(), document.Title())); - } - - pub fn push_history(&self, document: &Document) { - let mut history = self.history.borrow_mut(); - // Clear all session history entries after the active index - history.drain((self.active_index.get() + 1)..); - history.push(SessionHistoryEntry::new(document, document.url().clone(), document.Title())); - self.active_index.set(self.active_index.get() + 1); - assert_eq!(self.active_index.get(), history.len() - 1); + pub fn set_active_document(&self, document: &Document) { + self.active_document.set(Some(document)) } pub fn active_document(&self) -> Root<Document> { - Root::from_ref(&self.history.borrow()[self.active_index.get()].document) + self.active_document.get().expect("No active document.") } pub fn maybe_active_document(&self) -> Option<Root<Document>> { - self.history.borrow().get(self.active_index.get()).map(|entry| { - Root::from_ref(&*entry.document) - }) + self.active_document.get() } pub fn active_window(&self) -> Root<Window> { @@ -167,9 +154,8 @@ impl BrowsingContext { }).map(|context| context.active_window()) } - pub fn clear_session_history(&self) { - self.active_index.set(0); - self.history.borrow_mut().clear(); + pub fn unset_active_document(&self) { + self.active_document.set(None) } pub fn iter(&self) -> ContextIterator { @@ -208,27 +194,6 @@ impl Iterator for ContextIterator { } } -// This isn't a DOM struct, just a convenience struct -// without a reflector, so we don't mark this as #[dom_struct] -#[must_root] -#[privatize] -#[derive(JSTraceable, HeapSizeOf)] -pub struct SessionHistoryEntry { - document: JS<Document>, - url: Url, - title: DOMString, -} - -impl SessionHistoryEntry { - fn new(document: &Document, url: Url, title: DOMString) -> SessionHistoryEntry { - SessionHistoryEntry { - document: JS::from_ref(document), - url: url, - title: title, - } - } -} - #[allow(unsafe_code)] unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: HandleObject, diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs index 05bd5e558b8..ad28c585248 100644 --- a/components/script/dom/console.rs +++ b/components/script/dom/console.rs @@ -17,10 +17,15 @@ impl Console { fn send_to_devtools(global: GlobalRef, level: LogLevel, message: DOMString) { if let Some(chan) = global.devtools_chan() { let console_message = prepare_message(level, message); + let worker_id = if let GlobalRef::Worker(worker) = global { + Some(worker.get_worker_id()) + } else { + None + }; let devtools_message = ScriptToDevtoolsControlMsg::ConsoleAPI( global.pipeline_id(), console_message, - global.get_worker_id()); + worker_id); chan.send(devtools_message).unwrap(); } } diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 1d3efd59b19..9bdaac20288 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -515,21 +515,23 @@ impl EventTargetMethods for EventTarget { ty: DOMString, listener: Option<Rc<EventListener>>, capture: bool) { - if let Some(listener) = listener { - let mut handlers = self.handlers.borrow_mut(); - let entry = match handlers.entry(Atom::from(ty)) { - Occupied(entry) => entry.into_mut(), - Vacant(entry) => entry.insert(EventListeners(vec!())), - }; + let listener = match listener { + Some(l) => l, + None => return, + }; + let mut handlers = self.handlers.borrow_mut(); + let entry = match handlers.entry(Atom::from(ty)) { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.insert(EventListeners(vec!())), + }; - let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; - let new_entry = EventListenerEntry { - phase: phase, - listener: EventListenerType::Additive(listener) - }; - if !entry.contains(&new_entry) { - entry.push(new_entry); - } + let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; + let new_entry = EventListenerEntry { + phase: phase, + listener: EventListenerType::Additive(listener) + }; + if !entry.contains(&new_entry) { + entry.push(new_entry); } } @@ -538,18 +540,20 @@ impl EventTargetMethods for EventTarget { ty: DOMString, listener: Option<Rc<EventListener>>, capture: bool) { - if let Some(ref listener) = listener { - let mut handlers = self.handlers.borrow_mut(); - let entry = handlers.get_mut(&Atom::from(ty)); - for entry in entry { - let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; - let old_entry = EventListenerEntry { - phase: phase, - listener: EventListenerType::Additive(listener.clone()) - }; - if let Some(position) = entry.iter().position(|e| *e == old_entry) { - entry.remove(position); - } + let ref listener = match listener { + Some(l) => l, + None => return, + }; + let mut handlers = self.handlers.borrow_mut(); + let entry = handlers.get_mut(&Atom::from(ty)); + for entry in entry { + let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; + let old_entry = EventListenerEntry { + phase: phase, + listener: EventListenerType::Additive(listener.clone()) + }; + if let Some(position) = entry.iter().position(|e| *e == old_entry) { + entry.remove(position); } } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 74e21ac9668..b02aa0ad6a7 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -12,6 +12,7 @@ use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMet use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::bindings::refcounted::Trusted; +use dom::bindings::reflector::Reflectable; use dom::bindings::str::DOMString; use dom::document::Document; use dom::domtokenlist::DOMTokenList; @@ -28,7 +29,8 @@ use hyper_serde::Serde; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use msg::constellation_msg::ReferrerPolicy; -use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError}; +use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError}; +use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use script_layout_interface::message::Msg; use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg}; @@ -244,11 +246,8 @@ impl HTMLLinkElement { script_chan: document.window().networking_task_source(), wrapper: Some(document.window().get_runnable_wrapper()), }; - let response_target = AsyncResponseTarget { - sender: action_sender, - }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify_action(message.to().unwrap()); + listener.notify_fetch(message.to().unwrap()); }); if self.parser_inserted.get() { @@ -257,10 +256,23 @@ impl HTMLLinkElement { let referrer_policy = match self.RelList().Contains("noreferrer".into()) { true => Some(ReferrerPolicy::NoReferrer), - false => None, + false => document.get_referrer_policy(), + }; + + let request = RequestInit { + url: url.clone(), + type_: RequestType::Style, + destination: Destination::Style, + credentials_mode: CredentialsMode::Include, + use_url_credentials: true, + origin: document.url().clone(), + pipeline_id: Some(self.global().r().pipeline_id()), + referrer_url: Some(document.url().clone()), + referrer_policy: referrer_policy, + .. RequestInit::default() }; - document.load_async(LoadType::Stylesheet(url), response_target, referrer_policy); + document.fetch_async(LoadType::Stylesheet(url), request, action_sender); } fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) { @@ -296,9 +308,19 @@ struct StylesheetContext { impl PreInvoke for StylesheetContext {} -impl AsyncResponseListener for StylesheetContext { - fn headers_available(&mut self, metadata: Result<Metadata, NetworkError>) { - self.metadata = metadata.ok(); +impl FetchResponseListener for StylesheetContext { + fn process_request_body(&mut self) {} + + fn process_request_eof(&mut self) {} + + fn process_response(&mut self, + metadata: Result<FetchMetadata, NetworkError>) { + self.metadata = metadata.ok().map(|m| { + match m { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { unsafe_, .. } => unsafe_ + } + }); if let Some(ref meta) = self.metadata { if let Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Css, _)))) = meta.content_type { } else { @@ -307,12 +329,11 @@ impl AsyncResponseListener for StylesheetContext { } } - fn data_available(&mut self, payload: Vec<u8>) { - let mut payload = payload; + fn process_response_chunk(&mut self, mut payload: Vec<u8>) { self.data.append(&mut payload); } - fn response_complete(&mut self, status: Result<(), NetworkError>) { + fn process_response_eof(&mut self, status: Result<(), NetworkError>) { let elem = self.elem.root(); let document = document_from_node(&*elem); let mut successful = false; diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index ebfe0abf49e..fa665679c0d 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -36,7 +36,6 @@ use net_traits::request::Request as NetTraitsRequest; use net_traits::request::RequestMode as NetTraitsRequestMode; use net_traits::request::Type as NetTraitsRequestType; use std::cell::{Cell, Ref}; -use std::mem; use std::rc::Rc; use url::Url; @@ -47,6 +46,8 @@ pub struct Request { body_used: Cell<bool>, headers: MutNullableHeap<JS<Headers>>, mime_type: DOMRefCell<Vec<u8>>, + #[ignore_heap_size_of = "Rc"] + body_promise: DOMRefCell<Option<(Rc<Promise>, BodyType)>>, } impl Request { @@ -62,6 +63,7 @@ impl Request { body_used: Cell::new(false), headers: Default::default(), mime_type: DOMRefCell::new("".to_string().into_bytes()), + body_promise: DOMRefCell::new(None), } } @@ -662,20 +664,20 @@ impl BodyOperations for Request { self.BodyUsed() } + fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType) { + assert!(self.body_promise.borrow().is_none()); + self.body_used.set(true); + *self.body_promise.borrow_mut() = Some((p.clone(), body_type)); + } + fn is_locked(&self) -> bool { self.locked() } fn take_body(&self) -> Option<Vec<u8>> { - let ref mut net_traits_req = *self.request.borrow_mut(); - let body: Option<Vec<u8>> = mem::replace(&mut *net_traits_req.body.borrow_mut(), None); - match body { - Some(_) => { - self.body_used.set(true); - body - }, - _ => None, - } + let request = self.request.borrow_mut(); + let body = request.body.borrow_mut().take(); + Some(body.unwrap_or(vec![])) } fn get_mime_type(&self) -> Ref<Vec<u8>> { diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index 66a7e84f112..2287bb181b4 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use body::{BodyOperations, BodyType, consume_body}; +use body::{BodyOperations, BodyType, consume_body, consume_body_with_promise}; use core::cell::Cell; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::HeadersBinding::HeadersMethods; @@ -44,6 +44,8 @@ pub struct Response { url_list: DOMRefCell<Vec<Url>>, // For now use the existing NetTraitsResponseBody enum body: DOMRefCell<NetTraitsResponseBody>, + #[ignore_heap_size_of = "Rc"] + body_promise: DOMRefCell<Option<(Rc<Promise>, BodyType)>>, } impl Response { @@ -59,6 +61,7 @@ impl Response { url: DOMRefCell::new(None), url_list: DOMRefCell::new(vec![]), body: DOMRefCell::new(NetTraitsResponseBody::Empty), + body_promise: DOMRefCell::new(None), } } @@ -194,18 +197,26 @@ impl BodyOperations for Response { self.BodyUsed() } + fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType) { + assert!(self.body_promise.borrow().is_none()); + self.body_used.set(true); + *self.body_promise.borrow_mut() = Some((p.clone(), body_type)); + } + fn is_locked(&self) -> bool { self.locked() } fn take_body(&self) -> Option<Vec<u8>> { - let body: NetTraitsResponseBody = mem::replace(&mut *self.body.borrow_mut(), NetTraitsResponseBody::Empty); + let body = mem::replace(&mut *self.body.borrow_mut(), NetTraitsResponseBody::Empty); match body { - NetTraitsResponseBody::Done(bytes) | NetTraitsResponseBody::Receiving(bytes) => { - self.body_used.set(true); + NetTraitsResponseBody::Done(bytes) => { Some(bytes) }, - _ => None, + body => { + mem::replace(&mut *self.body.borrow_mut(), body); + None + }, } } @@ -366,4 +377,12 @@ impl Response { pub fn set_final_url(&self, final_url: Url) { *self.url.borrow_mut() = Some(final_url); } + + #[allow(unrooted_must_root)] + pub fn finish(&self, body: Vec<u8>) { + *self.body.borrow_mut() = NetTraitsResponseBody::Done(body); + if let Some((p, body_type)) = self.body_promise.borrow_mut().take() { + consume_body_with_promise(self, body_type, &p); + } + } } diff --git a/components/script/dom/serviceworkerregistration.rs b/components/script/dom/serviceworkerregistration.rs index 6daec5d9647..f7c47b8ecec 100644 --- a/components/script/dom/serviceworkerregistration.rs +++ b/components/script/dom/serviceworkerregistration.rs @@ -60,7 +60,6 @@ impl ServiceWorkerRegistration { let init = prepare_workerscope_init(global, None); ScopeThings { script_url: script_url, - pipeline_id: global.pipeline_id(), init: init, worker_load_origin: worker_load_origin, devtools_chan: global.devtools_chan(), diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 0fc0fef1f89..634439c7c7d 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -24,6 +24,7 @@ use net_traits::CoreResourceMsg::Fetch as NetTraitsFetch; use net_traits::request::Request as NetTraitsRequest; use net_traits::request::RequestInit as NetTraitsRequestInit; use network_listener::{NetworkListener, PreInvoke}; +use std::mem; use std::rc::Rc; use std::sync::{Arc, Mutex}; use url::Url; @@ -31,6 +32,7 @@ use url::Url; struct FetchContext { fetch_promise: Option<TrustedPromise>, response_object: Trusted<Response>, + body: Vec<u8>, } fn from_referrer_to_referrer_url(request: &NetTraitsRequest) -> Option<Url> { @@ -89,6 +91,7 @@ pub fn Fetch(global: GlobalRef, input: RequestOrUSVString, init: &RequestInit) - let fetch_context = Arc::new(Mutex::new(FetchContext { fetch_promise: Some(TrustedPromise::new(promise.clone())), response_object: Trusted::new(&*response), + body: vec![], })); let listener = NetworkListener { context: fetch_context, @@ -154,11 +157,15 @@ impl FetchResponseListener for FetchContext { } fn process_response_chunk(&mut self, mut chunk: Vec<u8>) { - // TODO when body is implemented - // ... this will append the chunk to Response's body. + self.body.append(&mut chunk); } - fn process_response_eof(&mut self, response: Result<(), NetworkError>) { + fn process_response_eof(&mut self, _response: Result<(), NetworkError>) { + let response = self.response_object.root(); + let global = response.global(); + let cx = global.r().get_cx(); + let _ac = JSAutoCompartment::new(cx, global.r().reflector().get_jsobject().get()); + response.finish(mem::replace(&mut self.body, vec![])); // TODO // ... trailerObject is not supported in Servo yet. } diff --git a/components/script/lib.rs b/components/script/lib.rs index a7c73205d2f..7e4c9c78ab1 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -14,11 +14,12 @@ #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] #![feature(plugin)] +#![feature(question_mark)] #![feature(slice_patterns)] #![feature(stmt_expr_attributes)] -#![feature(question_mark)] #![feature(try_borrow)] #![feature(try_from)] +#![feature(untagged_unions)] #![deny(unsafe_code)] #![allow(non_snake_case)] diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 282fd90a08b..61ecacda815 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1655,8 +1655,6 @@ impl ScriptThread { } } - let mut using_new_context = true; - let (browsing_context, context_to_remove) = if !self.root_browsing_context_exists() { // Create a new context tree entry. This will become the root context. let new_context = BrowsingContext::new(&window, frame_element, incomplete.pipeline_id); @@ -1675,7 +1673,6 @@ impl ScriptThread { parent_context.push_child_context(&*new_context); (new_context, ContextToRemove::Child(incomplete.pipeline_id)) } else { - using_new_context = false; (self.root_browsing_context(), ContextToRemove::None) }; @@ -1741,11 +1738,7 @@ impl ScriptThread { loader, referrer, referrer_policy); - if using_new_context { - browsing_context.init(&document); - } else { - browsing_context.push_history(&document); - } + browsing_context.set_active_document(&document); document.set_ready_state(DocumentReadyState::Loading); self.constellation_chan @@ -2238,7 +2231,7 @@ fn shut_down_layout(context_tree: &BrowsingContext) { window.clear_js_runtime(); // Sever the connection between the global and the DOM tree - context.clear_session_history(); + context.unset_active_document(); } // Destroy the layout thread. If there were node leaks, layout will now crash safely. diff --git a/components/script/serviceworker_manager.rs b/components/script/serviceworker_manager.rs index 3ce26a7693e..3920b0cd62b 100644 --- a/components/script/serviceworker_manager.rs +++ b/components/script/serviceworker_manager.rs @@ -87,7 +87,7 @@ impl ServiceWorkerManager { title: title, url: scope_things.script_url.clone(), }; - let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal((scope_things.pipeline_id, + let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal((scope_things.init.pipeline_id, Some(scope_things.worker_id)), devtools_sender, page_info)); |