aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/body.rs33
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py35
-rw-r--r--components/script/dom/bindings/global.rs15
-rw-r--r--components/script/dom/browsingcontext.rs71
-rw-r--r--components/script/dom/console.rs7
-rw-r--r--components/script/dom/eventtarget.rs56
-rw-r--r--components/script/dom/htmllinkelement.rs47
-rw-r--r--components/script/dom/request.rs22
-rw-r--r--components/script/dom/response.rs29
-rw-r--r--components/script/dom/serviceworkerregistration.rs1
-rw-r--r--components/script/fetch.rs13
-rw-r--r--components/script/lib.rs3
-rw-r--r--components/script/script_thread.rs11
-rw-r--r--components/script/serviceworker_manager.rs2
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));