mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Upgrade to latest Rust.
This commit is contained in:
parent
728fb9a7de
commit
a7ef1cd35e
127 changed files with 1892 additions and 2501 deletions
|
@ -7,7 +7,6 @@
|
|||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::bindings::utils::{DOMString, null_str_as_empty};
|
||||
use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest};
|
||||
use dom::bindings::utils;
|
||||
use dom::characterdata::CharacterData;
|
||||
use dom::document::{AbstractDocument, DocumentTypeId};
|
||||
use dom::documenttype::DocumentType;
|
||||
|
@ -20,12 +19,15 @@ use dom::nodelist::{NodeList};
|
|||
use dom::text::Text;
|
||||
|
||||
use js::jsapi::{JSObject, JSContext};
|
||||
use servo_util::slot::{MutSlotRef, Slot, SlotRef};
|
||||
use std::cast::transmute;
|
||||
|
||||
use layout_interface::{LayoutChan, ReapLayoutDataMsg};
|
||||
|
||||
use std::cast;
|
||||
use std::unstable::raw::Box;
|
||||
use std::util;
|
||||
use std::cast::transmute;
|
||||
use std::cell::{RefCell, Ref, RefMut};
|
||||
use std::iter::Filter;
|
||||
use std::util;
|
||||
use std::unstable::raw::Box;
|
||||
|
||||
//
|
||||
// The basic Node structure
|
||||
|
@ -37,7 +39,7 @@ use std::iter::Filter;
|
|||
/// FIXME: This should be replaced with a trait once they can inherit from structs.
|
||||
#[deriving(Eq)]
|
||||
pub struct AbstractNode {
|
||||
priv obj: *mut Box<Node>,
|
||||
priv obj: *mut (),
|
||||
}
|
||||
|
||||
/// An HTML node.
|
||||
|
@ -109,30 +111,43 @@ impl Drop for Node {
|
|||
}
|
||||
|
||||
/// Encapsulates the abstract layout data.
|
||||
pub struct LayoutData {
|
||||
priv chan: Option<LayoutChan>,
|
||||
priv data: *(),
|
||||
}
|
||||
|
||||
pub struct LayoutDataRef {
|
||||
priv data: Slot<Option<*()>>,
|
||||
data_cell: RefCell<Option<LayoutData>>,
|
||||
}
|
||||
|
||||
impl LayoutDataRef {
|
||||
#[inline]
|
||||
pub fn init() -> LayoutDataRef {
|
||||
pub fn new() -> LayoutDataRef {
|
||||
LayoutDataRef {
|
||||
data: Slot::init(None),
|
||||
data_cell: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new piece of layout data from a value.
|
||||
#[inline]
|
||||
pub unsafe fn from_data<T>(data: ~T) -> LayoutDataRef {
|
||||
LayoutDataRef {
|
||||
data: Slot::init(Some(cast::transmute(data))),
|
||||
data_cell: RefCell::new(Some(cast::transmute(data))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this layout data is present or false otherwise.
|
||||
/// Returns true if there is layout data present.
|
||||
#[inline]
|
||||
pub fn is_present(&self) -> bool {
|
||||
self.data.get().is_some()
|
||||
let data_ref = self.data_cell.borrow();
|
||||
data_ref.get().is_some()
|
||||
}
|
||||
|
||||
/// Take the chan out of the layout data if it is present.
|
||||
pub fn take_chan(&self) -> Option<LayoutChan> {
|
||||
let mut data_ref = self.data_cell.borrow_mut();
|
||||
let layout_data = data_ref.get();
|
||||
match *layout_data {
|
||||
None => None,
|
||||
Some(..) => Some(layout_data.get_mut_ref().chan.take_unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrows the layout data immutably, *asserting that there are no mutators*. Bad things will
|
||||
|
@ -141,17 +156,15 @@ impl LayoutDataRef {
|
|||
///
|
||||
/// FIXME(pcwalton): Enforce this invariant via the type system. Will require traversal
|
||||
/// functions to be trusted, but c'est la vie.
|
||||
#[inline]
|
||||
pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a () {
|
||||
cast::transmute(self.data.borrow_unchecked())
|
||||
}
|
||||
// #[inline]
|
||||
// pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a () {
|
||||
// self.data.borrow_unchecked()
|
||||
// }
|
||||
|
||||
/// Borrows the layout data immutably. This function is *not* thread-safe.
|
||||
#[inline]
|
||||
pub fn borrow<'a>(&'a self) -> SlotRef<'a,()> {
|
||||
unsafe {
|
||||
cast::transmute(self.data.borrow())
|
||||
}
|
||||
pub fn borrow<'a>(&'a self) -> Ref<'a,Option<LayoutData>> {
|
||||
self.data_cell.borrow()
|
||||
}
|
||||
|
||||
/// Borrows the layout data mutably. This function is *not* thread-safe.
|
||||
|
@ -160,10 +173,8 @@ impl LayoutDataRef {
|
|||
/// prevent CSS selector matching from mutably accessing nodes it's not supposed to and racing
|
||||
/// on it. This has already resulted in one bug!
|
||||
#[inline]
|
||||
pub fn mutate<'a>(&'a self) -> MutSlotRef<'a,()> {
|
||||
unsafe {
|
||||
cast::transmute(self.data.mutate())
|
||||
}
|
||||
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a,Option<LayoutData>> {
|
||||
self.data_cell.borrow_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,13 +204,15 @@ impl Clone for AbstractNode {
|
|||
impl AbstractNode {
|
||||
pub fn node<'a>(&'a self) -> &'a Node {
|
||||
unsafe {
|
||||
&(*self.obj).data
|
||||
let box_: *mut Box<Node> = cast::transmute(self.obj);
|
||||
&(*box_).data
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mut_node<'a>(&'a self) -> &'a mut Node {
|
||||
unsafe {
|
||||
&mut (*self.obj).data
|
||||
let box_: *mut Box<Node> = cast::transmute(self.obj);
|
||||
&mut (*box_).data
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,20 +230,20 @@ impl AbstractNode {
|
|||
|
||||
pub fn is_element(&self) -> bool {
|
||||
match self.type_id() {
|
||||
ElementNodeTypeId(*) => true,
|
||||
ElementNodeTypeId(..) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_document(&self) -> bool {
|
||||
match self.type_id() {
|
||||
DocumentNodeTypeId(*) => true,
|
||||
DocumentNodeTypeId(..) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> AbstractNode {
|
||||
impl<'a> AbstractNode {
|
||||
// Unsafe accessors
|
||||
|
||||
pub unsafe fn as_cacheable_wrapper(&self) -> @mut Reflectable {
|
||||
|
@ -252,7 +265,7 @@ impl<'self> AbstractNode {
|
|||
/// FIXME(pcwalton): Mark unsafe?
|
||||
pub fn from_box<T>(ptr: *mut Box<T>) -> AbstractNode {
|
||||
AbstractNode {
|
||||
obj: ptr as *mut Box<Node>
|
||||
obj: ptr as *mut ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,27 +304,27 @@ impl<'self> AbstractNode {
|
|||
// Downcasting borrows
|
||||
//
|
||||
|
||||
pub fn transmute<T, R>(self, f: &fn(&T) -> R) -> R {
|
||||
pub fn transmute<'a, T, R>(self, f: |&'a T| -> R) -> R {
|
||||
unsafe {
|
||||
let node_box: *mut Box<Node> = transmute(self.obj);
|
||||
let node = &mut (*node_box).data;
|
||||
let old = node.abstract;
|
||||
node.abstract = Some(self);
|
||||
let box: *Box<T> = transmute(self.obj);
|
||||
let rv = f(&(*box).data);
|
||||
let box_: *Box<T> = transmute(self.obj);
|
||||
let rv = f(&(*box_).data);
|
||||
node.abstract = old;
|
||||
rv
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transmute_mut<T, R>(self, f: &fn(&mut T) -> R) -> R {
|
||||
pub fn transmute_mut<T, R>(self, f: |&mut T| -> R) -> R {
|
||||
unsafe {
|
||||
let node_box: *mut Box<Node> = transmute(self.obj);
|
||||
let node = &mut (*node_box).data;
|
||||
let old = node.abstract;
|
||||
node.abstract = Some(self);
|
||||
let box: *Box<T> = transmute(self.obj);
|
||||
let rv = f(cast::transmute(&(*box).data));
|
||||
let box_: *Box<T> = transmute(self.obj);
|
||||
let rv = f(cast::transmute(&(*box_).data));
|
||||
node.abstract = old;
|
||||
rv
|
||||
}
|
||||
|
@ -323,14 +336,14 @@ impl<'self> AbstractNode {
|
|||
self.is_text() || self.is_comment()
|
||||
}
|
||||
|
||||
pub fn with_imm_characterdata<R>(self, f: &fn(&CharacterData) -> R) -> R {
|
||||
pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R {
|
||||
if !self.is_characterdata() {
|
||||
fail!(~"node is not characterdata");
|
||||
}
|
||||
self.transmute(f)
|
||||
}
|
||||
|
||||
pub fn with_mut_characterdata<R>(self, f: &fn(&mut CharacterData) -> R) -> R {
|
||||
pub fn with_mut_characterdata<R>(self, f: |&mut CharacterData| -> R) -> R {
|
||||
if !self.is_characterdata() {
|
||||
fail!(~"node is not characterdata");
|
||||
}
|
||||
|
@ -341,14 +354,14 @@ impl<'self> AbstractNode {
|
|||
self.type_id() == DoctypeNodeTypeId
|
||||
}
|
||||
|
||||
pub fn with_imm_doctype<R>(self, f: &fn(&DocumentType) -> R) -> R {
|
||||
pub fn with_imm_doctype<R>(self, f: |&DocumentType| -> R) -> R {
|
||||
if !self.is_doctype() {
|
||||
fail!(~"node is not doctype");
|
||||
}
|
||||
self.transmute(f)
|
||||
}
|
||||
|
||||
pub fn with_mut_doctype<R>(self, f: &fn(&mut DocumentType) -> R) -> R {
|
||||
pub fn with_mut_doctype<R>(self, f: |&mut DocumentType| -> R) -> R {
|
||||
if !self.is_doctype() {
|
||||
fail!(~"node is not doctype");
|
||||
}
|
||||
|
@ -375,14 +388,14 @@ impl<'self> AbstractNode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_imm_text<R>(self, f: &fn(&Text) -> R) -> R {
|
||||
pub fn with_imm_text<R>(self, f: |&Text| -> R) -> R {
|
||||
if !self.is_text() {
|
||||
fail!(~"node is not text");
|
||||
}
|
||||
self.transmute(f)
|
||||
}
|
||||
|
||||
pub fn with_mut_text<R>(self, f: &fn(&mut Text) -> R) -> R {
|
||||
pub fn with_mut_text<R>(self, f: |&mut Text| -> R) -> R {
|
||||
if !self.is_text() {
|
||||
fail!(~"node is not text");
|
||||
}
|
||||
|
@ -390,7 +403,7 @@ impl<'self> AbstractNode {
|
|||
}
|
||||
|
||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||
pub fn with_imm_element<R>(self, f: &fn(&Element) -> R) -> R {
|
||||
pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R {
|
||||
if !self.is_element() {
|
||||
fail!(~"node is not an element");
|
||||
}
|
||||
|
@ -398,7 +411,7 @@ impl<'self> AbstractNode {
|
|||
}
|
||||
|
||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||
pub fn as_mut_element<R>(self, f: &fn(&mut Element) -> R) -> R {
|
||||
pub fn as_mut_element<R>(self, f: |&mut Element| -> R) -> R {
|
||||
if !self.is_element() {
|
||||
fail!(~"node is not an element");
|
||||
}
|
||||
|
@ -413,7 +426,7 @@ impl<'self> AbstractNode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_mut_image_element<R>(self, f: &fn(&mut HTMLImageElement) -> R) -> R {
|
||||
pub fn with_mut_image_element<R>(self, f: |&mut HTMLImageElement| -> R) -> R {
|
||||
if !self.is_image_element() {
|
||||
fail!(~"node is not an image element");
|
||||
}
|
||||
|
@ -424,7 +437,7 @@ impl<'self> AbstractNode {
|
|||
self.type_id() == ElementNodeTypeId(HTMLIframeElementTypeId)
|
||||
}
|
||||
|
||||
pub fn with_mut_iframe_element<R>(self, f: &fn(&mut HTMLIFrameElement) -> R) -> R {
|
||||
pub fn with_mut_iframe_element<R>(self, f: |&mut HTMLIFrameElement| -> R) -> R {
|
||||
if !self.is_iframe_element() {
|
||||
fail!(~"node is not an iframe element");
|
||||
}
|
||||
|
@ -440,12 +453,12 @@ impl<'self> AbstractNode {
|
|||
}
|
||||
|
||||
pub unsafe fn raw_object(self) -> *mut Box<Node> {
|
||||
self.obj
|
||||
cast::transmute(self.obj)
|
||||
}
|
||||
|
||||
pub fn from_raw(raw: *mut Box<Node>) -> AbstractNode {
|
||||
AbstractNode {
|
||||
obj: raw
|
||||
obj: raw as *mut ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,10 +492,6 @@ impl<'self> AbstractNode {
|
|||
// Convenience accessors
|
||||
//
|
||||
|
||||
fn is_leaf(&self) -> bool {
|
||||
self.first_child().is_none()
|
||||
}
|
||||
|
||||
pub fn children(&self) -> AbstractNodeChildrenIterator {
|
||||
self.node().children()
|
||||
}
|
||||
|
@ -610,35 +619,6 @@ impl AbstractNode {
|
|||
child_node.set_next_sibling(None);
|
||||
child_node.set_parent_node(None);
|
||||
}
|
||||
|
||||
//
|
||||
// Low-level pointer stitching wrappers
|
||||
//
|
||||
|
||||
fn set_parent_node(&self, new_parent_node: Option<AbstractNode>) {
|
||||
let node = self.mut_node();
|
||||
node.set_parent_node(new_parent_node)
|
||||
}
|
||||
|
||||
fn set_first_child(&self, new_first_child: Option<AbstractNode>) {
|
||||
let node = self.mut_node();
|
||||
node.set_first_child(new_first_child)
|
||||
}
|
||||
|
||||
fn set_last_child(&self, new_last_child: Option<AbstractNode>) {
|
||||
let node = self.mut_node();
|
||||
node.set_last_child(new_last_child)
|
||||
}
|
||||
|
||||
fn set_prev_sibling(&self, new_prev_sibling: Option<AbstractNode>) {
|
||||
let node = self.mut_node();
|
||||
node.set_prev_sibling(new_prev_sibling)
|
||||
}
|
||||
|
||||
fn set_next_sibling(&self, new_next_sibling: Option<AbstractNode>) {
|
||||
let node = self.mut_node();
|
||||
node.set_next_sibling(new_next_sibling)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -652,9 +632,9 @@ pub struct AbstractNodeChildrenIterator {
|
|||
impl Iterator<AbstractNode> for AbstractNodeChildrenIterator {
|
||||
fn next(&mut self) -> Option<AbstractNode> {
|
||||
let node = self.current_node;
|
||||
self.current_node = do self.current_node.and_then |node| {
|
||||
self.current_node = self.current_node.and_then(|node| {
|
||||
node.next_sibling()
|
||||
};
|
||||
});
|
||||
node
|
||||
}
|
||||
}
|
||||
|
@ -766,9 +746,9 @@ impl Node {
|
|||
assert!(node.reflector().get_jsobject().is_null());
|
||||
let node = reflect_dom_object(node, document.document().window, wrap_fn);
|
||||
assert!(node.reflector().get_jsobject().is_not_null());
|
||||
// This surrenders memory management of the node!
|
||||
// JS owns the node now, so transmute_copy to not increase the refcount
|
||||
AbstractNode {
|
||||
obj: unsafe { transmute(node) },
|
||||
obj: unsafe { cast::transmute_copy(&node) },
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,16 +778,19 @@ impl Node {
|
|||
|
||||
flags: NodeFlags::new(type_id),
|
||||
|
||||
layout_data: LayoutDataRef::init(),
|
||||
layout_data: LayoutDataRef::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends layout data, if any, back to the script task to be destroyed.
|
||||
pub unsafe fn reap_layout_data(&mut self) {
|
||||
if self.layout_data.is_present() {
|
||||
let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::init());
|
||||
let js_window = utils::global_object_for_dom_object(self);
|
||||
(*js_window).data.page.reap_dead_layout_data(layout_data)
|
||||
let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::new());
|
||||
let layout_chan = layout_data.take_chan();
|
||||
match layout_chan {
|
||||
None => {}
|
||||
Some(chan) => chan.send(ReapLayoutDataMsg(layout_data)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -825,17 +808,17 @@ impl Node {
|
|||
|
||||
pub fn NodeName(&self, abstract_self: AbstractNode) -> DOMString {
|
||||
match self.type_id {
|
||||
ElementNodeTypeId(*) => {
|
||||
do abstract_self.with_imm_element |element| {
|
||||
ElementNodeTypeId(..) => {
|
||||
abstract_self.with_imm_element(|element| {
|
||||
element.TagName()
|
||||
}
|
||||
})
|
||||
}
|
||||
CommentNodeTypeId => ~"#comment",
|
||||
TextNodeTypeId => ~"#text",
|
||||
DoctypeNodeTypeId => {
|
||||
do abstract_self.with_imm_doctype |doctype| {
|
||||
abstract_self.with_imm_doctype(|doctype| {
|
||||
doctype.name.clone()
|
||||
}
|
||||
})
|
||||
},
|
||||
DocumentFragmentNodeTypeId => ~"#document-fragment",
|
||||
DocumentNodeTypeId(_) => ~"#document"
|
||||
|
@ -848,7 +831,7 @@ impl Node {
|
|||
|
||||
pub fn GetOwnerDocument(&self) -> Option<AbstractDocument> {
|
||||
match self.type_id {
|
||||
ElementNodeTypeId(*) |
|
||||
ElementNodeTypeId(..) |
|
||||
CommentNodeTypeId |
|
||||
TextNodeTypeId |
|
||||
DoctypeNodeTypeId |
|
||||
|
@ -889,9 +872,9 @@ impl Node {
|
|||
match self.type_id {
|
||||
// ProcessingInstruction
|
||||
CommentNodeTypeId | TextNodeTypeId => {
|
||||
do abstract_self.with_imm_characterdata() |characterdata| {
|
||||
abstract_self.with_imm_characterdata(|characterdata| {
|
||||
Some(characterdata.Data())
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
|
@ -906,21 +889,21 @@ impl Node {
|
|||
|
||||
pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> {
|
||||
match self.type_id {
|
||||
DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
|
||||
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
|
||||
let mut content = ~"";
|
||||
for node in abstract_self.traverse_preorder() {
|
||||
if node.is_text() {
|
||||
do node.with_imm_text() |text| {
|
||||
node.with_imm_text(|text| {
|
||||
content = content + text.element.Data();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Some(content)
|
||||
}
|
||||
CommentNodeTypeId | TextNodeTypeId => {
|
||||
do abstract_self.with_imm_characterdata() |characterdata| {
|
||||
abstract_self.with_imm_characterdata(|characterdata| {
|
||||
Some(characterdata.Data())
|
||||
}
|
||||
})
|
||||
}
|
||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
|
||||
None
|
||||
|
@ -968,9 +951,9 @@ impl Node {
|
|||
|
||||
// Step 1.
|
||||
match parent.type_id() {
|
||||
DocumentNodeTypeId(*) |
|
||||
DocumentNodeTypeId(..) |
|
||||
DocumentFragmentNodeTypeId |
|
||||
ElementNodeTypeId(*) => (),
|
||||
ElementNodeTypeId(..) => (),
|
||||
_ => {
|
||||
return Err(HierarchyRequest);
|
||||
},
|
||||
|
@ -999,7 +982,7 @@ impl Node {
|
|||
TextNodeTypeId |
|
||||
// ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId => (),
|
||||
DocumentNodeTypeId(*) => return Err(HierarchyRequest),
|
||||
DocumentNodeTypeId(..) => return Err(HierarchyRequest),
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
|
@ -1241,7 +1224,7 @@ impl Node {
|
|||
-> ErrorResult {
|
||||
let value = null_str_as_empty(&value);
|
||||
match self.type_id {
|
||||
DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
|
||||
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
|
||||
// Step 1-2.
|
||||
let node = if value.len() == 0 {
|
||||
None
|
||||
|
@ -1255,13 +1238,13 @@ impl Node {
|
|||
CommentNodeTypeId | TextNodeTypeId => {
|
||||
self.wait_until_safe_to_modify_dom();
|
||||
|
||||
do abstract_self.with_mut_characterdata() |characterdata| {
|
||||
abstract_self.with_mut_characterdata(|characterdata| {
|
||||
characterdata.data = value.clone();
|
||||
|
||||
// Notify the document that the content of this node is different
|
||||
let document = self.owner_doc();
|
||||
document.document().content_changed();
|
||||
}
|
||||
})
|
||||
}
|
||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue