Auto merge of #8060 - nox:deref-js, r=Ms2ger

Implement Deref<Target=T> for JS<T> where T: Reflectable

We can only borrow `JS<T>` from rooted things, so it's safe to deref it.
The only types that provide mutable `JS<T>` things are `MutHeap<JS<T>>` and
`MutNullableHeap<JS<T>>`, which don't actually expose that they contain
`JS<T>` values.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8060)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-10-19 06:32:05 -06:00
commit 1a376aa75d
23 changed files with 187 additions and 274 deletions

View file

@ -96,6 +96,16 @@ impl<T: Reflectable> JS<T> {
} }
} }
impl<T: Reflectable> Deref for JS<T> {
type Target = T;
fn deref(&self) -> &T {
// We can only have &JS<T> from a rooted thing, so it's safe to deref
// it to &T.
unsafe { &**self.ptr }
}
}
impl<T: Reflectable> JSTraceable for JS<T> { impl<T: Reflectable> JSTraceable for JS<T> {
fn trace(&self, trc: *mut JSTracer) { fn trace(&self, trc: *mut JSTracer) {
trace_reflector(trc, "", unsafe { (**self.ptr).reflector() }); trace_reflector(trc, "", unsafe { (**self.ptr).reflector() });

View file

@ -44,17 +44,16 @@ impl BrowsingContext {
} }
} }
pub fn active_document(&self) -> Root<Document> { pub fn active_document(&self) -> &Document {
self.history[self.active_index].document.root() &*self.history[self.active_index].document
} }
pub fn active_window(&self) -> Root<Window> { pub fn active_window(&self) -> &Window {
let doc = self.active_document(); self.active_document().window()
doc.r().window()
} }
pub fn frame_element(&self) -> Option<Root<Element>> { pub fn frame_element(&self) -> Option<&Element> {
self.frame_element.as_ref().map(JS::root) self.frame_element.as_ref().map(|element| &**element)
} }
pub fn window_proxy(&self) -> *mut JSObject { pub fn window_proxy(&self) -> *mut JSObject {
@ -64,8 +63,8 @@ impl BrowsingContext {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn create_window_proxy(&mut self) { pub fn create_window_proxy(&mut self) {
let win = self.active_window(); // We inline self.active_window() because we can't borrow *self here.
let win = win.r(); let win = self.history[self.active_index].document.window();
let WindowProxyHandler(handler) = win.windowproxy_handler(); let WindowProxyHandler(handler) = win.windowproxy_handler();
assert!(!handler.is_null()); assert!(!handler.is_null());

View file

@ -232,8 +232,8 @@ impl Document {
} }
#[inline] #[inline]
pub fn window(&self) -> Root<Window> { pub fn window(&self) -> &Window {
self.window.root() &*self.window
} }
#[inline] #[inline]
@ -248,13 +248,11 @@ impl Document {
// https://html.spec.whatwg.org/multipage/#fully-active // https://html.spec.whatwg.org/multipage/#fully-active
pub fn is_fully_active(&self) -> bool { pub fn is_fully_active(&self) -> bool {
let window = self.window.root(); let browsing_context = self.window.browsing_context();
let window = window.r();
let browsing_context = window.browsing_context();
let browsing_context = browsing_context.as_ref().unwrap(); let browsing_context = browsing_context.as_ref().unwrap();
let active_document = browsing_context.active_document(); let active_document = browsing_context.active_document();
if self != active_document.r() { if self != active_document {
return false; return false;
} }
// FIXME: It should also check whether the browser context is top-level or not // FIXME: It should also check whether the browser context is top-level or not
@ -308,9 +306,7 @@ impl Document {
self.quirks_mode.set(mode); self.quirks_mode.set(mode);
if mode == Quirks { if mode == Quirks {
let window = self.window.root(); let LayoutChan(ref layout_chan) = self.window.layout_chan();
let window = window.r();
let LayoutChan(ref layout_chan) = window.layout_chan();
layout_chan.send(Msg::SetQuirksMode).unwrap(); layout_chan.send(Msg::SetQuirksMode).unwrap();
} }
} }
@ -336,10 +332,9 @@ impl Document {
} }
self.reflow_timeout.set(None); self.reflow_timeout.set(None);
let window = self.window.root(); self.window.reflow(ReflowGoal::ForDisplay,
window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery,
ReflowQueryType::NoQuery, ReflowReason::RefreshTick);
ReflowReason::RefreshTick);
} }
} }
@ -449,8 +444,7 @@ impl Document {
None => return None, None => return None,
}; };
let root = NodeCast::from_ref(root); let root = NodeCast::from_ref(root);
let win = self.window.root(); let address = match self.window.layout().hit_test(root.to_trusted_node_address(), *point) {
let address = match win.r().layout().hit_test(root.to_trusted_node_address(), *point) {
Ok(HitTestResponse(node_address)) => Some(node_address), Ok(HitTestResponse(node_address)) => Some(node_address),
Err(()) => { Err(()) => {
debug!("layout query error"); debug!("layout query error");
@ -467,8 +461,7 @@ impl Document {
None => return vec!(), None => return vec!(),
}; };
let root = NodeCast::from_ref(root); let root = NodeCast::from_ref(root);
let win = self.window.root(); match self.window.layout().mouse_over(root.to_trusted_node_address(), *point) {
match win.r().layout().mouse_over(root.to_trusted_node_address(), *point) {
Ok(MouseOverResponse(node_address)) => node_address, Ok(MouseOverResponse(node_address)) => node_address,
Err(()) => vec!(), Err(()) => vec!(),
} }
@ -478,8 +471,7 @@ impl Document {
pub fn set_ready_state(&self, state: DocumentReadyState) { pub fn set_ready_state(&self, state: DocumentReadyState) {
self.ready_state.set(state); self.ready_state.set(state);
let window = self.window.root(); let event = Event::new(GlobalRef::Window(&self.window), "readystatechange".to_owned(),
let event = Event::new(GlobalRef::Window(window.r()), "readystatechange".to_owned(),
EventBubbles::DoesNotBubble, EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable); EventCancelable::NotCancelable);
let target = EventTargetCast::from_ref(self); let target = EventTargetCast::from_ref(self);
@ -527,9 +519,8 @@ impl Document {
// Update the focus state for all elements in the focus chain. // Update the focus state for all elements in the focus chain.
// https://html.spec.whatwg.org/multipage/#focus-chain // https://html.spec.whatwg.org/multipage/#focus-chain
if focus_type == FocusType::Element { if focus_type == FocusType::Element {
let window = self.window.root(); let ConstellationChan(ref chan) = self.window.constellation_chan();
let ConstellationChan(ref chan) = window.r().constellation_chan(); let event = ConstellationMsg::Focus(self.window.pipeline());
let event = ConstellationMsg::Focus(window.r().pipeline());
chan.send(event).unwrap(); chan.send(event).unwrap();
} }
} }
@ -546,8 +537,6 @@ impl Document {
/// Sends this document's title to the compositor. /// Sends this document's title to the compositor.
pub fn send_title_to_compositor(&self) { pub fn send_title_to_compositor(&self) {
let window = self.window(); let window = self.window();
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let window = window.r();
let compositor = window.compositor(); let compositor = window.compositor();
compositor.send(ScriptToCompositorMsg::SetTitle(window.pipeline(), Some(self.Title()))).unwrap(); compositor.send(ScriptToCompositorMsg::SetTitle(window.pipeline(), Some(self.Title()))).unwrap();
} }
@ -598,17 +587,15 @@ impl Document {
self.begin_focus_transaction(); self.begin_focus_transaction();
} }
let window = self.window.root();
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-click // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-click
let x = point.x as i32; let x = point.x as i32;
let y = point.y as i32; let y = point.y as i32;
let clickCount = 1; let clickCount = 1;
let event = MouseEvent::new(window.r(), let event = MouseEvent::new(&self.window,
mouse_event_type_string, mouse_event_type_string,
EventBubbles::Bubbles, EventBubbles::Bubbles,
EventCancelable::Cancelable, EventCancelable::Cancelable,
Some(window.r()), Some(&self.window),
clickCount, clickCount,
x, y, x, y, x, y, x, y,
false, false, false, false, false, false, false, false,
@ -630,7 +617,9 @@ impl Document {
if let MouseEventType::Click = mouse_event_type { if let MouseEventType::Click = mouse_event_type {
self.commit_focus_transaction(FocusType::Element); self.commit_focus_transaction(FocusType::Element);
} }
window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::MouseEvent); self.window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::MouseEvent);
} }
pub fn fire_mouse_event(&self, pub fn fire_mouse_event(&self,
@ -640,13 +629,11 @@ impl Document {
let x = point.x.to_i32().unwrap_or(0); let x = point.x.to_i32().unwrap_or(0);
let y = point.y.to_i32().unwrap_or(0); let y = point.y.to_i32().unwrap_or(0);
let window = self.window.root(); let mouse_event = MouseEvent::new(&self.window,
let mouse_event = MouseEvent::new(window.r(),
event_name, event_name,
EventBubbles::Bubbles, EventBubbles::Bubbles,
EventCancelable::Cancelable, EventCancelable::Cancelable,
Some(window.r()), Some(&self.window),
0i32, 0i32,
x, y, x, y, x, y, x, y,
false, false, false, false, false, false, false, false,
@ -714,10 +701,9 @@ impl Document {
prev_mouse_over_targets.clear(); prev_mouse_over_targets.clear();
prev_mouse_over_targets.append(&mut *mouse_over_targets); prev_mouse_over_targets.append(&mut *mouse_over_targets);
let window = self.window.root(); self.window.reflow(ReflowGoal::ForDisplay,
window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery,
ReflowQueryType::NoQuery, ReflowReason::MouseEvent);
ReflowReason::MouseEvent);
} }
/// The entry point for all key processing for web content /// The entry point for all key processing for web content
@ -726,14 +712,13 @@ impl Document {
state: KeyState, state: KeyState,
modifiers: KeyModifiers, modifiers: KeyModifiers,
compositor: &mut IpcSender<ScriptToCompositorMsg>) { compositor: &mut IpcSender<ScriptToCompositorMsg>) {
let window = self.window.root();
let focused = self.get_focused_element(); let focused = self.get_focused_element();
let body = self.GetBody(); let body = self.GetBody();
let target = match (&focused, &body) { let target = match (&focused, &body) {
(&Some(ref focused), _) => EventTargetCast::from_ref(focused.r()), (&Some(ref focused), _) => EventTargetCast::from_ref(focused.r()),
(&None, &Some(ref body)) => EventTargetCast::from_ref(body.r()), (&None, &Some(ref body)) => EventTargetCast::from_ref(body.r()),
(&None, &None) => EventTargetCast::from_ref(window.r()), (&None, &None) => EventTargetCast::from_ref(&*self.window),
}; };
let ctrl = modifiers.contains(CONTROL); let ctrl = modifiers.contains(CONTROL);
@ -750,8 +735,8 @@ impl Document {
let props = KeyboardEvent::key_properties(key, modifiers); let props = KeyboardEvent::key_properties(key, modifiers);
let keyevent = KeyboardEvent::new(window.r(), ev_type, true, true, let keyevent = KeyboardEvent::new(&self.window, ev_type, true, true,
Some(window.r()), 0, Some(key), Some(&self.window), 0, Some(key),
props.key_string.to_owned(), props.code.to_owned(), props.key_string.to_owned(), props.code.to_owned(),
props.location, is_repeating, is_composing, props.location, is_repeating, is_composing,
ctrl, alt, shift, meta, ctrl, alt, shift, meta,
@ -763,8 +748,8 @@ impl Document {
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keys-cancelable-keys // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keys-cancelable-keys
if state != KeyState::Released && props.is_printable() && !prevented { if state != KeyState::Released && props.is_printable() && !prevented {
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keypress-event-order // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keypress-event-order
let event = KeyboardEvent::new(window.r(), "keypress".to_owned(), let event = KeyboardEvent::new(&self.window, "keypress".to_owned(),
true, true, Some(window.r()), 0, Some(key), true, true, Some(&self.window), 0, Some(key),
props.key_string.to_owned(), props.code.to_owned(), props.key_string.to_owned(), props.code.to_owned(),
props.location, is_repeating, is_composing, props.location, is_repeating, is_composing,
ctrl, alt, shift, meta, ctrl, alt, shift, meta,
@ -804,7 +789,9 @@ impl Document {
_ => () _ => ()
} }
window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::KeyEvent); self.window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::KeyEvent);
} }
pub fn node_from_nodes_and_strings(&self, nodes: Vec<NodeOrString>) pub fn node_from_nodes_and_strings(&self, nodes: Vec<NodeOrString>)
@ -856,10 +843,8 @@ impl Document {
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) { pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
if htmliframeelement::mozbrowser_enabled() { if htmliframeelement::mozbrowser_enabled() {
let window = self.window.root(); if let Some((containing_pipeline_id, subpage_id)) = self.window.parent_info() {
let ConstellationChan(ref chan) = self.window.constellation_chan();
if let Some((containing_pipeline_id, subpage_id)) = window.r().parent_info() {
let ConstellationChan(ref chan) = window.r().constellation_chan();
let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id, let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id,
subpage_id, subpage_id,
event); event);
@ -870,16 +855,14 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#dom-window-requestanimationframe /// https://html.spec.whatwg.org/multipage/#dom-window-requestanimationframe
pub fn request_animation_frame(&self, callback: Box<FnBox(f64)>) -> u32 { pub fn request_animation_frame(&self, callback: Box<FnBox(f64)>) -> u32 {
let window = self.window.root();
let window = window.r();
let ident = self.animation_frame_ident.get() + 1; let ident = self.animation_frame_ident.get() + 1;
self.animation_frame_ident.set(ident); self.animation_frame_ident.set(ident);
self.animation_frame_list.borrow_mut().insert(ident, callback); self.animation_frame_list.borrow_mut().insert(ident, callback);
// TODO: Should tick animation only when document is visible // TODO: Should tick animation only when document is visible
let ConstellationChan(ref chan) = window.constellation_chan(); let ConstellationChan(ref chan) = self.window.constellation_chan();
let event = ConstellationMsg::ChangeRunningAnimationsState(window.pipeline(), let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
AnimationState::AnimationCallbacksPresent); AnimationState::AnimationCallbacksPresent);
chan.send(event).unwrap(); chan.send(event).unwrap();
@ -890,10 +873,8 @@ impl Document {
pub fn cancel_animation_frame(&self, ident: u32) { pub fn cancel_animation_frame(&self, ident: u32) {
self.animation_frame_list.borrow_mut().remove(&ident); self.animation_frame_list.borrow_mut().remove(&ident);
if self.animation_frame_list.borrow().is_empty() { if self.animation_frame_list.borrow().is_empty() {
let window = self.window.root(); let ConstellationChan(ref chan) = self.window.constellation_chan();
let window = window.r(); let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
let ConstellationChan(ref chan) = window.constellation_chan();
let event = ConstellationMsg::ChangeRunningAnimationsState(window.pipeline(),
AnimationState::NoAnimationCallbacksPresent); AnimationState::NoAnimationCallbacksPresent);
chan.send(event).unwrap(); chan.send(event).unwrap();
} }
@ -906,16 +887,12 @@ impl Document {
let mut list = self.animation_frame_list.borrow_mut(); let mut list = self.animation_frame_list.borrow_mut();
animation_frame_list = Vec::from_iter(list.drain()); animation_frame_list = Vec::from_iter(list.drain());
let window = self.window.root(); let ConstellationChan(ref chan) = self.window.constellation_chan();
let window = window.r(); let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
let ConstellationChan(ref chan) = window.constellation_chan();
let event = ConstellationMsg::ChangeRunningAnimationsState(window.pipeline(),
AnimationState::NoAnimationCallbacksPresent); AnimationState::NoAnimationCallbacksPresent);
chan.send(event).unwrap(); chan.send(event).unwrap();
} }
let window = self.window.root(); let performance = self.window.Performance();
let window = window.r();
let performance = window.Performance();
let performance = performance.r(); let performance = performance.r();
let timing = performance.Now(); let timing = performance.Now();
@ -923,9 +900,9 @@ impl Document {
callback(*timing); callback(*timing);
} }
window.reflow(ReflowGoal::ForDisplay, self.window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery, ReflowQueryType::NoQuery,
ReflowReason::RequestAnimationFrame); ReflowReason::RequestAnimationFrame);
} }
pub fn prepare_async_load(&self, load: LoadType) -> PendingAsyncLoad { pub fn prepare_async_load(&self, load: LoadType) -> PendingAsyncLoad {
@ -949,9 +926,8 @@ impl Document {
} }
pub fn notify_constellation_load(&self) { pub fn notify_constellation_load(&self) {
let window = self.window.root(); let pipeline_id = self.window.pipeline();
let pipeline_id = window.r().pipeline(); let ConstellationChan(ref chan) = self.window.constellation_chan();
let ConstellationChan(ref chan) = window.r().constellation_chan();
let event = ConstellationMsg::DOMLoad(pipeline_id); let event = ConstellationMsg::DOMLoad(pipeline_id);
chan.send(event).unwrap(); chan.send(event).unwrap();
@ -1092,12 +1068,11 @@ impl Document {
} }
fn create_node_list<F: Fn(&Node) -> bool>(&self, callback: F) -> Root<NodeList> { fn create_node_list<F: Fn(&Node) -> bool>(&self, callback: F) -> Root<NodeList> {
let window = self.window.root();
let doc = self.GetDocumentElement(); let doc = self.GetDocumentElement();
let maybe_node = doc.r().map(NodeCast::from_ref); let maybe_node = doc.r().map(NodeCast::from_ref);
let iter = maybe_node.iter().flat_map(|node| node.traverse_preorder()) let iter = maybe_node.iter().flat_map(|node| node.traverse_preorder())
.filter(|node| callback(node.r())); .filter(|node| callback(node.r()));
NodeList::new_simple_list(window.r(), iter) NodeList::new_simple_list(&self.window, iter)
} }
fn get_html_element(&self) -> Option<Root<HTMLHtmlElement>> { fn get_html_element(&self) -> Option<Root<HTMLHtmlElement>> {
@ -1116,7 +1091,7 @@ impl Document {
IsHTMLDocument::NonHTMLDocument IsHTMLDocument::NonHTMLDocument
}; };
let new_doc = Document::new( let new_doc = Document::new(
&*self.window(), None, doctype, None, None, self.window(), None, doctype, None, None,
DocumentSource::NotFromParser, DocumentLoader::new(&self.loader())); DocumentSource::NotFromParser, DocumentLoader::new(&self.loader()));
new_doc.appropriate_template_contents_owner_document.set(Some(&new_doc)); new_doc.appropriate_template_contents_owner_document.set(Some(&new_doc));
new_doc new_doc
@ -1168,9 +1143,7 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-hasfocus // https://html.spec.whatwg.org/multipage/#dom-document-hasfocus
fn HasFocus(&self) -> bool { fn HasFocus(&self) -> bool {
let target = self; // Step 1. let target = self; // Step 1.
let window = self.window.root(); let browsing_context = self.window.browsing_context();
let window = window.r();
let browsing_context = window.browsing_context();
let browsing_context = browsing_context.as_ref(); let browsing_context = browsing_context.as_ref();
match browsing_context { match browsing_context {
@ -1230,22 +1203,18 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-getelementsbytagname // https://dom.spec.whatwg.org/#dom-document-getelementsbytagname
fn GetElementsByTagName(&self, tag_name: DOMString) -> Root<HTMLCollection> { fn GetElementsByTagName(&self, tag_name: DOMString) -> Root<HTMLCollection> {
let window = self.window.root(); HTMLCollection::by_tag_name(&self.window, NodeCast::from_ref(self), tag_name)
HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), tag_name)
} }
// https://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens // https://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens
fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, tag_name: DOMString) fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, tag_name: DOMString)
-> Root<HTMLCollection> { -> Root<HTMLCollection> {
let window = self.window.root(); HTMLCollection::by_tag_name_ns(&self.window, NodeCast::from_ref(self), tag_name, maybe_ns)
HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), tag_name, maybe_ns)
} }
// https://dom.spec.whatwg.org/#dom-document-getelementsbyclassname // https://dom.spec.whatwg.org/#dom-document-getelementsbyclassname
fn GetElementsByClassName(&self, classes: DOMString) -> Root<HTMLCollection> { fn GetElementsByClassName(&self, classes: DOMString) -> Root<HTMLCollection> {
let window = self.window.root(); HTMLCollection::by_class_name(&self.window, NodeCast::from_ref(self), classes)
HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes)
} }
// https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid // https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
@ -1284,13 +1253,12 @@ impl DocumentMethods for Document {
return Err(Error::InvalidCharacter); return Err(Error::InvalidCharacter);
} }
let window = self.window.root();
let name = Atom::from_slice(&local_name); let name = Atom::from_slice(&local_name);
// repetition used because string_cache::atom::Atom is non-copyable // repetition used because string_cache::atom::Atom is non-copyable
let l_name = Atom::from_slice(&local_name); let l_name = Atom::from_slice(&local_name);
let value = AttrValue::String("".to_owned()); let value = AttrValue::String("".to_owned());
Ok(Attr::new(window.r(), name, value, l_name, ns!(""), None, None)) Ok(Attr::new(&self.window, name, value, l_name, ns!(""), None, None))
} }
// https://dom.spec.whatwg.org/#dom-document-createattributens // https://dom.spec.whatwg.org/#dom-document-createattributens
@ -1298,10 +1266,9 @@ impl DocumentMethods for Document {
-> Fallible<Root<Attr>> { -> Fallible<Root<Attr>> {
let (namespace, prefix, local_name) = let (namespace, prefix, local_name) =
try!(validate_and_extract(namespace, &qualified_name)); try!(validate_and_extract(namespace, &qualified_name));
let window = self.window.root();
let value = AttrValue::String("".to_owned()); let value = AttrValue::String("".to_owned());
let qualified_name = Atom::from_slice(&qualified_name); let qualified_name = Atom::from_slice(&qualified_name);
Ok(Attr::new(window.r(), local_name, value, qualified_name, Ok(Attr::new(&self.window, local_name, value, qualified_name,
namespace, prefix, None)) namespace, prefix, None))
} }
@ -1369,22 +1336,20 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-createevent // https://dom.spec.whatwg.org/#dom-document-createevent
fn CreateEvent(&self, mut interface: DOMString) -> Fallible<Root<Event>> { fn CreateEvent(&self, mut interface: DOMString) -> Fallible<Root<Event>> {
let window = self.window.root();
interface.make_ascii_lowercase(); interface.make_ascii_lowercase();
match &*interface { match &*interface {
"uievents" | "uievent" => Ok(EventCast::from_root( "uievents" | "uievent" => Ok(EventCast::from_root(
UIEvent::new_uninitialized(window.r()))), UIEvent::new_uninitialized(&self.window))),
"mouseevents" | "mouseevent" => Ok(EventCast::from_root( "mouseevents" | "mouseevent" => Ok(EventCast::from_root(
MouseEvent::new_uninitialized(window.r()))), MouseEvent::new_uninitialized(&self.window))),
"customevent" => Ok(EventCast::from_root( "customevent" => Ok(EventCast::from_root(
CustomEvent::new_uninitialized(GlobalRef::Window(window.r())))), CustomEvent::new_uninitialized(GlobalRef::Window(&self.window)))),
"htmlevents" | "events" | "event" => Ok(Event::new_uninitialized( "htmlevents" | "events" | "event" => Ok(Event::new_uninitialized(
GlobalRef::Window(window.r()))), GlobalRef::Window(&self.window))),
"keyboardevent" | "keyevents" => Ok(EventCast::from_root( "keyboardevent" | "keyevents" => Ok(EventCast::from_root(
KeyboardEvent::new_uninitialized(window.r()))), KeyboardEvent::new_uninitialized(&self.window))),
"messageevent" => Ok(EventCast::from_root( "messageevent" => Ok(EventCast::from_root(
MessageEvent::new_uninitialized(GlobalRef::Window(window.r())))), MessageEvent::new_uninitialized(GlobalRef::Window(&self.window)))),
_ => Err(Error::NotSupported) _ => Err(Error::NotSupported)
} }
} }
@ -1585,20 +1550,18 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-images // https://html.spec.whatwg.org/multipage/#dom-document-images
fn Images(&self) -> Root<HTMLCollection> { fn Images(&self) -> Root<HTMLCollection> {
self.images.or_init(|| { self.images.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box ImagesFilter; let filter = box ImagesFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
// https://html.spec.whatwg.org/multipage/#dom-document-embeds // https://html.spec.whatwg.org/multipage/#dom-document-embeds
fn Embeds(&self) -> Root<HTMLCollection> { fn Embeds(&self) -> Root<HTMLCollection> {
self.embeds.or_init(|| { self.embeds.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box EmbedsFilter; let filter = box EmbedsFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
@ -1610,40 +1573,36 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-links // https://html.spec.whatwg.org/multipage/#dom-document-links
fn Links(&self) -> Root<HTMLCollection> { fn Links(&self) -> Root<HTMLCollection> {
self.links.or_init(|| { self.links.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box LinksFilter; let filter = box LinksFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
// https://html.spec.whatwg.org/multipage/#dom-document-forms // https://html.spec.whatwg.org/multipage/#dom-document-forms
fn Forms(&self) -> Root<HTMLCollection> { fn Forms(&self) -> Root<HTMLCollection> {
self.forms.or_init(|| { self.forms.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box FormsFilter; let filter = box FormsFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
// https://html.spec.whatwg.org/multipage/#dom-document-scripts // https://html.spec.whatwg.org/multipage/#dom-document-scripts
fn Scripts(&self) -> Root<HTMLCollection> { fn Scripts(&self) -> Root<HTMLCollection> {
self.scripts.or_init(|| { self.scripts.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box ScriptsFilter; let filter = box ScriptsFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
// https://html.spec.whatwg.org/multipage/#dom-document-anchors // https://html.spec.whatwg.org/multipage/#dom-document-anchors
fn Anchors(&self) -> Root<HTMLCollection> { fn Anchors(&self) -> Root<HTMLCollection> {
self.anchors.or_init(|| { self.anchors.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box AnchorsFilter; let filter = box AnchorsFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
@ -1651,24 +1610,20 @@ impl DocumentMethods for Document {
fn Applets(&self) -> Root<HTMLCollection> { fn Applets(&self) -> Root<HTMLCollection> {
// FIXME: This should be return OBJECT elements containing applets. // FIXME: This should be return OBJECT elements containing applets.
self.applets.or_init(|| { self.applets.or_init(|| {
let window = self.window.root();
let root = NodeCast::from_ref(self); let root = NodeCast::from_ref(self);
let filter = box AppletsFilter; let filter = box AppletsFilter;
HTMLCollection::create(window.r(), root, filter) HTMLCollection::create(&self.window, root, filter)
}) })
} }
// https://html.spec.whatwg.org/multipage/#dom-document-location // https://html.spec.whatwg.org/multipage/#dom-document-location
fn Location(&self) -> Root<Location> { fn Location(&self) -> Root<Location> {
let window = self.window.root(); self.location.or_init(|| Location::new(&self.window))
let window = window.r();
self.location.or_init(|| Location::new(window))
} }
// https://dom.spec.whatwg.org/#dom-parentnode-children // https://dom.spec.whatwg.org/#dom-parentnode-children
fn Children(&self) -> Root<HTMLCollection> { fn Children(&self) -> Root<HTMLCollection> {
let window = self.window.root(); HTMLCollection::children(&self.window, NodeCast::from_ref(self))
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
} }
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild // https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
@ -1725,9 +1680,8 @@ impl DocumentMethods for Document {
if !is_scheme_host_port_tuple(&url) { if !is_scheme_host_port_tuple(&url) {
return Err(Error::Security); return Err(Error::Security);
} }
let window = self.window.root();
let (tx, rx) = ipc::channel().unwrap(); let (tx, rx) = ipc::channel().unwrap();
let _ = window.r().resource_task().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP)); let _ = self.window.resource_task().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP));
let cookies = rx.recv().unwrap(); let cookies = rx.recv().unwrap();
Ok(cookies.unwrap_or("".to_owned())) Ok(cookies.unwrap_or("".to_owned()))
} }
@ -1739,8 +1693,7 @@ impl DocumentMethods for Document {
if !is_scheme_host_port_tuple(url) { if !is_scheme_host_port_tuple(url) {
return Err(Error::Security); return Err(Error::Security);
} }
let window = self.window.root(); let _ = self.window.resource_task().send(SetCookiesForUrl((*url).clone(), cookie, NonHTTP));
let _ = window.r().resource_task().send(SetCookiesForUrl((*url).clone(), cookie, NonHTTP));
Ok(()) Ok(())
} }
@ -1834,9 +1787,8 @@ impl DocumentMethods for Document {
} }
// Step 4. // Step 4.
*found = true; *found = true;
let window = self.window();
let filter = NamedElementFilter { name: name }; let filter = NamedElementFilter { name: name };
let collection = HTMLCollection::create(window.r(), root, box filter); let collection = HTMLCollection::create(self.window(), root, box filter);
collection.r().reflector().get_jsobject().get() collection.r().reflector().get_jsobject().get()
} }
@ -1894,13 +1846,15 @@ impl DocumentProgressHandler {
fn dispatch_dom_content_loaded(&self) { fn dispatch_dom_content_loaded(&self) {
let document = self.addr.root(); let document = self.addr.root();
let window = document.r().window(); let window = document.r().window();
let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".to_owned(), let event = Event::new(GlobalRef::Window(window), "DOMContentLoaded".to_owned(),
EventBubbles::DoesNotBubble, EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable); EventCancelable::NotCancelable);
let doctarget = EventTargetCast::from_ref(document.r()); let doctarget = EventTargetCast::from_ref(document.r());
let _ = doctarget.DispatchEvent(event.r()); let _ = doctarget.DispatchEvent(event.r());
window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::DOMContentLoaded); window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::DOMContentLoaded);
} }
fn set_ready_state_complete(&self) { fn set_ready_state_complete(&self) {
@ -1911,35 +1865,34 @@ impl DocumentProgressHandler {
fn dispatch_load(&self) { fn dispatch_load(&self) {
let document = self.addr.root(); let document = self.addr.root();
let window = document.r().window(); let window = document.r().window();
let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(), let event = Event::new(GlobalRef::Window(window), "load".to_owned(),
EventBubbles::DoesNotBubble, EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable); EventCancelable::NotCancelable);
let wintarget = EventTargetCast::from_ref(window.r()); let wintarget = EventTargetCast::from_ref(window);
let doctarget = EventTargetCast::from_ref(document.r()); let doctarget = EventTargetCast::from_ref(document.r());
event.r().set_trusted(true); event.r().set_trusted(true);
let _ = wintarget.dispatch_event_with_target(doctarget, event.r()); let _ = wintarget.dispatch_event_with_target(doctarget, event.r());
let window_ref = window.r(); let browsing_context = window.browsing_context();
let browsing_context = window_ref.browsing_context();
let browsing_context = browsing_context.as_ref().unwrap(); let browsing_context = browsing_context.as_ref().unwrap();
browsing_context.frame_element().map(|frame_element| { if let Some(frame_element) = browsing_context.frame_element() {
let frame_window = window_from_node(frame_element.r()); let frame_window = window_from_node(frame_element);
let event = Event::new(GlobalRef::Window(frame_window.r()), "load".to_owned(), let event = Event::new(GlobalRef::Window(frame_window.r()), "load".to_owned(),
EventBubbles::DoesNotBubble, EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable); EventCancelable::NotCancelable);
let target = EventTargetCast::from_ref(frame_element.r()); let target = EventTargetCast::from_ref(frame_element);
event.r().fire(target); event.r().fire(target);
}); };
document.r().notify_constellation_load(); document.r().notify_constellation_load();
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend // https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend
document.r().trigger_mozbrowser_event(MozBrowserEvent::LoadEnd); document.r().trigger_mozbrowser_event(MozBrowserEvent::LoadEnd);
window_ref.reflow(ReflowGoal::ForDisplay, window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery, ReflowQueryType::NoQuery,
ReflowReason::DocumentLoaded); ReflowReason::DocumentLoaded);
} }
} }
@ -1947,7 +1900,7 @@ impl Runnable for DocumentProgressHandler {
fn handler(self: Box<DocumentProgressHandler>) { fn handler(self: Box<DocumentProgressHandler>) {
let document = self.addr.root(); let document = self.addr.root();
let window = document.r().window(); let window = document.r().window();
if window.r().is_alive() { if window.is_alive() {
match self.task { match self.task {
DocumentProgressTask::DOMContentLoaded => { DocumentProgressTask::DOMContentLoaded => {
self.dispatch_dom_content_loaded(); self.dispatch_dom_content_loaded();

View file

@ -42,7 +42,7 @@ impl DOMImplementation {
pub fn new(document: &Document) -> Root<DOMImplementation> { pub fn new(document: &Document) -> Root<DOMImplementation> {
let window = document.window(); let window = document.window();
reflect_dom_object(box DOMImplementation::new_inherited(document), reflect_dom_object(box DOMImplementation::new_inherited(document),
GlobalRef::Window(window.r()), GlobalRef::Window(window),
DOMImplementationBinding::Wrap) DOMImplementationBinding::Wrap)
} }
} }
@ -53,20 +53,17 @@ impl DOMImplementationMethods for DOMImplementation {
fn CreateDocumentType(&self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString) fn CreateDocumentType(&self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString)
-> Fallible<Root<DocumentType>> { -> Fallible<Root<DocumentType>> {
try!(validate_qualified_name(&qualified_name)); try!(validate_qualified_name(&qualified_name));
let document = self.document.root(); Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), &self.document))
Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r()))
} }
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocument // https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString, fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString,
maybe_doctype: Option<&DocumentType>) -> Fallible<Root<Document>> { maybe_doctype: Option<&DocumentType>) -> Fallible<Root<Document>> {
let doc = self.document.root(); let win = self.document.window();
let doc = doc.r(); let loader = DocumentLoader::new(&self.document.loader());
let win = doc.window();
let loader = DocumentLoader::new(&*doc.loader());
// Step 1. // Step 1.
let doc = Document::new(win.r(), None, IsHTMLDocument::NonHTMLDocument, let doc = Document::new(win, None, IsHTMLDocument::NonHTMLDocument,
None, None, DocumentSource::NotFromParser, loader); None, None, DocumentSource::NotFromParser, loader);
// Step 2-3. // Step 2-3.
let maybe_elem = if qname.is_empty() { let maybe_elem = if qname.is_empty() {
@ -108,13 +105,11 @@ impl DOMImplementationMethods for DOMImplementation {
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument // https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Root<Document> { fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Root<Document> {
let document = self.document.root(); let win = self.document.window();
let document = document.r(); let loader = DocumentLoader::new(&self.document.loader());
let win = document.window();
let loader = DocumentLoader::new(&*document.loader());
// Step 1-2. // Step 1-2.
let doc = Document::new(win.r(), None, IsHTMLDocument::HTMLDocument, None, None, let doc = Document::new(win, None, IsHTMLDocument::HTMLDocument, None, None,
DocumentSource::NotFromParser, loader); DocumentSource::NotFromParser, loader);
{ {

View file

@ -49,15 +49,14 @@ impl DOMParserMethods for DOMParser {
s: DOMString, s: DOMString,
ty: DOMParserBinding::SupportedType) ty: DOMParserBinding::SupportedType)
-> Fallible<Root<Document>> { -> Fallible<Root<Document>> {
let window = self.window.root(); let url = self.window.get_url();
let url = window.r().get_url();
let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as usize].to_owned(); let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as usize].to_owned();
let doc = window.r().Document(); let doc = self.window.Document();
let doc = doc.r(); let doc = doc.r();
let loader = DocumentLoader::new(&*doc.loader()); let loader = DocumentLoader::new(&*doc.loader());
match ty { match ty {
Text_html => { Text_html => {
let document = Document::new(window.r(), Some(url.clone()), let document = Document::new(&self.window, Some(url.clone()),
IsHTMLDocument::HTMLDocument, IsHTMLDocument::HTMLDocument,
Some(content_type), Some(content_type),
None, None,
@ -69,7 +68,7 @@ impl DOMParserMethods for DOMParser {
} }
Text_xml => { Text_xml => {
//FIXME: this should probably be FromParser when we actually parse the string (#3756). //FIXME: this should probably be FromParser when we actually parse the string (#3756).
Ok(Document::new(window.r(), Some(url.clone()), Ok(Document::new(&self.window, Some(url.clone()),
IsHTMLDocument::NonHTMLDocument, IsHTMLDocument::NonHTMLDocument,
Some(content_type), Some(content_type),
None, None,

View file

@ -37,20 +37,17 @@ impl DOMStringMap {
impl DOMStringMapMethods for DOMStringMap { impl DOMStringMapMethods for DOMStringMap {
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-removeitem // https://html.spec.whatwg.org/multipage/#dom-domstringmap-removeitem
fn NamedDeleter(&self, name: DOMString) { fn NamedDeleter(&self, name: DOMString) {
let element = self.element.root(); self.element.delete_custom_attr(name)
element.r().delete_custom_attr(name)
} }
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem // https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem
fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult { fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult {
let element = self.element.root(); self.element.set_custom_attr(name, value)
element.r().set_custom_attr(name, value)
} }
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem // https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> DOMString { fn NamedGetter(&self, name: DOMString, found: &mut bool) -> DOMString {
let element = self.element.root(); match self.element.get_custom_attr(name) {
match element.r().get_custom_attr(name) {
Some(value) => { Some(value) => {
*found = true; *found = true;
value.clone() value.clone()

View file

@ -39,8 +39,7 @@ impl DOMTokenList {
} }
fn attribute(&self) -> Option<Root<Attr>> { fn attribute(&self) -> Option<Root<Attr>> {
let element = self.element.root(); self.element.get_attribute(&ns!(""), &self.local_name)
element.r().get_attribute(&ns!(""), &self.local_name)
} }
fn check_token_exceptions(&self, token: &str) -> Fallible<Atom> { fn check_token_exceptions(&self, token: &str) -> Fallible<Atom> {
@ -87,43 +86,40 @@ impl DOMTokenListMethods for DOMTokenList {
// https://dom.spec.whatwg.org/#dom-domtokenlist-add // https://dom.spec.whatwg.org/#dom-domtokenlist-add
fn Add(&self, tokens: Vec<DOMString>) -> ErrorResult { fn Add(&self, tokens: Vec<DOMString>) -> ErrorResult {
let element = self.element.root(); let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
for token in &tokens { for token in &tokens {
let token = try!(self.check_token_exceptions(&token)); let token = try!(self.check_token_exceptions(&token));
if !atoms.iter().any(|atom| *atom == token) { if !atoms.iter().any(|atom| *atom == token) {
atoms.push(token); atoms.push(token);
} }
} }
element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms); self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(()) Ok(())
} }
// https://dom.spec.whatwg.org/#dom-domtokenlist-remove // https://dom.spec.whatwg.org/#dom-domtokenlist-remove
fn Remove(&self, tokens: Vec<DOMString>) -> ErrorResult { fn Remove(&self, tokens: Vec<DOMString>) -> ErrorResult {
let element = self.element.root(); let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
for token in &tokens { for token in &tokens {
let token = try!(self.check_token_exceptions(&token)); let token = try!(self.check_token_exceptions(&token));
atoms.iter().position(|atom| *atom == token).map(|index| { atoms.iter().position(|atom| *atom == token).map(|index| {
atoms.remove(index) atoms.remove(index)
}); });
} }
element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms); self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(()) Ok(())
} }
// https://dom.spec.whatwg.org/#dom-domtokenlist-toggle // https://dom.spec.whatwg.org/#dom-domtokenlist-toggle
fn Toggle(&self, token: DOMString, force: Option<bool>) -> Fallible<bool> { fn Toggle(&self, token: DOMString, force: Option<bool>) -> Fallible<bool> {
let element = self.element.root(); let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
let token = try!(self.check_token_exceptions(&token)); let token = try!(self.check_token_exceptions(&token));
match atoms.iter().position(|atom| *atom == token) { match atoms.iter().position(|atom| *atom == token) {
Some(index) => match force { Some(index) => match force {
Some(true) => Ok(true), Some(true) => Ok(true),
_ => { _ => {
atoms.remove(index); atoms.remove(index);
element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms); self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(false) Ok(false)
} }
}, },
@ -131,7 +127,7 @@ impl DOMTokenListMethods for DOMTokenList {
Some(false) => Ok(false), Some(false) => Ok(false),
_ => { _ => {
atoms.push(token); atoms.push(token);
element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms); self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(true) Ok(true)
} }
} }
@ -140,7 +136,7 @@ impl DOMTokenListMethods for DOMTokenList {
// https://dom.spec.whatwg.org/#stringification-behavior // https://dom.spec.whatwg.org/#stringification-behavior
fn Stringifier(&self) -> DOMString { fn Stringifier(&self) -> DOMString {
let tokenlist = self.element.root().r().get_tokenlist_attribute(&self.local_name); let tokenlist = self.element.get_tokenlist_attribute(&self.local_name);
str_join(&tokenlist, "\x20") str_join(&tokenlist, "\x20")
} }

View file

@ -1176,7 +1176,7 @@ impl ElementMethods for Element {
node.owner_doc() node.owner_doc()
}; };
let window = doc.r().window(); let window = doc.r().window();
NamedNodeMap::new(window.r(), self) NamedNodeMap::new(window, self)
}) })
} }

View file

@ -100,7 +100,6 @@ impl HTMLImageElement {
let node = NodeCast::from_ref(self); let node = NodeCast::from_ref(self);
let document = node.owner_doc(); let document = node.owner_doc();
let window = document.r().window(); let window = document.r().window();
let window = window.r();
let image_cache = window.image_cache_task(); let image_cache = window.image_cache_task();
match value { match value {
None => { None => {

View file

@ -106,7 +106,7 @@ static DEFAULT_INPUT_SIZE: u32 = 20;
impl HTMLInputElement { impl HTMLInputElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement {
let chan = document.window().r().constellation_chan(); let chan = document.window().constellation_chan();
HTMLInputElement { HTMLInputElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
@ -759,17 +759,16 @@ impl Activatable for HTMLInputElement {
InputType::InputRadio => { InputType::InputRadio => {
// We want to restore state only if the element had been changed in the first place // We want to restore state only if the element had been changed in the first place
if cache.was_mutable { if cache.was_mutable {
let old_checked = cache.checked_radio.as_ref().map(|t| t.root());
let name = self.get_radio_group_name(); let name = self.get_radio_group_name();
match old_checked { match cache.checked_radio.as_ref().map(|t| &*t) {
Some(ref o) => { Some(o) => {
// Avoiding iterating through the whole tree here, instead // Avoiding iterating through the whole tree here, instead
// we can check if the conditions for radio group siblings apply // we can check if the conditions for radio group siblings apply
if name == o.r().get_radio_group_name() && // TODO should be compatibility caseless if name == o.get_radio_group_name() && // TODO should be compatibility caseless
self.form_owner() == o.r().form_owner() && self.form_owner() == o.form_owner() &&
// TODO Both a and b are in the same home subtree // TODO Both a and b are in the same home subtree
o.r().input_type.get() == InputType::InputRadio { o.input_type.get() == InputType::InputRadio {
o.r().SetChecked(true); o.SetChecked(true);
} else { } else {
self.SetChecked(false); self.SetChecked(false);
} }

View file

@ -209,7 +209,7 @@ impl HTMLScriptElement {
// Step 10. // Step 10.
let document_from_node_ref = document_from_node(self); let document_from_node_ref = document_from_node(self);
let document_from_node_ref = document_from_node_ref.r(); let document_from_node_ref = document_from_node_ref.r();
if self.parser_inserted.get() && self.parser_document.root().r() != document_from_node_ref { if self.parser_inserted.get() && &*self.parser_document != document_from_node_ref {
return NextParserState::Continue; return NextParserState::Continue;
} }

View file

@ -84,7 +84,7 @@ impl HTMLTextAreaElement {
fn new_inherited(localName: DOMString, fn new_inherited(localName: DOMString,
prefix: Option<DOMString>, prefix: Option<DOMString>,
document: &Document) -> HTMLTextAreaElement { document: &Document) -> HTMLTextAreaElement {
let chan = document.window().r().constellation_chan(); let chan = document.window().constellation_chan();
HTMLTextAreaElement { HTMLTextAreaElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,

View file

@ -35,33 +35,31 @@ impl Location {
} }
fn get_url(&self) -> Url { fn get_url(&self) -> Url {
self.window.root().get_url() self.window.get_url()
} }
fn set_url_component(&self, value: USVString, fn set_url_component(&self, value: USVString,
setter: fn(&mut Url, USVString)) { setter: fn(&mut Url, USVString)) {
let window = self.window.root(); let mut url = self.window.get_url();
let mut url = window.get_url();
setter(&mut url, value); setter(&mut url, value);
window.load_url(url); self.window.load_url(url);
} }
} }
impl LocationMethods for Location { impl LocationMethods for Location {
// https://html.spec.whatwg.org/multipage/#dom-location-assign // https://html.spec.whatwg.org/multipage/#dom-location-assign
fn Assign(&self, url: DOMString) { fn Assign(&self, url: DOMString) {
let window = self.window.root();
// TODO: per spec, we should use the _API base URL_ specified by the // TODO: per spec, we should use the _API base URL_ specified by the
// _entry settings object_. // _entry settings object_.
let base_url = window.get_url(); let base_url = self.window.get_url();
if let Ok(url) = UrlParser::new().base_url(&base_url).parse(&url) { if let Ok(url) = UrlParser::new().base_url(&base_url).parse(&url) {
window.load_url(url); self.window.load_url(url);
} }
} }
// https://html.spec.whatwg.org/multipage/#dom-location-reload // https://html.spec.whatwg.org/multipage/#dom-location-reload
fn Reload(&self) { fn Reload(&self) {
self.window.root().load_url(self.get_url()); self.window.load_url(self.get_url());
} }
// https://url.spec.whatwg.org/#dom-urlutils-hash // https://url.spec.whatwg.org/#dom-urlutils-hash
@ -101,9 +99,8 @@ impl LocationMethods for Location {
// https://url.spec.whatwg.org/#dom-urlutils-href // https://url.spec.whatwg.org/#dom-urlutils-href
fn SetHref(&self, value: USVString) -> ErrorResult { fn SetHref(&self, value: USVString) -> ErrorResult {
let window = self.window.root(); if let Ok(url) = UrlParser::new().base_url(&self.window.get_url()).parse(&value.0) {
if let Ok(url) = UrlParser::new().base_url(&window.get_url()).parse(&value.0) { self.window.load_url(url);
window.load_url(url);
}; };
Ok(()) Ok(())
} }

View file

@ -37,57 +37,38 @@ impl NamedNodeMap {
impl NamedNodeMapMethods for NamedNodeMap { impl NamedNodeMapMethods for NamedNodeMap {
// https://dom.spec.whatwg.org/#dom-namednodemap-length // https://dom.spec.whatwg.org/#dom-namednodemap-length
fn Length(&self) -> u32 { fn Length(&self) -> u32 {
let owner = self.owner.root(); self.owner.attrs().len() as u32
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let owner = owner.r();
let attrs = owner.attrs();
attrs.len() as u32
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-item // https://dom.spec.whatwg.org/#dom-namednodemap-item
fn Item(&self, index: u32) -> Option<Root<Attr>> { fn Item(&self, index: u32) -> Option<Root<Attr>> {
let owner = self.owner.root(); self.owner.attrs().get(index as usize).map(JS::root)
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let owner = owner.r();
let attrs = owner.attrs();
attrs.get(index as usize).map(|t| t.root())
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-getnameditem // https://dom.spec.whatwg.org/#dom-namednodemap-getnameditem
fn GetNamedItem(&self, name: DOMString) -> Option<Root<Attr>> { fn GetNamedItem(&self, name: DOMString) -> Option<Root<Attr>> {
let owner = self.owner.root(); self.owner.get_attribute_by_name(name)
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let owner = owner.r();
owner.get_attribute_by_name(name)
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-getnameditemns // https://dom.spec.whatwg.org/#dom-namednodemap-getnameditemns
fn GetNamedItemNS(&self, namespace: Option<DOMString>, local_name: DOMString) fn GetNamedItemNS(&self, namespace: Option<DOMString>, local_name: DOMString)
-> Option<Root<Attr>> { -> Option<Root<Attr>> {
let owner = self.owner.root();
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let owner = owner.r();
let ns = namespace_from_domstring(namespace); let ns = namespace_from_domstring(namespace);
owner.get_attribute(&ns, &Atom::from_slice(&local_name)) self.owner.get_attribute(&ns, &Atom::from_slice(&local_name))
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
fn RemoveNamedItem(&self, name: DOMString) -> Fallible<Root<Attr>> { fn RemoveNamedItem(&self, name: DOMString) -> Fallible<Root<Attr>> {
let owner = self.owner.root(); let name = self.owner.parsed_name(name);
// FIXME(https://github.com/rust-lang/rust/issues/23338) self.owner.remove_attribute_by_name(&name).ok_or(Error::NotFound)
let owner = owner.r();
let name = owner.parsed_name(name);
owner.remove_attribute_by_name(&name).ok_or(Error::NotFound)
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
fn RemoveNamedItemNS(&self, namespace: Option<DOMString>, local_name: DOMString) fn RemoveNamedItemNS(&self, namespace: Option<DOMString>, local_name: DOMString)
-> Fallible<Root<Attr>> { -> Fallible<Root<Attr>> {
let owner = self.owner.root();
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let owner = owner.r();
let ns = namespace_from_domstring(namespace); let ns = namespace_from_domstring(namespace);
owner.remove_attribute(&ns, &Atom::from_slice(&local_name)).ok_or(Error::NotFound) self.owner.remove_attribute(&ns, &Atom::from_slice(&local_name))
.ok_or(Error::NotFound)
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-item // https://dom.spec.whatwg.org/#dom-namednodemap-item

View file

@ -1308,7 +1308,7 @@ impl Node {
wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<N>) -> Root<N>) wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<N>) -> Root<N>)
-> Root<N> { -> Root<N> {
let window = document.window(); let window = document.window();
reflect_dom_object(node, GlobalRef::Window(window.r()), wrap_fn) reflect_dom_object(node, GlobalRef::Window(window), wrap_fn)
} }
pub fn new_inherited(doc: &Document) -> Node { pub fn new_inherited(doc: &Document) -> Node {
@ -1651,7 +1651,7 @@ impl Node {
}; };
let window = document.window(); let window = document.window();
let loader = DocumentLoader::new(&*document.loader()); let loader = DocumentLoader::new(&*document.loader());
let document = Document::new(window.r(), Some((*document.url()).clone()), let document = Document::new(window, Some((*document.url()).clone()),
is_html_doc, None, is_html_doc, None,
None, DocumentSource::NotFromParser, loader); None, DocumentSource::NotFromParser, loader);
NodeCast::from_root(document) NodeCast::from_root(document)
@ -1892,7 +1892,7 @@ impl NodeMethods for Node {
self.child_list.or_init(|| { self.child_list.or_init(|| {
let doc = self.owner_doc(); let doc = self.owner_doc();
let window = doc.r().window(); let window = doc.r().window();
NodeList::new_child_list(window.r(), self) NodeList::new_child_list(window, self)
}) })
} }
@ -2391,7 +2391,7 @@ pub fn document_from_node<T: NodeBase + Reflectable>(derived: &T) -> Root<Docume
pub fn window_from_node<T: NodeBase + Reflectable>(derived: &T) -> Root<Window> { pub fn window_from_node<T: NodeBase + Reflectable>(derived: &T) -> Root<Window> {
let document = document_from_node(derived); let document = document_from_node(derived);
document.r().window() Root::from_ref(document.r().window())
} }
impl VirtualMethods for Node { impl VirtualMethods for Node {

View file

@ -47,9 +47,8 @@ impl NodeIterator {
root_node: &Node, root_node: &Node,
what_to_show: u32, what_to_show: u32,
filter: Filter) -> Root<NodeIterator> { filter: Filter) -> Root<NodeIterator> {
let window = document.window();
reflect_dom_object(box NodeIterator::new_inherited(root_node, what_to_show, filter), reflect_dom_object(box NodeIterator::new_inherited(root_node, what_to_show, filter),
GlobalRef::Window(window.r()), GlobalRef::Window(document.window()),
NodeIteratorBinding::Wrap) NodeIteratorBinding::Wrap)
} }
@ -122,7 +121,7 @@ impl NodeIteratorMethods for NodeIterator {
} }
// Step 3-1. // Step 3-1.
for following_node in node.r().following_nodes(self.root_node.root().r()) { for following_node in node.r().following_nodes(&self.root_node) {
// Step 3-2. // Step 3-2.
let result = try!(self.accept_node(following_node.r())); let result = try!(self.accept_node(following_node.r()));
@ -166,7 +165,7 @@ impl NodeIteratorMethods for NodeIterator {
} }
// Step 3-1. // Step 3-1.
for preceding_node in node.r().preceding_nodes(self.root_node.root().r()) { for preceding_node in node.r().preceding_nodes(&self.root_node) {
// Step 3-2. // Step 3-2.
let result = try!(self.accept_node(preceding_node.r())); let result = try!(self.accept_node(preceding_node.r()));

View file

@ -109,7 +109,7 @@ impl ChildrenList {
} }
pub fn len(&self) -> u32 { pub fn len(&self) -> u32 {
self.node.root().children_count() self.node.children_count()
} }
pub fn item(&self, index: u32) -> Option<Root<Node>> { pub fn item(&self, index: u32) -> Option<Root<Node>> {
@ -121,7 +121,7 @@ impl ChildrenList {
} }
if index == 0u32 { if index == 0u32 {
// Item is first child if any, not worth updating last visited. // Item is first child if any, not worth updating last visited.
return self.node.root().GetFirstChild(); return self.node.GetFirstChild();
} }
let last_index = self.last_index.get(); let last_index = self.last_index.get();
if index == last_index { if index == last_index {
@ -137,7 +137,7 @@ impl ChildrenList {
} else if index > last_index { } else if index > last_index {
if index == len - 1u32 { if index == len - 1u32 {
// Item is parent's last child, not worth updating last visited. // Item is parent's last child, not worth updating last visited.
return Some(self.node.root().GetLastChild().unwrap()); return Some(self.node.GetLastChild().unwrap());
} }
if index <= last_index + (len - last_index) / 2u32 { if index <= last_index + (len - last_index) / 2u32 {
// Item is closer to the last visited child and follows it. // Item is closer to the last visited child and follows it.
@ -147,7 +147,7 @@ impl ChildrenList {
} else { } else {
// Item is closer to parent's last child and obviously // Item is closer to parent's last child and obviously
// precedes it. // precedes it.
self.node.root().GetLastChild().unwrap() self.node.GetLastChild().unwrap()
.inclusively_preceding_siblings() .inclusively_preceding_siblings()
.nth((len - index - 1u32) as usize).unwrap() .nth((len - index - 1u32) as usize).unwrap()
} }
@ -159,7 +159,7 @@ impl ChildrenList {
} else { } else {
// Item is closer to parent's first child and obviously follows it. // Item is closer to parent's first child and obviously follows it.
debug_assert!(index < last_index / 2u32); debug_assert!(index < last_index / 2u32);
self.node.root().GetFirstChild().unwrap() self.node.GetFirstChild().unwrap()
.inclusively_following_siblings() .inclusively_following_siblings()
.nth(index as usize) .nth(index as usize)
.unwrap() .unwrap()
@ -263,7 +263,7 @@ impl ChildrenList {
} }
fn reset(&self) { fn reset(&self) {
self.last_visited.set(self.node.root().GetFirstChild().as_ref().map(Root::r)); self.last_visited.set(self.node.GetFirstChild().r());
self.last_index.set(0u32); self.last_index.set(0u32);
} }
} }

View file

@ -51,7 +51,7 @@ impl PerformanceMethods for Performance {
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now
fn Now(&self) -> DOMHighResTimeStamp { fn Now(&self) -> DOMHighResTimeStamp {
let navStart = self.timing.root().r().NavigationStartPrecise(); let navStart = self.timing.NavigationStartPrecise();
let now = (time::precise_time_ns() as f64 - navStart) / 1000000 as f64; let now = (time::precise_time_ns() as f64 - navStart) / 1000000 as f64;
Finite::wrap(now) Finite::wrap(now)
} }

View file

@ -49,10 +49,9 @@ impl Range {
start_container: &Node, start_offset: u32, start_container: &Node, start_offset: u32,
end_container: &Node, end_offset: u32) end_container: &Node, end_offset: u32)
-> Root<Range> { -> Root<Range> {
let window = document.window();
reflect_dom_object(box Range::new_inherited(start_container, start_offset, reflect_dom_object(box Range::new_inherited(start_container, start_offset,
end_container, end_offset), end_container, end_offset),
GlobalRef::Window(window.r()), GlobalRef::Window(document.window()),
RangeBinding::Wrap) RangeBinding::Wrap)
} }

View file

@ -15,7 +15,7 @@ use dom::bindings::refcounted::Trusted;
use dom::bindings::trace::JSTraceable; use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::Document; use dom::document::Document;
use dom::node::{Node, window_from_node}; use dom::node::Node;
use dom::text::Text; use dom::text::Text;
use dom::window::Window; use dom::window::Window;
use encoding::all::UTF_8; use encoding::all::UTF_8;
@ -48,8 +48,7 @@ impl Sink {
match child { match child {
NodeOrText::AppendNode(n) => n.root(), NodeOrText::AppendNode(n) => n.root(),
NodeOrText::AppendText(t) => { NodeOrText::AppendText(t) => {
let doc = self.document.root(); let text = Text::new(t.into(), &self.document);
let text = Text::new(t.into(), &doc);
NodeCast::from_root(text) NodeCast::from_root(text)
} }
} }
@ -109,7 +108,7 @@ impl AsyncResponseListener for ParserContext {
let parser = parser.r(); let parser = parser.r();
let win = parser.window(); let win = parser.window();
self.parser = Some(Trusted::new(win.r().get_cx(), parser, self.script_chan.clone())); self.parser = Some(Trusted::new(win.get_cx(), parser, self.script_chan.clone()));
match content_type { match content_type {
Some(ContentType(Mime(TopLevel::Image, _, _))) => { Some(ContentType(Mime(TopLevel::Image, _, _))) => {
@ -153,8 +152,7 @@ impl AsyncResponseListener for ParserContext {
Some(parser) => parser.root(), Some(parser) => parser.root(),
None => return, None => return,
}; };
let doc = parser.r().document.root(); parser.document.finish_load(LoadType::PageSource(self.url.clone()));
doc.r().finish_load(LoadType::PageSource(self.url.clone()));
if let Err(err) = status { if let Err(err) = status {
debug!("Failed to load page URL {}, error: {}", self.url.serialize(), err); debug!("Failed to load page URL {}, error: {}", self.url.serialize(), err);
@ -189,7 +187,7 @@ pub struct ServoHTMLParser {
impl<'a> Parser for &'a ServoHTMLParser { impl<'a> Parser for &'a ServoHTMLParser {
fn parse_chunk(self, input: String) { fn parse_chunk(self, input: String) {
self.document.root().r().set_current_parser(Some(self)); self.document.set_current_parser(Some(self));
self.pending_input.borrow_mut().push(input); self.pending_input.borrow_mut().push(input);
self.parse_sync(); self.parse_sync();
} }
@ -201,8 +199,7 @@ impl<'a> Parser for &'a ServoHTMLParser {
self.tokenizer().borrow_mut().end(); self.tokenizer().borrow_mut().end();
debug!("finished parsing"); debug!("finished parsing");
let document = self.document.root(); self.document.set_current_parser(None);
document.r().set_current_parser(None);
if let Some(pipeline) = self.pipeline { if let Some(pipeline) = self.pipeline {
ScriptTask::parsing_complete(pipeline); ScriptTask::parsing_complete(pipeline);
@ -214,7 +211,6 @@ impl ServoHTMLParser {
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
pub fn new(base_url: Option<Url>, document: &Document, pipeline: Option<PipelineId>) pub fn new(base_url: Option<Url>, document: &Document, pipeline: Option<PipelineId>)
-> Root<ServoHTMLParser> { -> Root<ServoHTMLParser> {
let window = document.window();
let sink = Sink { let sink = Sink {
base_url: base_url, base_url: base_url,
document: JS::from_ref(document), document: JS::from_ref(document),
@ -237,14 +233,13 @@ impl ServoHTMLParser {
pipeline: pipeline, pipeline: pipeline,
}; };
reflect_dom_object(box parser, GlobalRef::Window(window.r()), reflect_dom_object(box parser, GlobalRef::Window(document.window()),
ServoHTMLParserBinding::Wrap) ServoHTMLParserBinding::Wrap)
} }
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
pub fn new_for_fragment(base_url: Option<Url>, document: &Document, pub fn new_for_fragment(base_url: Option<Url>, document: &Document,
fragment_context: FragmentContext) -> Root<ServoHTMLParser> { fragment_context: FragmentContext) -> Root<ServoHTMLParser> {
let window = document.window();
let sink = Sink { let sink = Sink {
base_url: base_url, base_url: base_url,
document: JS::from_ref(document), document: JS::from_ref(document),
@ -275,7 +270,7 @@ impl ServoHTMLParser {
pipeline: None, pipeline: None,
}; };
reflect_dom_object(box parser, GlobalRef::Window(window.r()), reflect_dom_object(box parser, GlobalRef::Window(document.window()),
ServoHTMLParserBinding::Wrap) ServoHTMLParserBinding::Wrap)
} }
@ -301,8 +296,7 @@ impl ServoHTMLParser {
break; break;
} }
let document = self.document.root(); self.document.reflow_if_reflow_timer_expired();
document.r().reflow_if_reflow_timer_expired();
let mut pending_input = self.pending_input.borrow_mut(); let mut pending_input = self.pending_input.borrow_mut();
if !pending_input.is_empty() { if !pending_input.is_empty() {
@ -320,9 +314,8 @@ impl ServoHTMLParser {
} }
} }
fn window(&self) -> Root<Window> { fn window(&self) -> &Window {
let doc = self.document.root(); self.document.window()
window_from_node(doc.r())
} }
} }

View file

@ -45,9 +45,8 @@ impl TreeWalker {
root_node: &Node, root_node: &Node,
what_to_show: u32, what_to_show: u32,
filter: Filter) -> Root<TreeWalker> { filter: Filter) -> Root<TreeWalker> {
let window = document.window();
reflect_dom_object(box TreeWalker::new_inherited(root_node, what_to_show, filter), reflect_dom_object(box TreeWalker::new_inherited(root_node, what_to_show, filter),
GlobalRef::Window(window.r()), GlobalRef::Window(document.window()),
TreeWalkerBinding::Wrap) TreeWalkerBinding::Wrap)
} }

View file

@ -381,7 +381,7 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#dom-document-0 // https://html.spec.whatwg.org/multipage/#dom-document-0
fn Document(&self) -> Root<Document> { fn Document(&self) -> Root<Document> {
self.browsing_context().as_ref().unwrap().active_document() Root::from_ref(self.browsing_context().as_ref().unwrap().active_document())
} }
// https://html.spec.whatwg.org/multipage/#dom-location // https://html.spec.whatwg.org/multipage/#dom-location
@ -411,7 +411,7 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#dom-frameelement // https://html.spec.whatwg.org/multipage/#dom-frameelement
fn GetFrameElement(&self) -> Option<Root<Element>> { fn GetFrameElement(&self) -> Option<Root<Element>> {
self.browsing_context().as_ref().unwrap().frame_element() self.browsing_context().as_ref().unwrap().frame_element().map(Root::from_ref)
} }
// https://html.spec.whatwg.org/multipage/#dom-navigator // https://html.spec.whatwg.org/multipage/#dom-navigator
@ -1248,11 +1248,11 @@ impl Window {
let browsing_context = browsing_context.as_ref().unwrap(); let browsing_context = browsing_context.as_ref().unwrap();
browsing_context.frame_element().map(|frame_element| { browsing_context.frame_element().map(|frame_element| {
let window = window_from_node(frame_element.r()); let window = window_from_node(frame_element);
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let r = window.r(); let r = window.r();
let context = r.browsing_context(); let context = r.browsing_context();
context.as_ref().unwrap().active_window() Root::from_ref(context.as_ref().unwrap().active_window())
}) })
} }
} }

View file

@ -493,8 +493,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
if !self.sync.get() { if !self.sync.get() {
// Step 8 // Step 8
let upload_target = self.upload.root(); let event_target = EventTargetCast::from_ref(&*self.upload);
let event_target = EventTargetCast::from_ref(upload_target.r());
if event_target.has_handlers() { if event_target.has_handlers() {
self.upload_events.set(true); self.upload_events.set(true);
} }
@ -917,13 +916,12 @@ impl XMLHttpRequest {
fn dispatch_progress_event(&self, upload: bool, type_: DOMString, loaded: u64, total: Option<u64>) { fn dispatch_progress_event(&self, upload: bool, type_: DOMString, loaded: u64, total: Option<u64>) {
let global = self.global.root(); let global = self.global.root();
let upload_target = self.upload.root();
let progressevent = ProgressEvent::new(global.r(), let progressevent = ProgressEvent::new(global.r(),
type_, EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, type_, EventBubbles::DoesNotBubble, EventCancelable::NotCancelable,
total.is_some(), loaded, total.is_some(), loaded,
total.unwrap_or(0)); total.unwrap_or(0));
let target = if upload { let target = if upload {
EventTargetCast::from_ref(upload_target.r()) EventTargetCast::from_ref(&*self.upload)
} else { } else {
EventTargetCast::from_ref(self) EventTargetCast::from_ref(self)
}; };