mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Allow windows to share browsing contexts.
This commit is contained in:
parent
fc67878edf
commit
403499a9d5
11 changed files with 168 additions and 108 deletions
|
@ -41,7 +41,7 @@ use dom::bindings::str::DOMString;
|
|||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::utils::WRAP_CALLBACKS;
|
||||
use dom::browsingcontext::BrowsingContext;
|
||||
use dom::document::{Document, DocumentSource, FocusType, IsHTMLDocument, TouchEventResult};
|
||||
use dom::document::{Document, DocumentSource, FocusType, HasBrowsingContext, IsHTMLDocument, TouchEventResult};
|
||||
use dom::element::Element;
|
||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use dom::globalscope::GlobalScope;
|
||||
|
@ -391,13 +391,15 @@ impl<'a> Iterator for DocumentsIter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
// ScriptThread instances are rooted on creation, so this is okay
|
||||
#[allow(unrooted_must_root)]
|
||||
pub struct ScriptThread {
|
||||
/// The documents for pipelines managed by this thread
|
||||
documents: DOMRefCell<Documents>,
|
||||
/// The browsing contexts known by this thread
|
||||
/// TODO: this map grows, but never shrinks. Issue #15258.
|
||||
browsing_contexts: DOMRefCell<HashMap<FrameId, JS<BrowsingContext>>>,
|
||||
/// A list of data pertaining to loads that have not yet received a network response
|
||||
incomplete_loads: DOMRefCell<Vec<InProgressLoad>>,
|
||||
/// A map to store service worker registrations for a given origin
|
||||
|
@ -651,6 +653,7 @@ impl ScriptThread {
|
|||
|
||||
ScriptThread {
|
||||
documents: DOMRefCell::new(Documents::new()),
|
||||
browsing_contexts: DOMRefCell::new(HashMap::new()),
|
||||
incomplete_loads: DOMRefCell::new(vec!()),
|
||||
registration_map: DOMRefCell::new(HashMap::new()),
|
||||
job_queue_map: Rc::new(JobQueue::new()),
|
||||
|
@ -1514,29 +1517,26 @@ impl ScriptThread {
|
|||
load.pipeline_id == id
|
||||
});
|
||||
|
||||
if let Some(idx) = idx {
|
||||
let chan = if let Some(idx) = idx {
|
||||
let load = self.incomplete_loads.borrow_mut().remove(idx);
|
||||
|
||||
// Tell the layout thread to begin shutting down, and wait until it
|
||||
// processed this message.
|
||||
let (response_chan, response_port) = channel();
|
||||
let chan = &load.layout_chan;
|
||||
if chan.send(message::Msg::PrepareToExit(response_chan)).is_ok() {
|
||||
debug!("shutting down layout for page {}", id);
|
||||
response_port.recv().unwrap();
|
||||
chan.send(message::Msg::ExitNow).ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(document) = self.documents.borrow_mut().remove(id) {
|
||||
shut_down_layout(document.window());
|
||||
load.layout_chan.clone()
|
||||
} else if let Some(document) = self.documents.borrow_mut().remove(id) {
|
||||
let window = document.window();
|
||||
if discard_bc == DiscardBrowsingContext::Yes {
|
||||
if let Some(context) = document.browsing_context() {
|
||||
context.discard();
|
||||
}
|
||||
window.browsing_context().discard();
|
||||
}
|
||||
let _ = self.constellation_chan.send(ConstellationMsg::PipelineExited(id));
|
||||
}
|
||||
window.clear_js_runtime();
|
||||
window.layout_chan().clone()
|
||||
} else {
|
||||
return warn!("Exiting nonexistant pipeline {}.", id);
|
||||
};
|
||||
|
||||
let (response_chan, response_port) = channel();
|
||||
chan.send(message::Msg::PrepareToExit(response_chan)).ok();
|
||||
debug!("shutting down layout for page {}", id);
|
||||
response_port.recv().unwrap();
|
||||
chan.send(message::Msg::ExitNow).ok();
|
||||
self.constellation_chan.send(ConstellationMsg::PipelineExited(id)).ok();
|
||||
|
||||
debug!("Exited pipeline {}.", id);
|
||||
}
|
||||
|
@ -1693,8 +1693,18 @@ impl ScriptThread {
|
|||
self.webvr_thread.clone());
|
||||
let frame_element = frame_element.r().map(Castable::upcast);
|
||||
|
||||
let browsing_context = BrowsingContext::new(&window, frame_element);
|
||||
window.init_browsing_context(&browsing_context);
|
||||
match self.browsing_contexts.borrow_mut().entry(incomplete.frame_id) {
|
||||
hash_map::Entry::Vacant(entry) => {
|
||||
let browsing_context = BrowsingContext::new(&window, frame_element);
|
||||
entry.insert(JS::from_ref(&*browsing_context));
|
||||
window.init_browsing_context(&browsing_context);
|
||||
},
|
||||
hash_map::Entry::Occupied(entry) => {
|
||||
let browsing_context = entry.get();
|
||||
browsing_context.set_window_proxy(&window);
|
||||
window.init_browsing_context(browsing_context);
|
||||
},
|
||||
}
|
||||
|
||||
let last_modified = metadata.headers.as_ref().and_then(|headers| {
|
||||
headers.get().map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm))
|
||||
|
@ -1735,7 +1745,7 @@ impl ScriptThread {
|
|||
.map(ReferrerPolicy::from);
|
||||
|
||||
let document = Document::new(&window,
|
||||
Some(&browsing_context),
|
||||
HasBrowsingContext::Yes,
|
||||
Some(final_url.clone()),
|
||||
incomplete.origin,
|
||||
is_html_document,
|
||||
|
@ -2139,29 +2149,6 @@ impl Drop for ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
/// Shuts down layout for the given window.
|
||||
fn shut_down_layout(window: &Window) {
|
||||
// Tell the layout thread to begin shutting down, and wait until it
|
||||
// processed this message.
|
||||
let (response_chan, response_port) = channel();
|
||||
let chan = window.layout_chan().clone();
|
||||
if chan.send(message::Msg::PrepareToExit(response_chan)).is_ok() {
|
||||
let _ = response_port.recv();
|
||||
}
|
||||
|
||||
// The browsing context is cleared by window.clear_js_runtime(), so we need to save a copy
|
||||
let browsing_context = window.browsing_context();
|
||||
|
||||
// Drop our references to the JSContext and DOM objects.
|
||||
window.clear_js_runtime();
|
||||
|
||||
// Discard the browsing context.
|
||||
browsing_context.discard();
|
||||
|
||||
// Destroy the layout thread. If there were node leaks, layout will now crash safely.
|
||||
chan.send(message::Msg::ExitNow).ok();
|
||||
}
|
||||
|
||||
fn dom_last_modified(tm: &Tm) -> String {
|
||||
tm.to_local().strftime("%m/%d/%Y %H:%M:%S").unwrap().to_string()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue