mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
auto merge of #2490 : saneyuki/servo/js, r=jdm
This only change to make `JS<T> ` to a POD type about #1854, except using `Cell`/`RefCell` for interior mutability. Fix #1854 @jdm r?
This commit is contained in:
commit
e511c04935
20 changed files with 212 additions and 161 deletions
|
@ -136,6 +136,10 @@ pub struct LayoutNode<'a> {
|
|||
|
||||
/// Being chained to a ContravariantLifetime prevents `LayoutNode`s from escaping.
|
||||
pub chain: ContravariantLifetime<'a>,
|
||||
|
||||
/// Padding to ensure the transmute `JS<T>` -> `LayoutNode`, `LayoutNode` -> `UnsafeLayoutNode`,
|
||||
/// and `UnsafeLayoutNode` -> others.
|
||||
pad: uint
|
||||
}
|
||||
|
||||
impl<'ln> Clone for LayoutNode<'ln> {
|
||||
|
@ -143,6 +147,7 @@ impl<'ln> Clone for LayoutNode<'ln> {
|
|||
LayoutNode {
|
||||
node: self.node.clone(),
|
||||
chain: self.chain,
|
||||
pad: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,6 +165,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
|
|||
LayoutNode {
|
||||
node: node.transmute_copy(),
|
||||
chain: self.chain,
|
||||
pad: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +181,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
|
|||
|
||||
fn first_child(&self) -> Option<LayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,6 +202,7 @@ impl<'ln> LayoutNode<'ln> {
|
|||
f(LayoutNode {
|
||||
node: node,
|
||||
chain: ContravariantLifetime,
|
||||
pad: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -223,19 +230,19 @@ impl<'ln> LayoutNode<'ln> {
|
|||
impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
|
||||
fn parent_node(&self) -> Option<LayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
fn prev_sibling(&self) -> Option<LayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
fn next_sibling(&self) -> Option<LayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,6 +432,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
|
|||
node: LayoutNode {
|
||||
node: node.transmute_copy(),
|
||||
chain: self.node.chain,
|
||||
pad: 0,
|
||||
},
|
||||
pseudo: Normal,
|
||||
}
|
||||
|
@ -463,7 +471,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,10 +521,10 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
|||
/// Returns the next sibling of this node. Unsafe and private because this can lead to races.
|
||||
unsafe fn next_sibling(&self) -> Option<ThreadSafeLayoutNode<'ln>> {
|
||||
if self.pseudo == Before || self.pseudo == BeforeBlock {
|
||||
return self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
return self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
|
||||
self.get_jsmanaged().next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
|
||||
self.get_jsmanaged().next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
|
||||
/// Returns an iterator over this node's children.
|
||||
|
|
|
@ -13,6 +13,7 @@ use dom::virtualmethods::vtable_for;
|
|||
use servo_util::namespace;
|
||||
use servo_util::namespace::Namespace;
|
||||
use servo_util::str::DOMString;
|
||||
use std::cell::Cell;
|
||||
|
||||
pub enum AttrSettingType {
|
||||
FirstSetAttr,
|
||||
|
@ -29,7 +30,7 @@ pub struct Attr {
|
|||
pub prefix: Option<DOMString>,
|
||||
|
||||
/// the element that owns this attribute.
|
||||
pub owner: JS<Element>,
|
||||
pub owner: Cell<JS<Element>>,
|
||||
}
|
||||
|
||||
impl Reflectable for Attr {
|
||||
|
@ -53,7 +54,7 @@ impl Attr {
|
|||
name: name, //TODO: Intern attribute names
|
||||
namespace: namespace,
|
||||
prefix: prefix,
|
||||
owner: owner.unrooted(),
|
||||
owner: Cell::new(owner.unrooted()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +66,7 @@ impl Attr {
|
|||
}
|
||||
|
||||
pub fn set_value(&mut self, set_type: AttrSettingType, value: DOMString) {
|
||||
let mut owner = self.owner.root();
|
||||
let mut owner = self.owner.get().root();
|
||||
let node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *owner);
|
||||
let namespace_is_null = self.namespace == namespace::Null;
|
||||
|
||||
|
|
|
@ -39,11 +39,11 @@ pub trait AttrListMethods {
|
|||
|
||||
impl<'a> AttrListMethods for JSRef<'a, AttrList> {
|
||||
fn Length(&self) -> u32 {
|
||||
self.owner.root().attrs.len() as u32
|
||||
self.owner.root().attrs.borrow().len() as u32
|
||||
}
|
||||
|
||||
fn Item(&self, index: u32) -> Option<Temporary<Attr>> {
|
||||
self.owner.root().attrs.as_slice().get(index as uint).map(|x| Temporary::new(x.clone()))
|
||||
self.owner.root().attrs.borrow().as_slice().get(index as uint).map(|x| Temporary::new(x.clone()))
|
||||
}
|
||||
|
||||
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Attr>> {
|
||||
|
|
|
@ -47,7 +47,7 @@ use layout_interface::TrustedNodeAddress;
|
|||
use script_task::StackRoots;
|
||||
|
||||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::kinds::marker::ContravariantLifetime;
|
||||
|
||||
/// A type that represents a JS-owned value that is rooted for the lifetime of this value.
|
||||
|
@ -111,7 +111,7 @@ impl<T: Reflectable> Temporary<T> {
|
|||
|
||||
/// A rooted, JS-owned value. Must only be used as a field in other JS-owned types.
|
||||
pub struct JS<T> {
|
||||
ptr: RefCell<*mut T>
|
||||
ptr: *T
|
||||
}
|
||||
|
||||
impl<T> Eq for JS<T> {
|
||||
|
@ -134,7 +134,7 @@ impl JS<Node> {
|
|||
pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<Node> {
|
||||
let TrustedNodeAddress(addr) = inner;
|
||||
JS {
|
||||
ptr: RefCell::new(addr as *mut Node)
|
||||
ptr: addr as *Node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl JS<XMLHttpRequest> {
|
|||
pub unsafe fn from_trusted_xhr_address(inner: TrustedXHRAddress) -> JS<XMLHttpRequest> {
|
||||
let TrustedXHRAddress(addr) = inner;
|
||||
JS {
|
||||
ptr: RefCell::new(addr as *mut XMLHttpRequest)
|
||||
ptr: addr as *XMLHttpRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ impl<T: Reflectable> JS<T> {
|
|||
/// Create a new JS-owned value wrapped from a raw Rust pointer.
|
||||
pub unsafe fn from_raw(raw: *mut T) -> JS<T> {
|
||||
JS {
|
||||
ptr: RefCell::new(raw)
|
||||
ptr: raw as *T
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,15 @@ impl<T: Assignable<U>, U: Reflectable> OptionalSettable<T> for Option<JS<U>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Assignable<U>, U: Reflectable> OptionalSettable<T> for Cell<Option<JS<U>>> {
|
||||
fn assign(&mut self, val: Option<T>) {
|
||||
let mut item = self.get();
|
||||
item.assign(val);
|
||||
self.set(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Root a rootable Option type (used for Option<Temporary<T>>)
|
||||
pub trait OptionalRootable<T> {
|
||||
fn root<'a, 'b>(self) -> Option<Root<'a, 'b, T>>;
|
||||
|
@ -394,7 +403,7 @@ pub struct Root<'a, 'b, T> {
|
|||
/// Reference to rooted value that must not outlive this container
|
||||
jsref: JSRef<'b, T>,
|
||||
/// Pointer to underlying Rust data
|
||||
ptr: RefCell<*mut T>,
|
||||
ptr: *T,
|
||||
/// On-stack JS pointer to assuage conservative stack scanner
|
||||
js_ptr: *mut JSObject,
|
||||
}
|
||||
|
@ -445,25 +454,23 @@ impl<'a, 'b, T: Reflectable> DerefMut<JSRef<'b, T>> for Root<'a, 'b, T> {
|
|||
|
||||
impl<'a, T: Reflectable> Deref<T> for JSRef<'a, T> {
|
||||
fn deref<'b>(&'b self) -> &'b T {
|
||||
let borrow = self.ptr.borrow();
|
||||
unsafe {
|
||||
&**borrow
|
||||
&*self.ptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Reflectable> DerefMut<T> for JSRef<'a, T> {
|
||||
fn deref_mut<'b>(&'b mut self) -> &'b mut T {
|
||||
let mut borrowed = self.ptr.borrow_mut();
|
||||
unsafe {
|
||||
&mut **borrowed
|
||||
&mut *(self.ptr as *mut T)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Encapsulates a reference to something that is guaranteed to be alive. This is freely copyable.
|
||||
pub struct JSRef<'a, T> {
|
||||
ptr: RefCell<*mut T>,
|
||||
ptr: *T,
|
||||
chain: ContravariantLifetime<'a>,
|
||||
}
|
||||
|
||||
|
@ -495,7 +502,7 @@ impl<'a,T> JSRef<'a,T> {
|
|||
|
||||
pub fn unrooted(&self) -> JS<T> {
|
||||
JS {
|
||||
ptr: self.ptr.clone()
|
||||
ptr: self.ptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,3 +160,23 @@ impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<JSVal> {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// for a field which contains DOMType
|
||||
impl<T: Reflectable+Encodable<S, E>, S: Encoder<E>, E> Encodable<S, E> for Cell<JS<T>> {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
self.get().encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable+Encodable<S, E>, S: Encoder<E>, E> Encodable<S, E> for Cell<Option<JS<T>>> {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
self.get().encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// for a field which contains non-POD type contains DOMType
|
||||
impl<T: Reflectable+Encodable<S, E>, S: Encoder<E>, E> Encodable<S, E> for RefCell<Vec<JS<T>>> {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
self.borrow().encode(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@ pub struct ClientRectList {
|
|||
impl ClientRectList {
|
||||
pub fn new_inherited(window: &JSRef<Window>,
|
||||
rects: Vec<JSRef<ClientRect>>) -> ClientRectList {
|
||||
let rects = rects.iter().map(|rect| rect.unrooted()).collect();
|
||||
ClientRectList {
|
||||
reflector_: Reflector::new(),
|
||||
rects: rects.iter().map(|rect| rect.unrooted()).collect(),
|
||||
rects: rects,
|
||||
window: window.unrooted(),
|
||||
}
|
||||
}
|
||||
|
@ -44,8 +45,9 @@ impl<'a> ClientRectListMethods for JSRef<'a, ClientRectList> {
|
|||
}
|
||||
|
||||
fn Item(&self, index: u32) -> Option<Temporary<ClientRect>> {
|
||||
if index < self.rects.len() as u32 {
|
||||
Some(Temporary::new(self.rects.get(index as uint).clone()))
|
||||
let rects = &self.rects;
|
||||
if index < rects.len() as u32 {
|
||||
Some(Temporary::new(rects.get(index as uint).clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ use servo_util::str::{DOMString, null_str_as_empty_ref, split_html_space_chars};
|
|||
|
||||
use std::ascii::StrAsciiExt;
|
||||
use std::cast;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct Element {
|
||||
|
@ -38,9 +39,9 @@ pub struct Element {
|
|||
pub local_name: DOMString, // TODO: This should be an atom, not a DOMString.
|
||||
pub namespace: Namespace,
|
||||
pub prefix: Option<DOMString>,
|
||||
pub attrs: Vec<JS<Attr>>,
|
||||
pub attrs: RefCell<Vec<JS<Attr>>>,
|
||||
pub style_attribute: Option<style::PropertyDeclarationBlock>,
|
||||
pub attr_list: Option<JS<AttrList>>
|
||||
pub attr_list: Cell<Option<JS<AttrList>>>
|
||||
}
|
||||
|
||||
impl ElementDerived for EventTarget {
|
||||
|
@ -147,8 +148,8 @@ impl Element {
|
|||
local_name: local_name,
|
||||
namespace: namespace,
|
||||
prefix: prefix,
|
||||
attrs: vec!(),
|
||||
attr_list: None,
|
||||
attrs: RefCell::new(vec!()),
|
||||
attr_list: Cell::new(None),
|
||||
style_attribute: None,
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +168,9 @@ impl RawLayoutElementHelpers for Element {
|
|||
#[inline]
|
||||
unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str)
|
||||
-> Option<&'static str> {
|
||||
self.attrs.iter().find(|attr: & &JS<Attr>| {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let attrs: *Vec<JS<Attr>> = cast::transmute(&self.attrs);
|
||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||
let attr = attr.unsafe_get();
|
||||
name == (*attr).local_name && (*attr).namespace == *namespace
|
||||
}).map(|attr| {
|
||||
|
@ -232,7 +235,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
let element: &Element = self.deref();
|
||||
let is_html_element = self.html_element_in_html_document();
|
||||
|
||||
element.attrs.iter().map(|attr| attr.root()).find(|attr| {
|
||||
element.attrs.borrow().iter().map(|attr| attr.root()).find(|attr| {
|
||||
let same_name = if is_html_element {
|
||||
name.to_ascii_lower() == attr.local_name
|
||||
} else {
|
||||
|
@ -284,7 +287,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString,
|
||||
name: DOMString, namespace: Namespace,
|
||||
prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) {
|
||||
let idx = self.deref().attrs.iter()
|
||||
let idx = self.deref().attrs.borrow().iter()
|
||||
.map(|attr| attr.root())
|
||||
.position(|attr| cb(&*attr));
|
||||
let (idx, set_type) = match idx {
|
||||
|
@ -293,18 +296,18 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
let window = window_from_node(self).root();
|
||||
let attr = Attr::new(&*window, local_name.clone(), value.clone(),
|
||||
name, namespace.clone(), prefix, self);
|
||||
self.deref_mut().attrs.push_unrooted(&attr);
|
||||
(self.deref().attrs.len() - 1, FirstSetAttr)
|
||||
self.deref().attrs.borrow_mut().push_unrooted(&attr);
|
||||
(self.deref().attrs.borrow().len() - 1, FirstSetAttr)
|
||||
}
|
||||
};
|
||||
|
||||
self.deref_mut().attrs.get(idx).root().set_value(set_type, value);
|
||||
self.deref().attrs.borrow().get(idx).root().set_value(set_type, value);
|
||||
}
|
||||
|
||||
fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult {
|
||||
let (_, local_name) = get_attribute_parts(name.clone());
|
||||
|
||||
let idx = self.deref().attrs.iter().map(|attr| attr.root()).position(|attr| {
|
||||
let idx = self.deref().attrs.borrow().iter().map(|attr| attr.root()).position(|attr| {
|
||||
attr.local_name == local_name
|
||||
});
|
||||
|
||||
|
@ -317,12 +320,12 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
}
|
||||
|
||||
if namespace == namespace::Null {
|
||||
let removed_raw_value = self.deref().attrs.get(idx).root().Value();
|
||||
let removed_raw_value = self.deref().attrs.borrow().get(idx).root().Value();
|
||||
vtable_for(NodeCast::from_mut_ref(self))
|
||||
.before_remove_attr(local_name.clone(), removed_raw_value);
|
||||
}
|
||||
|
||||
self.deref_mut().attrs.remove(idx);
|
||||
self.deref().attrs.borrow_mut().remove(idx);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -469,7 +472,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-element-attributes
|
||||
fn Attributes(&mut self) -> Temporary<AttrList> {
|
||||
match self.attr_list {
|
||||
match self.attr_list.get() {
|
||||
None => (),
|
||||
Some(ref list) => return Temporary::new(list.clone()),
|
||||
}
|
||||
|
@ -481,7 +484,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
let window = doc.deref().window.root();
|
||||
let list = AttrList::new(&*window, self);
|
||||
self.attr_list.assign(Some(list));
|
||||
Temporary::new(self.attr_list.get_ref().clone())
|
||||
Temporary::new(self.attr_list.get().get_ref().clone())
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-element-getattribute
|
||||
|
|
|
@ -10,6 +10,7 @@ use dom::bindings::error::Fallible;
|
|||
use dom::eventtarget::EventTarget;
|
||||
use dom::window::Window;
|
||||
use servo_util::str::DOMString;
|
||||
use std::cell::Cell;
|
||||
|
||||
use geom::point::Point2D;
|
||||
|
||||
|
@ -46,8 +47,8 @@ pub enum EventTypeId {
|
|||
pub struct Event {
|
||||
pub type_id: EventTypeId,
|
||||
pub reflector_: Reflector,
|
||||
pub current_target: Option<JS<EventTarget>>,
|
||||
pub target: Option<JS<EventTarget>>,
|
||||
pub current_target: Cell<Option<JS<EventTarget>>>,
|
||||
pub target: Cell<Option<JS<EventTarget>>>,
|
||||
pub type_: DOMString,
|
||||
pub phase: EventPhase,
|
||||
pub canceled: bool,
|
||||
|
@ -66,8 +67,8 @@ impl Event {
|
|||
Event {
|
||||
type_id: type_id,
|
||||
reflector_: Reflector::new(),
|
||||
current_target: None,
|
||||
target: None,
|
||||
current_target: Cell::new(None),
|
||||
target: Cell::new(None),
|
||||
phase: PhaseNone,
|
||||
type_: "".to_owned(),
|
||||
canceled: false,
|
||||
|
@ -123,11 +124,11 @@ impl<'a> EventMethods for JSRef<'a, Event> {
|
|||
}
|
||||
|
||||
fn GetTarget(&self) -> Option<Temporary<EventTarget>> {
|
||||
self.target.as_ref().map(|target| Temporary::new(target.clone()))
|
||||
self.target.get().as_ref().map(|target| Temporary::new(target.clone()))
|
||||
}
|
||||
|
||||
fn GetCurrentTarget(&self) -> Option<Temporary<EventTarget>> {
|
||||
self.current_target.as_ref().map(|target| Temporary::new(target.clone()))
|
||||
self.current_target.get().as_ref().map(|target| Temporary::new(target.clone()))
|
||||
}
|
||||
|
||||
fn DefaultPrevented(&self) -> bool {
|
||||
|
@ -173,7 +174,7 @@ impl<'a> EventMethods for JSRef<'a, Event> {
|
|||
self.stop_immediate = false;
|
||||
self.canceled = false;
|
||||
self.trusted = false;
|
||||
self.target = None;
|
||||
self.target.set(None);
|
||||
self.type_ = type_;
|
||||
self.bubbles = bubbles;
|
||||
self.cancelable = cancelable;
|
||||
|
|
|
@ -140,7 +140,7 @@ pub fn dispatch_event<'a, 'b>(target: &JSRef<'a, EventTarget>,
|
|||
|
||||
event.dispatching = false;
|
||||
event.phase = PhaseNone;
|
||||
event.current_target = None;
|
||||
event.current_target.set(None);
|
||||
|
||||
!event.DefaultPrevented()
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use dom::blob::Blob;
|
|||
use dom::htmlformelement::HTMLFormElement;
|
||||
use dom::window::Window;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use collections::hashmap::HashMap;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
|
|
|
@ -106,7 +106,7 @@ fn serialize_doctype(doctype: &JSRef<DocumentType>, html: &mut StrBuf) {
|
|||
fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>, html: &mut StrBuf) {
|
||||
html.push_char('<');
|
||||
html.push_str(elem.deref().local_name);
|
||||
for attr in elem.deref().attrs.iter() {
|
||||
for attr in elem.deref().attrs.borrow().iter() {
|
||||
let attr = attr.root();
|
||||
serialize_attr(&*attr, html);
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ use dom::eventtarget::EventTarget;
|
|||
use dom::uievent::{UIEvent, UIEventMethods};
|
||||
use dom::window::Window;
|
||||
use servo_util::str::DOMString;
|
||||
use std::cell::Cell;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct MouseEvent {
|
||||
|
@ -25,7 +26,7 @@ pub struct MouseEvent {
|
|||
pub alt_key: bool,
|
||||
pub meta_key: bool,
|
||||
pub button: u16,
|
||||
pub related_target: Option<JS<EventTarget>>
|
||||
pub related_target: Cell<Option<JS<EventTarget>>>
|
||||
}
|
||||
|
||||
impl MouseEventDerived for Event {
|
||||
|
@ -47,7 +48,7 @@ impl MouseEvent {
|
|||
alt_key: false,
|
||||
meta_key: false,
|
||||
button: 0,
|
||||
related_target: None
|
||||
related_target: Cell::new(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,7 +169,7 @@ impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> {
|
|||
}
|
||||
|
||||
fn GetRelatedTarget(&self) -> Option<Temporary<EventTarget>> {
|
||||
self.related_target.clone().map(|target| Temporary::new(target))
|
||||
self.related_target.get().clone().map(|target| Temporary::new(target))
|
||||
}
|
||||
|
||||
fn GetModifierState(&self, _keyArg: DOMString) -> bool {
|
||||
|
|
|
@ -41,7 +41,7 @@ use libc;
|
|||
use libc::uintptr_t;
|
||||
use std::cast::transmute;
|
||||
use std::cast;
|
||||
use std::cell::{RefCell, Ref, RefMut};
|
||||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
use std::iter::{Map, Filter};
|
||||
use std::mem;
|
||||
use style::ComputedValues;
|
||||
|
@ -63,25 +63,25 @@ pub struct Node {
|
|||
pub type_id: NodeTypeId,
|
||||
|
||||
/// The parent of this node.
|
||||
pub parent_node: Option<JS<Node>>,
|
||||
pub parent_node: Cell<Option<JS<Node>>>,
|
||||
|
||||
/// The first child of this node.
|
||||
pub first_child: Option<JS<Node>>,
|
||||
pub first_child: Cell<Option<JS<Node>>>,
|
||||
|
||||
/// The last child of this node.
|
||||
pub last_child: Option<JS<Node>>,
|
||||
pub last_child: Cell<Option<JS<Node>>>,
|
||||
|
||||
/// The next sibling of this node.
|
||||
pub next_sibling: Option<JS<Node>>,
|
||||
pub next_sibling: Cell<Option<JS<Node>>>,
|
||||
|
||||
/// The previous sibling of this node.
|
||||
pub prev_sibling: Option<JS<Node>>,
|
||||
pub prev_sibling: Cell<Option<JS<Node>>>,
|
||||
|
||||
/// The document that this node belongs to.
|
||||
owner_doc: Option<JS<Document>>,
|
||||
owner_doc: Cell<Option<JS<Document>>>,
|
||||
|
||||
/// The live list of children return by .childNodes.
|
||||
pub child_list: Option<JS<NodeList>>,
|
||||
pub child_list: Cell<Option<JS<NodeList>>>,
|
||||
|
||||
/// A bitfield of flags for node items.
|
||||
flags: NodeFlags,
|
||||
|
@ -327,26 +327,26 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> {
|
|||
///
|
||||
/// Fails unless `child` is a child of this node. (FIXME: This is not yet checked.)
|
||||
fn remove_child(&mut self, child: &mut JSRef<Node>) {
|
||||
assert!(child.parent_node.is_some());
|
||||
assert!(child.parent_node.get().is_some());
|
||||
|
||||
match child.prev_sibling.root() {
|
||||
match child.prev_sibling.get().root() {
|
||||
None => {
|
||||
let next_sibling = child.next_sibling.root();
|
||||
let next_sibling = child.next_sibling.get().root();
|
||||
self.set_first_child(next_sibling.root_ref());
|
||||
}
|
||||
Some(ref mut prev_sibling) => {
|
||||
let next_sibling = child.next_sibling.root();
|
||||
let next_sibling = child.next_sibling.get().root();
|
||||
prev_sibling.set_next_sibling(next_sibling.root_ref());
|
||||
}
|
||||
}
|
||||
|
||||
match child.next_sibling.root() {
|
||||
match child.next_sibling.get().root() {
|
||||
None => {
|
||||
let prev_sibling = child.prev_sibling.root();
|
||||
let prev_sibling = child.prev_sibling.get().root();
|
||||
self.set_last_child(prev_sibling.root_ref());
|
||||
}
|
||||
Some(ref mut next_sibling) => {
|
||||
let prev_sibling = child.prev_sibling.root();
|
||||
let prev_sibling = child.prev_sibling.get().root();
|
||||
next_sibling.set_prev_sibling(prev_sibling.root_ref());
|
||||
}
|
||||
}
|
||||
|
@ -475,25 +475,25 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
|
|||
}
|
||||
|
||||
fn parent_node(&self) -> Option<Temporary<Node>> {
|
||||
self.deref().parent_node.clone().map(|node| Temporary::new(node))
|
||||
self.deref().parent_node.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
fn first_child(&self) -> Option<Temporary<Node>> {
|
||||
self.deref().first_child.clone().map(|node| Temporary::new(node))
|
||||
self.deref().first_child.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
fn last_child(&self) -> Option<Temporary<Node>> {
|
||||
self.deref().last_child.clone().map(|node| Temporary::new(node))
|
||||
self.deref().last_child.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
/// Returns the previous sibling of this node. Fails if this node is borrowed mutably.
|
||||
fn prev_sibling(&self) -> Option<Temporary<Node>> {
|
||||
self.deref().prev_sibling.clone().map(|node| Temporary::new(node))
|
||||
self.deref().prev_sibling.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
/// Returns the next sibling of this node. Fails if this node is borrowed mutably.
|
||||
fn next_sibling(&self) -> Option<Temporary<Node>> {
|
||||
self.deref().next_sibling.clone().map(|node| Temporary::new(node))
|
||||
self.deref().next_sibling.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -593,12 +593,12 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
|
|||
|
||||
fn ancestors(&self) -> AncestorIterator {
|
||||
AncestorIterator {
|
||||
current: self.parent_node.clone().map(|node| (*node.root()).clone()),
|
||||
current: self.parent_node.get().map(|node| (*node.root()).clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn owner_doc(&self) -> Temporary<Document> {
|
||||
Temporary::new(self.owner_doc.get_ref().clone())
|
||||
Temporary::new(self.owner_doc.get().get_ref().clone())
|
||||
}
|
||||
|
||||
fn set_owner_doc(&mut self, document: &JSRef<Document>) {
|
||||
|
@ -607,7 +607,7 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
|
|||
|
||||
fn children(&self) -> AbstractNodeChildrenIterator {
|
||||
AbstractNodeChildrenIterator {
|
||||
current_node: self.first_child.clone().map(|node| (*node.root()).clone()),
|
||||
current_node: self.first_child.get().map(|node| (*node.root()).clone()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -654,13 +654,13 @@ pub fn from_untrusted_node_address(runtime: *mut JSRuntime, candidate: Untrusted
|
|||
pub trait LayoutNodeHelpers {
|
||||
unsafe fn type_id_for_layout(&self) -> NodeTypeId;
|
||||
|
||||
unsafe fn parent_node_ref<'a>(&'a self) -> Option<&'a JS<Node>>;
|
||||
unsafe fn first_child_ref<'a>(&'a self) -> Option<&'a JS<Node>>;
|
||||
unsafe fn last_child_ref<'a>(&'a self) -> Option<&'a JS<Node>>;
|
||||
unsafe fn prev_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>>;
|
||||
unsafe fn next_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>>;
|
||||
unsafe fn parent_node_ref<'a>(&'a self) -> Option<JS<Node>>;
|
||||
unsafe fn first_child_ref<'a>(&'a self) -> Option<JS<Node>>;
|
||||
unsafe fn last_child_ref<'a>(&'a self) -> Option<JS<Node>>;
|
||||
unsafe fn prev_sibling_ref<'a>(&'a self) -> Option<JS<Node>>;
|
||||
unsafe fn next_sibling_ref<'a>(&'a self) -> Option<JS<Node>>;
|
||||
|
||||
unsafe fn owner_doc_for_layout<'a>(&'a self) -> &'a JS<Document>;
|
||||
unsafe fn owner_doc_for_layout<'a>(&'a self) -> JS<Document>;
|
||||
|
||||
unsafe fn is_element_for_layout(&self) -> bool;
|
||||
}
|
||||
|
@ -675,32 +675,32 @@ impl LayoutNodeHelpers for JS<Node> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn parent_node_ref<'a>(&'a self) -> Option<&'a JS<Node>> {
|
||||
(*self.unsafe_get()).parent_node.as_ref()
|
||||
unsafe fn parent_node_ref<'a>(&'a self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).parent_node.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn first_child_ref<'a>(&'a self) -> Option<&'a JS<Node>> {
|
||||
(*self.unsafe_get()).first_child.as_ref()
|
||||
unsafe fn first_child_ref<'a>(&'a self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).first_child.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn last_child_ref<'a>(&'a self) -> Option<&'a JS<Node>> {
|
||||
(*self.unsafe_get()).last_child.as_ref()
|
||||
unsafe fn last_child_ref<'a>(&'a self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).last_child.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn prev_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>> {
|
||||
(*self.unsafe_get()).prev_sibling.as_ref()
|
||||
unsafe fn prev_sibling_ref<'a>(&'a self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).prev_sibling.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn next_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>> {
|
||||
(*self.unsafe_get()).next_sibling.as_ref()
|
||||
unsafe fn next_sibling_ref<'a>(&'a self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).next_sibling.get()
|
||||
}
|
||||
|
||||
unsafe fn owner_doc_for_layout<'a>(&'a self) -> &'a JS<Document> {
|
||||
(*self.unsafe_get()).owner_doc.get_ref()
|
||||
unsafe fn owner_doc_for_layout<'a>(&'a self) -> JS<Document> {
|
||||
(*self.unsafe_get()).owner_doc.get().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,7 +822,7 @@ impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator {
|
|||
self.current_node = match self.current_node.as_ref().map(|node| node.root()) {
|
||||
None => {
|
||||
if self.include_start {
|
||||
Some(self.start_node.clone())
|
||||
Some(self.start_node)
|
||||
} else {
|
||||
self.next_child(&*self.start_node.root())
|
||||
.map(|child| child.unrooted())
|
||||
|
@ -860,7 +860,7 @@ impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator {
|
|||
}
|
||||
}
|
||||
};
|
||||
self.current_node.clone().map(|node| (*node.root()).clone())
|
||||
self.current_node.map(|node| (*node.root()).clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -911,14 +911,14 @@ impl Node {
|
|||
eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)),
|
||||
type_id: type_id,
|
||||
|
||||
parent_node: None,
|
||||
first_child: None,
|
||||
last_child: None,
|
||||
next_sibling: None,
|
||||
prev_sibling: None,
|
||||
parent_node: Cell::new(None),
|
||||
first_child: Cell::new(None),
|
||||
last_child: Cell::new(None),
|
||||
next_sibling: Cell::new(None),
|
||||
prev_sibling: Cell::new(None),
|
||||
|
||||
owner_doc: doc.unrooted(),
|
||||
child_list: None,
|
||||
owner_doc: Cell::new(doc.unrooted()),
|
||||
child_list: Cell::new(None),
|
||||
|
||||
flags: NodeFlags::new(type_id),
|
||||
|
||||
|
@ -1297,8 +1297,8 @@ impl Node {
|
|||
// FIXME: https://github.com/mozilla/servo/issues/1737
|
||||
copy_elem.namespace = node_elem.namespace.clone();
|
||||
let window = document.deref().window.root();
|
||||
for attr in node_elem.attrs.iter().map(|attr| attr.root()) {
|
||||
copy_elem.attrs.push_unrooted(
|
||||
for attr in node_elem.attrs.borrow().iter().map(|attr| attr.root()) {
|
||||
copy_elem.attrs.borrow_mut().push_unrooted(
|
||||
&Attr::new(&*window,
|
||||
attr.deref().local_name.clone(), attr.deref().value.clone(),
|
||||
attr.deref().name.clone(), attr.deref().namespace.clone(),
|
||||
|
@ -1427,12 +1427,12 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-node-parentnode
|
||||
fn GetParentNode(&self) -> Option<Temporary<Node>> {
|
||||
self.parent_node.clone().map(|node| Temporary::new(node))
|
||||
self.parent_node.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-parentelement
|
||||
fn GetParentElement(&self) -> Option<Temporary<Element>> {
|
||||
self.parent_node.clone()
|
||||
self.parent_node.get()
|
||||
.and_then(|parent| {
|
||||
let parent = parent.root();
|
||||
ElementCast::to_ref(&*parent).map(|elem| {
|
||||
|
@ -1443,12 +1443,12 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-node-haschildnodes
|
||||
fn HasChildNodes(&self) -> bool {
|
||||
self.first_child.is_some()
|
||||
self.first_child.get().is_some()
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-childnodes
|
||||
fn ChildNodes(&mut self) -> Temporary<NodeList> {
|
||||
match self.child_list {
|
||||
match self.child_list.get() {
|
||||
None => (),
|
||||
Some(ref list) => return Temporary::new(list.clone()),
|
||||
}
|
||||
|
@ -1457,27 +1457,27 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
let window = doc.deref().window.root();
|
||||
let child_list = NodeList::new_child_list(&*window, self);
|
||||
self.child_list.assign(Some(child_list));
|
||||
Temporary::new(self.child_list.get_ref().clone())
|
||||
Temporary::new(self.child_list.get().get_ref().clone())
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-firstchild
|
||||
fn GetFirstChild(&self) -> Option<Temporary<Node>> {
|
||||
self.first_child.clone().map(|node| Temporary::new(node))
|
||||
self.first_child.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-lastchild
|
||||
fn GetLastChild(&self) -> Option<Temporary<Node>> {
|
||||
self.last_child.clone().map(|node| Temporary::new(node))
|
||||
self.last_child.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-previoussibling
|
||||
fn GetPreviousSibling(&self) -> Option<Temporary<Node>> {
|
||||
self.prev_sibling.clone().map(|node| Temporary::new(node))
|
||||
self.prev_sibling.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-nextsibling
|
||||
fn GetNextSibling(&self) -> Option<Temporary<Node>> {
|
||||
self.next_sibling.clone().map(|node| Temporary::new(node))
|
||||
self.next_sibling.get().map(|node| Temporary::new(node))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-nodevalue
|
||||
|
@ -1766,9 +1766,11 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
|
||||
let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap();
|
||||
// FIXME: namespace prefix
|
||||
(element.deref().namespace == other_element.deref().namespace) &&
|
||||
(element.deref().local_name == other_element.deref().local_name) &&
|
||||
(element.deref().attrs.len() == other_element.deref().attrs.len())
|
||||
let element = element.deref();
|
||||
let other_element = other_element.deref();
|
||||
(element.namespace == other_element.namespace) &&
|
||||
(element.local_name == other_element.local_name) &&
|
||||
(element.attrs.borrow().len() == other_element.attrs.borrow().len())
|
||||
}
|
||||
fn is_equal_processinginstruction(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
|
||||
let pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
|
||||
|
@ -1784,9 +1786,11 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
fn is_equal_element_attrs(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
|
||||
let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
|
||||
let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap();
|
||||
assert!(element.deref().attrs.len() == other_element.deref().attrs.len());
|
||||
element.deref().attrs.iter().map(|attr| attr.root()).all(|attr| {
|
||||
other_element.deref().attrs.iter().map(|attr| attr.root()).any(|other_attr| {
|
||||
let element = element.deref();
|
||||
let other_element = other_element.deref();
|
||||
assert!(element.attrs.borrow().len() == other_element.attrs.borrow().len());
|
||||
element.attrs.borrow().iter().map(|attr| attr.root()).all(|attr| {
|
||||
other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| {
|
||||
(attr.namespace == other_attr.namespace) &&
|
||||
(attr.local_name == other_attr.local_name) &&
|
||||
(attr.value == other_attr.value)
|
||||
|
|
|
@ -7,7 +7,6 @@ use dom::bindings::js::{JS, JSRef, Temporary};
|
|||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::performancetiming::{PerformanceTiming, PerformanceTimingMethods};
|
||||
use dom::window::Window;
|
||||
|
||||
use time;
|
||||
|
||||
pub type DOMHighResTimeStamp = f64;
|
||||
|
@ -20,9 +19,10 @@ pub struct Performance {
|
|||
|
||||
impl Performance {
|
||||
fn new_inherited(window: &JSRef<Window>) -> Performance {
|
||||
let timing = PerformanceTiming::new(window).root().root_ref().unrooted();
|
||||
Performance {
|
||||
reflector_: Reflector::new(),
|
||||
timing: PerformanceTiming::new(window).root().root_ref().unrooted(),
|
||||
timing: timing,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,12 @@ use servo_util::str::DOMString;
|
|||
use js::jsapi::JSContext;
|
||||
use js::jsval::{JSVal, NullValue};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct TestBinding {
|
||||
pub reflector: Reflector,
|
||||
pub window: JS<Window>,
|
||||
pub window: Cell<JS<Window>>,
|
||||
}
|
||||
|
||||
pub trait TestBindingMethods {
|
||||
|
@ -243,19 +245,19 @@ pub trait TestBindingMethods {
|
|||
|
||||
impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
|
||||
fn InterfaceAttribute(&self) -> Temporary<Blob> {
|
||||
let window = self.window.root();
|
||||
let window = self.window.get().root();
|
||||
Blob::new(&*window)
|
||||
}
|
||||
fn GetInterfaceAttributeNullable(&self) -> Option<Temporary<Blob>> {
|
||||
let window = self.window.root();
|
||||
let window = self.window.get().root();
|
||||
Some(Blob::new(&*window))
|
||||
}
|
||||
fn ReceiveInterface(&self) -> Temporary<Blob> {
|
||||
let window = self.window.root();
|
||||
let window = self.window.get().root();
|
||||
Blob::new(&*window)
|
||||
}
|
||||
fn ReceiveNullableInterface(&self) -> Option<Temporary<Blob>> {
|
||||
let window = self.window.root();
|
||||
let window = self.window.get().root();
|
||||
Some(Blob::new(&*window))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ pub trait UIEventMethods {
|
|||
|
||||
impl<'a> UIEventMethods for JSRef<'a, UIEvent> {
|
||||
fn GetView(&self) -> Option<Temporary<Window>> {
|
||||
self.view.clone().map(|view| Temporary::new(view))
|
||||
self.view.map(|view| Temporary::new(view))
|
||||
}
|
||||
|
||||
fn Detail(&self) -> i32 {
|
||||
|
|
|
@ -6,11 +6,12 @@ use dom::bindings::codegen::BindingDeclarations::ValidityStateBinding;
|
|||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::window::Window;
|
||||
use std::cell::Cell;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct ValidityState {
|
||||
pub reflector_: Reflector,
|
||||
pub window: JS<Window>,
|
||||
pub window: Cell<JS<Window>>,
|
||||
pub state: u8,
|
||||
}
|
||||
|
||||
|
@ -18,7 +19,7 @@ impl ValidityState {
|
|||
pub fn new_inherited(window: &JSRef<Window>) -> ValidityState {
|
||||
ValidityState {
|
||||
reflector_: Reflector::new(),
|
||||
window: window.unrooted(),
|
||||
window: Cell::new(window.unrooted()),
|
||||
state: 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ use js::jsapi::{JS_GC, JS_GetRuntime};
|
|||
use js::jsval::{NullValue, JSVal};
|
||||
|
||||
use collections::hashmap::HashMap;
|
||||
use std::cell::Cell;
|
||||
use std::cmp;
|
||||
use std::comm::{channel, Sender};
|
||||
use std::comm::Select;
|
||||
|
@ -69,16 +70,16 @@ impl TimerHandle {
|
|||
pub struct Window {
|
||||
pub eventtarget: EventTarget,
|
||||
pub script_chan: ScriptChan,
|
||||
pub console: Option<JS<Console>>,
|
||||
pub location: Option<JS<Location>>,
|
||||
pub navigator: Option<JS<Navigator>>,
|
||||
pub console: Cell<Option<JS<Console>>>,
|
||||
pub location: Cell<Option<JS<Location>>>,
|
||||
pub navigator: Cell<Option<JS<Navigator>>>,
|
||||
pub image_cache_task: ImageCacheTask,
|
||||
pub active_timers: Box<HashMap<TimerId, TimerHandle>>,
|
||||
pub next_timer_handle: i32,
|
||||
pub compositor: Untraceable<Box<ScriptListener>>,
|
||||
pub browser_context: Option<BrowserContext>,
|
||||
pub page: Rc<Page>,
|
||||
pub performance: Option<JS<Performance>>,
|
||||
pub performance: Cell<Option<JS<Performance>>>,
|
||||
pub navigationStart: u64,
|
||||
pub navigationStartPrecise: f64,
|
||||
}
|
||||
|
@ -200,28 +201,28 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
|
|||
}
|
||||
|
||||
fn Location(&mut self) -> Temporary<Location> {
|
||||
if self.location.is_none() {
|
||||
if self.location.get().is_none() {
|
||||
let page = self.deref().page.clone();
|
||||
let location = Location::new(self, page);
|
||||
self.location.assign(Some(location));
|
||||
}
|
||||
Temporary::new(self.location.get_ref().clone())
|
||||
Temporary::new(self.location.get().get_ref().clone())
|
||||
}
|
||||
|
||||
fn Console(&mut self) -> Temporary<Console> {
|
||||
if self.console.is_none() {
|
||||
if self.console.get().is_none() {
|
||||
let console = Console::new(self);
|
||||
self.console.assign(Some(console));
|
||||
}
|
||||
Temporary::new(self.console.get_ref().clone())
|
||||
Temporary::new(self.console.get().get_ref().clone())
|
||||
}
|
||||
|
||||
fn Navigator(&mut self) -> Temporary<Navigator> {
|
||||
if self.navigator.is_none() {
|
||||
if self.navigator.get().is_none() {
|
||||
let navigator = Navigator::new(self);
|
||||
self.navigator.assign(Some(navigator));
|
||||
}
|
||||
Temporary::new(self.navigator.get_ref().clone())
|
||||
Temporary::new(self.navigator.get().get_ref().clone())
|
||||
}
|
||||
|
||||
fn Confirm(&self, _message: DOMString) -> bool {
|
||||
|
@ -269,11 +270,11 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
|
|||
}
|
||||
|
||||
fn Performance(&mut self) -> Temporary<Performance> {
|
||||
if self.performance.is_none() {
|
||||
if self.performance.get().is_none() {
|
||||
let performance = Performance::new(self);
|
||||
self.performance.assign(Some(performance));
|
||||
}
|
||||
Temporary::new(self.performance.get_ref().clone())
|
||||
Temporary::new(self.performance.get().get_ref().clone())
|
||||
}
|
||||
|
||||
fn GetOnload(&self) -> Option<EventHandlerNonNull> {
|
||||
|
@ -441,16 +442,16 @@ impl Window {
|
|||
let win = box Window {
|
||||
eventtarget: EventTarget::new_inherited(WindowTypeId),
|
||||
script_chan: script_chan,
|
||||
console: None,
|
||||
console: Cell::new(None),
|
||||
compositor: Untraceable::new(compositor),
|
||||
page: page,
|
||||
location: None,
|
||||
navigator: None,
|
||||
location: Cell::new(None),
|
||||
navigator: Cell::new(None),
|
||||
image_cache_task: image_cache_task,
|
||||
active_timers: box HashMap::new(),
|
||||
next_timer_handle: 0,
|
||||
browser_context: None,
|
||||
performance: None,
|
||||
performance: Cell::new(None),
|
||||
navigationStart: time::get_time().sec as u64,
|
||||
navigationStartPrecise: time::precise_time_s(),
|
||||
};
|
||||
|
|
|
@ -32,6 +32,7 @@ use url::Url;
|
|||
use libc;
|
||||
use libc::c_void;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::comm::channel;
|
||||
use std::io::{BufReader, MemWriter};
|
||||
use std::from_str::FromStr;
|
||||
|
@ -98,14 +99,14 @@ pub struct XMLHttpRequest {
|
|||
ready_state: XMLHttpRequestState,
|
||||
timeout: u32,
|
||||
with_credentials: bool,
|
||||
upload: Option<JS<XMLHttpRequestUpload>>,
|
||||
upload: Cell<Option<JS<XMLHttpRequestUpload>>>,
|
||||
response_url: DOMString,
|
||||
status: u16,
|
||||
status_text: ByteString,
|
||||
response: ByteString,
|
||||
response_type: XMLHttpRequestResponseType,
|
||||
response_text: DOMString,
|
||||
response_xml: Option<JS<Document>>,
|
||||
response_xml: Cell<Option<JS<Document>>>,
|
||||
response_headers: Untraceable<ResponseHeaderCollection>,
|
||||
|
||||
// Associated concepts
|
||||
|
@ -129,14 +130,14 @@ impl XMLHttpRequest {
|
|||
ready_state: Unsent,
|
||||
timeout: 0u32,
|
||||
with_credentials: false,
|
||||
upload: None,
|
||||
upload: Cell::new(None),
|
||||
response_url: "".to_owned(),
|
||||
status: 0,
|
||||
status_text: ByteString::new(vec!()),
|
||||
response: ByteString::new(vec!()),
|
||||
response_type: _empty,
|
||||
response_text: "".to_owned(),
|
||||
response_xml: None,
|
||||
response_xml: Cell::new(None),
|
||||
response_headers: Untraceable::new(ResponseHeaderCollection::new()),
|
||||
|
||||
request_method: Untraceable::new(Get),
|
||||
|
@ -385,7 +386,7 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
|||
self.with_credentials = with_credentials
|
||||
}
|
||||
fn Upload(&self) -> Temporary<XMLHttpRequestUpload> {
|
||||
Temporary::new(self.upload.get_ref().clone())
|
||||
Temporary::new(self.upload.get().get_ref().clone())
|
||||
}
|
||||
fn Send(&mut self, data: Option<DOMString>) -> ErrorResult {
|
||||
if self.ready_state != Opened || self.send_flag {
|
||||
|
@ -407,7 +408,7 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
|||
};
|
||||
if !self.sync {
|
||||
// Step 8
|
||||
let upload_target = &*self.upload.root().unwrap();
|
||||
let upload_target = &*self.upload.get().root().unwrap();
|
||||
let event_target: &JSRef<EventTarget> = EventTargetCast::from_ref(upload_target);
|
||||
if event_target.handlers.iter().len() > 0 {
|
||||
self.upload_events = true;
|
||||
|
@ -498,7 +499,7 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
|||
self.response_text.clone()
|
||||
}
|
||||
fn GetResponseXML(&self) -> Option<Temporary<Document>> {
|
||||
self.response_xml.clone().map(|response| Temporary::new(response))
|
||||
self.response_xml.get().map(|response| Temporary::new(response))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,7 +638,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
|
|||
|
||||
fn dispatch_progress_event(&self, upload: bool, type_: DOMString, loaded: u64, total: Option<u64>) {
|
||||
let win = &*self.global.root();
|
||||
let upload_target = &*self.upload.root().unwrap();
|
||||
let upload_target = &*self.upload.get().root().unwrap();
|
||||
let mut progressevent = ProgressEvent::new(win, type_, false, false,
|
||||
total.is_some(), loaded,
|
||||
total.unwrap_or(0)).root();
|
||||
|
|
|
@ -162,7 +162,7 @@ pub struct Page {
|
|||
resize_event: Untraceable<Cell<Option<Size2D<uint>>>>,
|
||||
|
||||
/// Pending scroll to fragment event, if any
|
||||
fragment_node: Traceable<RefCell<Option<JS<Element>>>>,
|
||||
fragment_node: Cell<Option<JS<Element>>>,
|
||||
|
||||
/// Associated resource task for use by DOM objects like XMLHttpRequest
|
||||
pub resource_task: Untraceable<ResourceTask>,
|
||||
|
@ -221,7 +221,7 @@ impl Page {
|
|||
url: Untraceable::new(RefCell::new(None)),
|
||||
next_subpage_id: Untraceable::new(Cell::new(SubpageId(0))),
|
||||
resize_event: Untraceable::new(Cell::new(None)),
|
||||
fragment_node: Traceable::new(RefCell::new(None)),
|
||||
fragment_node: Cell::new(None),
|
||||
last_reflow_id: Traceable::new(Cell::new(0)),
|
||||
resource_task: Untraceable::new(resource_task),
|
||||
constellation_chan: Untraceable::new(constellation_chan),
|
||||
|
@ -1043,8 +1043,8 @@ impl ScriptTask {
|
|||
let _ = wintarget.dispatch_event_with_target(Some((*doctarget).clone()),
|
||||
&mut *event);
|
||||
|
||||
let mut fragment_node = page.fragment_node.deref().borrow_mut();
|
||||
(*fragment_node).assign(fragment.map_or(None, |fragid| page.find_fragment_node(fragid)));
|
||||
let mut fragment_node = page.fragment_node.get();
|
||||
fragment_node.assign(fragment.map_or(None, |fragid| page.find_fragment_node(fragid)));
|
||||
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(LoadCompleteMsg(page.id, url));
|
||||
|
@ -1080,7 +1080,7 @@ impl ScriptTask {
|
|||
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
|
||||
}
|
||||
|
||||
let mut fragment_node = page.fragment_node.deref().borrow_mut();
|
||||
let mut fragment_node = page.fragment_node.get();
|
||||
match fragment_node.take().map(|node| node.root()) {
|
||||
Some(node) => self.scroll_fragment_point(pipeline_id, &*node),
|
||||
None => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue