Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store a pointer to the browsing context in the Document. #9603

Merged
merged 1 commit into from Feb 19, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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};
use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor};
@@ -26,26 +27,24 @@ use std::ptr;
#[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());

@@ -59,7 +58,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 _));
@@ -70,12 +69,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_document(&self) -> Root<Document> {
Root::from_ref(&*self.history.borrow()[self.active_index].document)
}

pub fn active_window(&self) -> &Window {
self.active_document().window()
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;
@@ -127,6 +128,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,
@@ -277,6 +280,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
@@ -307,7 +316,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
@@ -1462,6 +1471,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>,
@@ -1480,6 +1490,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 {
@@ -1548,6 +1559,7 @@ impl Document {
let doc = doc.r();
let docloader = DocumentLoader::new(&*doc.loader());
Ok(Document::new(win,
None,
None,
IsHTMLDocument::NonHTMLDocument,
None,
@@ -1557,6 +1569,7 @@ impl Document {
}

pub fn new(window: &Window,
browsing_context: Option<&BrowsingContext>,
url: Option<Url>,
doctype: IsHTMLDocument,
content_type: Option<DOMString>,
@@ -1565,6 +1578,7 @@ impl Document {
doc_loader: DocumentLoader)
-> Root<Document> {
let document = reflect_dom_object(box Document::new_inherited(window,
browsing_context,
url,
doctype,
content_type,
@@ -1627,6 +1641,7 @@ impl Document {
IsHTMLDocument::NonHTMLDocument
};
let new_doc = Document::new(self.window(),
None,
None,
doctype,
None,
@@ -1716,7 +1731,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),
@@ -1602,7 +1602,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)
@@ -425,7 +425,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
@@ -1094,8 +1094,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.
@@ -1282,7 +1283,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,
@@ -1110,6 +1110,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};
@@ -1792,6 +1793,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))
});
@@ -1819,16 +1824,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
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.