mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Auto merge of #9603 - Ms2ger:document-bc, r=jdm
Store a pointer to the browsing context in the Document. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9603) <!-- Reviewable:end -->
This commit is contained in:
commit
ee158cc65f
10 changed files with 53 additions and 23 deletions
|
@ -2,6 +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 dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject};
|
||||
use dom::bindings::js::{JS, Root, RootedReference};
|
||||
use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor};
|
||||
|
@ -25,26 +26,24 @@ use js::jsval::{ObjectValue, UndefinedValue, PrivateValue};
|
|||
#[dom_struct]
|
||||
pub struct BrowsingContext {
|
||||
reflector: Reflector,
|
||||
history: Vec<SessionHistoryEntry>,
|
||||
history: DOMRefCell<Vec<SessionHistoryEntry>>,
|
||||
active_index: usize,
|
||||
frame_element: Option<JS<Element>>,
|
||||
}
|
||||
|
||||
impl BrowsingContext {
|
||||
pub fn new_inherited(document: &Document, frame_element: Option<&Element>) -> BrowsingContext {
|
||||
pub fn new_inherited(frame_element: Option<&Element>) -> BrowsingContext {
|
||||
BrowsingContext {
|
||||
reflector: Reflector::new(),
|
||||
history: vec![SessionHistoryEntry::new(document)],
|
||||
history: DOMRefCell::new(vec![]),
|
||||
active_index: 0,
|
||||
frame_element: frame_element.map(JS::from_ref),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn new(document: &Document, frame_element: Option<&Element>) -> Root<BrowsingContext> {
|
||||
pub fn new(window: &Window, frame_element: Option<&Element>) -> Root<BrowsingContext> {
|
||||
unsafe {
|
||||
let window = document.window();
|
||||
|
||||
let WindowProxyHandler(handler) = window.windowproxy_handler();
|
||||
assert!(!handler.is_null());
|
||||
|
||||
|
@ -58,7 +57,7 @@ impl BrowsingContext {
|
|||
NewWindowProxy(cx, parent, handler));
|
||||
assert!(!window_proxy.ptr.is_null());
|
||||
|
||||
let object = box BrowsingContext::new_inherited(document, frame_element);
|
||||
let object = box BrowsingContext::new_inherited(frame_element);
|
||||
|
||||
let raw = Box::into_raw(object);
|
||||
SetProxyExtra(window_proxy.ptr, 0, PrivateValue(raw as *const _));
|
||||
|
@ -69,12 +68,18 @@ impl BrowsingContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn active_document(&self) -> &Document {
|
||||
&*self.history[self.active_index].document
|
||||
pub fn init(&self, document: &Document) {
|
||||
assert!(self.history.borrow().is_empty());
|
||||
assert_eq!(self.active_index, 0);
|
||||
self.history.borrow_mut().push(SessionHistoryEntry::new(document));
|
||||
}
|
||||
|
||||
pub fn active_window(&self) -> &Window {
|
||||
self.active_document().window()
|
||||
pub fn active_document(&self) -> Root<Document> {
|
||||
Root::from_ref(&*self.history.borrow()[self.active_index].document)
|
||||
}
|
||||
|
||||
pub fn active_window(&self) -> Root<Window> {
|
||||
Root::from_ref(self.active_document().window())
|
||||
}
|
||||
|
||||
pub fn frame_element(&self) -> Option<&Element> {
|
||||
|
|
|
@ -30,6 +30,7 @@ use dom::bindings::reflector::{Reflectable, reflect_dom_object};
|
|||
use dom::bindings::trace::RootedVec;
|
||||
use dom::bindings::xmlname::XMLName::InvalidXMLName;
|
||||
use dom::bindings::xmlname::{validate_and_extract, namespace_from_domstring, xml_name_type};
|
||||
use dom::browsingcontext::BrowsingContext;
|
||||
use dom::comment::Comment;
|
||||
use dom::customevent::CustomEvent;
|
||||
use dom::documentfragment::DocumentFragment;
|
||||
|
@ -129,6 +130,8 @@ enum ParserBlockedByScript {
|
|||
pub struct Document {
|
||||
node: Node,
|
||||
window: JS<Window>,
|
||||
/// https://html.spec.whatwg.org/multipage/#concept-document-bc
|
||||
browsing_context: Option<JS<BrowsingContext>>,
|
||||
implementation: MutNullableHeap<JS<DOMImplementation>>,
|
||||
location: MutNullableHeap<JS<Location>>,
|
||||
content_type: DOMString,
|
||||
|
@ -279,6 +282,12 @@ impl Document {
|
|||
self.loader.borrow_mut()
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#concept-document-bc
|
||||
#[inline]
|
||||
pub fn browsing_context(&self) -> Option<&BrowsingContext> {
|
||||
self.browsing_context.as_ref().map(|browsing_context| &**browsing_context)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn window(&self) -> &Window {
|
||||
&*self.window
|
||||
|
@ -309,7 +318,7 @@ impl Document {
|
|||
let browsing_context = browsing_context.as_ref().unwrap();
|
||||
let active_document = browsing_context.active_document();
|
||||
|
||||
if self != active_document {
|
||||
if self != &*active_document {
|
||||
return false;
|
||||
}
|
||||
// FIXME: It should also check whether the browser context is top-level or not
|
||||
|
@ -1507,6 +1516,7 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
|
|||
|
||||
impl Document {
|
||||
pub fn new_inherited(window: &Window,
|
||||
browsing_context: Option<&BrowsingContext>,
|
||||
url: Option<Url>,
|
||||
is_html_document: IsHTMLDocument,
|
||||
content_type: Option<DOMString>,
|
||||
|
@ -1525,6 +1535,7 @@ impl Document {
|
|||
Document {
|
||||
node: Node::new_document_node(),
|
||||
window: JS::from_ref(window),
|
||||
browsing_context: browsing_context.map(JS::from_ref),
|
||||
implementation: Default::default(),
|
||||
location: Default::default(),
|
||||
content_type: match content_type {
|
||||
|
@ -1593,6 +1604,7 @@ impl Document {
|
|||
let doc = doc.r();
|
||||
let docloader = DocumentLoader::new(&*doc.loader());
|
||||
Ok(Document::new(win,
|
||||
None,
|
||||
None,
|
||||
IsHTMLDocument::NonHTMLDocument,
|
||||
None,
|
||||
|
@ -1602,6 +1614,7 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn new(window: &Window,
|
||||
browsing_context: Option<&BrowsingContext>,
|
||||
url: Option<Url>,
|
||||
doctype: IsHTMLDocument,
|
||||
content_type: Option<DOMString>,
|
||||
|
@ -1610,6 +1623,7 @@ impl Document {
|
|||
doc_loader: DocumentLoader)
|
||||
-> Root<Document> {
|
||||
let document = reflect_dom_object(box Document::new_inherited(window,
|
||||
browsing_context,
|
||||
url,
|
||||
doctype,
|
||||
content_type,
|
||||
|
@ -1672,6 +1686,7 @@ impl Document {
|
|||
IsHTMLDocument::NonHTMLDocument
|
||||
};
|
||||
let new_doc = Document::new(self.window(),
|
||||
None,
|
||||
None,
|
||||
doctype,
|
||||
None,
|
||||
|
@ -1761,7 +1776,7 @@ impl DocumentMethods for Document {
|
|||
// Step 2.
|
||||
let candidate = browsing_context.active_document();
|
||||
// Step 3.
|
||||
if candidate == target {
|
||||
if &*candidate == target {
|
||||
true
|
||||
} else {
|
||||
false //TODO Step 4.
|
||||
|
|
|
@ -115,6 +115,7 @@ impl DOMImplementationMethods for DOMImplementation {
|
|||
|
||||
// Step 1-2.
|
||||
let doc = Document::new(win,
|
||||
None,
|
||||
None,
|
||||
IsHTMLDocument::HTMLDocument,
|
||||
None,
|
||||
|
|
|
@ -59,6 +59,7 @@ impl DOMParserMethods for DOMParser {
|
|||
match ty {
|
||||
Text_html => {
|
||||
let document = Document::new(&self.window,
|
||||
None,
|
||||
Some(url.clone()),
|
||||
IsHTMLDocument::HTMLDocument,
|
||||
Some(content_type),
|
||||
|
@ -72,6 +73,7 @@ impl DOMParserMethods for DOMParser {
|
|||
Text_xml => {
|
||||
// FIXME: this should probably be FromParser when we actually parse the string (#3756).
|
||||
let document = Document::new(&self.window,
|
||||
None,
|
||||
Some(url.clone()),
|
||||
IsHTMLDocument::NonHTMLDocument,
|
||||
Some(content_type),
|
||||
|
|
|
@ -1605,7 +1605,8 @@ impl Node {
|
|||
};
|
||||
let window = document.window();
|
||||
let loader = DocumentLoader::new(&*document.loader());
|
||||
let document = Document::new(window, Some((*document.url()).clone()),
|
||||
let document = Document::new(window, None,
|
||||
Some((*document.url()).clone()),
|
||||
is_html_doc, None,
|
||||
None, DocumentSource::NotFromParser, loader);
|
||||
Root::upcast::<Node>(document)
|
||||
|
|
|
@ -426,7 +426,7 @@ impl WindowMethods for Window {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-document-2
|
||||
fn Document(&self) -> Root<Document> {
|
||||
Root::from_ref(self.browsing_context().as_ref().unwrap().active_document())
|
||||
self.browsing_context().as_ref().unwrap().active_document()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-location
|
||||
|
@ -1095,8 +1095,9 @@ impl Window {
|
|||
(element, response.rect)
|
||||
}
|
||||
|
||||
pub fn init_browsing_context(&self, doc: &Document, frame_element: Option<&Element>) {
|
||||
self.browsing_context.set(Some(&BrowsingContext::new(doc, frame_element)));
|
||||
pub fn init_browsing_context(&self, browsing_context: &BrowsingContext) {
|
||||
assert!(self.browsing_context.get().is_none());
|
||||
self.browsing_context.set(Some(&browsing_context));
|
||||
}
|
||||
|
||||
/// Commence a new URL load which will either replace this window or scroll to a fragment.
|
||||
|
@ -1283,7 +1284,7 @@ impl Window {
|
|||
browsing_context.frame_element().map(|frame_element| {
|
||||
let window = window_from_node(frame_element);
|
||||
let context = window.browsing_context();
|
||||
Root::from_ref(context.unwrap().active_window())
|
||||
context.unwrap().active_window()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ impl XMLDocument {
|
|||
doc_loader: DocumentLoader) -> XMLDocument {
|
||||
XMLDocument {
|
||||
document: Document::new_inherited(window,
|
||||
None,
|
||||
url,
|
||||
is_html_document,
|
||||
content_type,
|
||||
|
|
|
@ -1230,6 +1230,7 @@ impl XMLHttpRequest {
|
|||
DOMString::from(format!("{}", mime))
|
||||
});
|
||||
Document::new(win,
|
||||
None,
|
||||
parsed_url,
|
||||
is_html_document,
|
||||
content_type,
|
||||
|
|
|
@ -275,7 +275,7 @@ pub fn parse_html_fragment(context_node: &Node,
|
|||
|
||||
// Step 1.
|
||||
let loader = DocumentLoader::new(&*context_document.loader());
|
||||
let document = Document::new(window.r(), Some(url.clone()),
|
||||
let document = Document::new(window.r(), None, Some(url.clone()),
|
||||
IsHTMLDocument::HTMLDocument,
|
||||
None, None,
|
||||
DocumentSource::FromParser,
|
||||
|
|
|
@ -32,6 +32,7 @@ use dom::bindings::js::{RootCollectionPtr, RootedReference};
|
|||
use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference, trace_refcounted_objects};
|
||||
use dom::bindings::trace::{JSTraceable, RootedVec, trace_traceables};
|
||||
use dom::bindings::utils::{DOM_CALLBACKS, WRAP_CALLBACKS};
|
||||
use dom::browsingcontext::BrowsingContext;
|
||||
use dom::document::{Document, DocumentProgressHandler, DocumentSource, FocusType, IsHTMLDocument};
|
||||
use dom::element::Element;
|
||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||
|
@ -1795,6 +1796,10 @@ impl ScriptThread {
|
|||
incomplete.parent_info,
|
||||
incomplete.window_size);
|
||||
|
||||
let frame_element = frame_element.r().map(Castable::upcast);
|
||||
let browsing_context = BrowsingContext::new(&window, frame_element);
|
||||
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))
|
||||
});
|
||||
|
@ -1822,16 +1827,14 @@ impl ScriptThread {
|
|||
};
|
||||
|
||||
let document = Document::new(window.r(),
|
||||
Some(&browsing_context),
|
||||
Some(final_url.clone()),
|
||||
is_html_document,
|
||||
content_type,
|
||||
last_modified,
|
||||
DocumentSource::FromParser,
|
||||
loader);
|
||||
|
||||
let frame_element = frame_element.r().map(Castable::upcast);
|
||||
window.init_browsing_context(document.r(), frame_element);
|
||||
|
||||
browsing_context.init(&document);
|
||||
document.set_ready_state(DocumentReadyState::Loading);
|
||||
|
||||
// Create the root frame
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue