mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Make Document a Node.
This commit is contained in:
parent
cc76a2188e
commit
99a36cbeb6
10 changed files with 96 additions and 120 deletions
|
@ -23,7 +23,7 @@ use style::computed_values::display;
|
||||||
use style::computed_values::float;
|
use style::computed_values::float;
|
||||||
use layout::float_context::{FloatLeft, FloatRight};
|
use layout::float_context::{FloatLeft, FloatRight};
|
||||||
use script::dom::node::{AbstractNode, CommentNodeTypeId, DoctypeNodeTypeId};
|
use script::dom::node::{AbstractNode, CommentNodeTypeId, DoctypeNodeTypeId};
|
||||||
use script::dom::node::{ElementNodeTypeId, LayoutView, TextNodeTypeId};
|
use script::dom::node::{ElementNodeTypeId, LayoutView, TextNodeTypeId, DocumentNodeTypeId};
|
||||||
use script::dom::node::DocumentFragmentNodeTypeId;
|
use script::dom::node::DocumentFragmentNodeTypeId;
|
||||||
use servo_util::range::Range;
|
use servo_util::range::Range;
|
||||||
use servo_util::tree::{TreeNodeRef, TreeNode};
|
use servo_util::tree::{TreeNodeRef, TreeNode};
|
||||||
|
@ -391,6 +391,7 @@ impl LayoutTreeBuilder {
|
||||||
display => display,
|
display => display,
|
||||||
},
|
},
|
||||||
TextNodeTypeId => display::inline,
|
TextNodeTypeId => display::inline,
|
||||||
|
DocumentNodeTypeId(_) |
|
||||||
DoctypeNodeTypeId |
|
DoctypeNodeTypeId |
|
||||||
DocumentFragmentNodeTypeId |
|
DocumentFragmentNodeTypeId |
|
||||||
CommentNodeTypeId => return NoGenerator,
|
CommentNodeTypeId => return NoGenerator,
|
||||||
|
@ -449,10 +450,10 @@ impl LayoutTreeBuilder {
|
||||||
match (parent_generator.flow.as_block().is_root, node.parent_node()) {
|
match (parent_generator.flow.as_block().is_root, node.parent_node()) {
|
||||||
// If this is the root node, then use the root flow's
|
// If this is the root node, then use the root flow's
|
||||||
// context. Otherwise, make a child block context.
|
// context. Otherwise, make a child block context.
|
||||||
(true, Some(_)) => {
|
(true, Some(parent)) if !parent.is_document() => {
|
||||||
self.create_child_generator(node, parent_generator, BlockFlowType)
|
self.create_child_generator(node, parent_generator, BlockFlowType)
|
||||||
}
|
}
|
||||||
(true, None) => return ParentGenerator,
|
(true, None) | (true, Some(_)) => return ParentGenerator,
|
||||||
(false, _) => {
|
(false, _) => {
|
||||||
self.create_child_generator(node, parent_generator, BlockFlowType)
|
self.create_child_generator(node, parent_generator, BlockFlowType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ enum VisibilityState { "hidden", "visible" };
|
||||||
|
|
||||||
/* http://dom.spec.whatwg.org/#interface-document */
|
/* http://dom.spec.whatwg.org/#interface-document */
|
||||||
[Constructor]
|
[Constructor]
|
||||||
interface Document /*: Node*/ { //XXXjdm Requires servo/#623
|
interface Document : Node {
|
||||||
/*[Throws]
|
/*[Throws]
|
||||||
readonly attribute DOMImplementation implementation;*/
|
readonly attribute DOMImplementation implementation;*/
|
||||||
// readonly attribute DOMString URL;
|
// readonly attribute DOMString URL;
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::utils::{Reflectable, Reflector, Traceable};
|
use dom::bindings::utils::{Reflectable, Reflector, Traceable};
|
||||||
|
use dom::document::{PlainDocumentTypeId, HTMLDocumentTypeId};
|
||||||
use dom::element::*;
|
use dom::element::*;
|
||||||
use dom::types::*;
|
use dom::types::*;
|
||||||
use dom::node::{AbstractNode, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
|
use dom::node::{AbstractNode, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
|
||||||
use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, ScriptView};
|
use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, ScriptView, DocumentNodeTypeId};
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::libc;
|
use std::libc;
|
||||||
|
@ -95,6 +96,8 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject
|
||||||
CommentNodeTypeId => generate_element!(Comment),
|
CommentNodeTypeId => generate_element!(Comment),
|
||||||
DoctypeNodeTypeId => generate_element!(DocumentType),
|
DoctypeNodeTypeId => generate_element!(DocumentType),
|
||||||
DocumentFragmentNodeTypeId => generate_element!(DocumentFragment),
|
DocumentFragmentNodeTypeId => generate_element!(DocumentFragment),
|
||||||
|
DocumentNodeTypeId(PlainDocumentTypeId) => generate_element!(Document),
|
||||||
|
DocumentNodeTypeId(HTMLDocumentTypeId) => generate_element!(HTMLDocument),
|
||||||
TextNodeTypeId => generate_element!(Text),
|
TextNodeTypeId => generate_element!(Text),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,18 +9,16 @@ use dom::bindings::utils::{Reflectable, Reflector, DerivedWrapper};
|
||||||
use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable, null_str_as_empty, null_str_as_word_null};
|
use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable, null_str_as_empty, null_str_as_word_null};
|
||||||
use dom::documentfragment::DocumentFragment;
|
use dom::documentfragment::DocumentFragment;
|
||||||
use dom::element::{Element};
|
use dom::element::{Element};
|
||||||
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
|
use dom::element::{HTMLHeadElementTypeId, HTMLTitleElementTypeId};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::HTMLCollection;
|
||||||
use dom::htmldocument::HTMLDocument;
|
use dom::htmldocument::HTMLDocument;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlhtmlelement::HTMLHtmlElement;
|
use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId, DocumentNodeTypeId};
|
||||||
use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId};
|
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use dom::htmltitleelement::HTMLTitleElement;
|
use dom::htmltitleelement::HTMLTitleElement;
|
||||||
use html::hubbub_html_parser::build_element_from_tag;
|
use html::hubbub_html_parser::build_element_from_tag;
|
||||||
use js::jsapi::{JSObject, JSContext, JSVal};
|
use js::jsapi::{JSObject, JSContext, JSVal, JSTracer};
|
||||||
use js::jsapi::{JSTRACE_OBJECT, JSTracer, JS_CallTracer};
|
|
||||||
use js::glue::RUST_OBJECT_TO_JSVAL;
|
use js::glue::RUST_OBJECT_TO_JSVAL;
|
||||||
use servo_util::tree::{TreeNodeRef, ElementLike};
|
use servo_util::tree::{TreeNodeRef, ElementLike};
|
||||||
|
|
||||||
|
@ -29,12 +27,18 @@ use std::hashmap::HashMap;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::str::eq_slice;
|
use std::str::eq_slice;
|
||||||
use std::libc;
|
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::unstable::raw::Box;
|
use std::unstable::raw::Box;
|
||||||
|
|
||||||
|
#[deriving(Eq)]
|
||||||
|
pub enum DocumentTypeId {
|
||||||
|
PlainDocumentTypeId,
|
||||||
|
HTMLDocumentTypeId
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ReflectableDocument {
|
pub trait ReflectableDocument {
|
||||||
fn init_reflector(@mut self, cx: *JSContext);
|
fn init_reflector(@mut self, cx: *JSContext);
|
||||||
|
fn init_node(@mut self, doc: AbstractDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
|
@ -45,9 +49,11 @@ pub struct AbstractDocument {
|
||||||
impl AbstractDocument {
|
impl AbstractDocument {
|
||||||
pub fn as_abstract<T: ReflectableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument {
|
pub fn as_abstract<T: ReflectableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument {
|
||||||
doc.init_reflector(cx);
|
doc.init_reflector(cx);
|
||||||
AbstractDocument {
|
let abstract = AbstractDocument {
|
||||||
document: unsafe { cast::transmute(doc) }
|
document: unsafe { cast::transmute(doc) }
|
||||||
}
|
};
|
||||||
|
doc.init_node(abstract);
|
||||||
|
abstract
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn document<'a>(&'a self) -> &'a Document {
|
pub fn document<'a>(&'a self) -> &'a Document {
|
||||||
|
@ -91,10 +97,9 @@ impl AbstractDocument {
|
||||||
});
|
});
|
||||||
|
|
||||||
let document = self.mut_document();
|
let document = self.mut_document();
|
||||||
document.root = Some(root);
|
document.node.AppendChild(AbstractNode::from_document(*self), root);
|
||||||
// Register elements having "id" attribute to the owner doc.
|
// Register elements having "id" attribute to the owner doc.
|
||||||
document.register_nodes_with_id(&root);
|
document.register_nodes_with_id(&root);
|
||||||
document.content_changed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +110,7 @@ pub enum DocumentType {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Document {
|
pub struct Document {
|
||||||
priv root: Option<AbstractNode<ScriptView>>,
|
node: Node<ScriptView>,
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
window: @mut Window,
|
window: @mut Window,
|
||||||
doctype: DocumentType,
|
doctype: DocumentType,
|
||||||
|
@ -116,8 +121,12 @@ pub struct Document {
|
||||||
impl Document {
|
impl Document {
|
||||||
#[fixed_stack_segment]
|
#[fixed_stack_segment]
|
||||||
pub fn new(window: @mut Window, doctype: DocumentType) -> Document {
|
pub fn new(window: @mut Window, doctype: DocumentType) -> Document {
|
||||||
|
let node_type = match doctype {
|
||||||
|
HTML => HTMLDocumentTypeId,
|
||||||
|
SVG | XML => PlainDocumentTypeId
|
||||||
|
};
|
||||||
Document {
|
Document {
|
||||||
root: None,
|
node: Node::new_without_doc(DocumentNodeTypeId(node_type)),
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
window: window,
|
window: window,
|
||||||
doctype: doctype,
|
doctype: doctype,
|
||||||
|
@ -128,16 +137,7 @@ impl Document {
|
||||||
|
|
||||||
pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> {
|
pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> {
|
||||||
let cx = owner.get_cx();
|
let cx = owner.get_cx();
|
||||||
|
Ok(AbstractDocument::as_abstract(cx, @mut Document::new(owner, XML)))
|
||||||
let document = AbstractDocument::as_abstract(cx, @mut Document::new(owner, XML));
|
|
||||||
|
|
||||||
let root = @HTMLHtmlElement {
|
|
||||||
htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document)
|
|
||||||
};
|
|
||||||
let root = unsafe { Node::as_abstract_node(cx, root) };
|
|
||||||
document.set_root(root);
|
|
||||||
|
|
||||||
Ok(document)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +145,10 @@ impl ReflectableDocument for Document {
|
||||||
fn init_reflector(@mut self, cx: *JSContext) {
|
fn init_reflector(@mut self, cx: *JSContext) {
|
||||||
self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
|
self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_node(@mut self, doc: AbstractDocument) {
|
||||||
|
self.node.set_owner_doc(doc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reflectable for AbstractDocument {
|
impl Reflectable for AbstractDocument {
|
||||||
|
@ -184,11 +188,11 @@ impl DerivedWrapper for AbstractDocument {
|
||||||
|
|
||||||
impl Reflectable for Document {
|
impl Reflectable for Document {
|
||||||
fn reflector<'a>(&'a self) -> &'a Reflector {
|
fn reflector<'a>(&'a self) -> &'a Reflector {
|
||||||
&self.reflector_
|
self.node.reflector()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
|
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
|
||||||
&mut self.reflector_
|
self.node.mut_reflector()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
||||||
|
@ -202,7 +206,7 @@ impl Reflectable for Document {
|
||||||
|
|
||||||
impl Document {
|
impl Document {
|
||||||
pub fn GetDocumentElement(&self) -> Option<AbstractNode<ScriptView>> {
|
pub fn GetDocumentElement(&self) -> Option<AbstractNode<ScriptView>> {
|
||||||
self.root
|
self.node.first_child
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cx(&self) -> *JSContext {
|
fn get_cx(&self) -> *JSContext {
|
||||||
|
@ -408,21 +412,6 @@ fn foreach_ided_elements(root: &AbstractNode<ScriptView>,
|
||||||
impl Traceable for Document {
|
impl Traceable for Document {
|
||||||
#[fixed_stack_segment]
|
#[fixed_stack_segment]
|
||||||
fn trace(&self, tracer: *mut JSTracer) {
|
fn trace(&self, tracer: *mut JSTracer) {
|
||||||
match self.root {
|
self.node.trace(tracer);
|
||||||
None => {},
|
|
||||||
Some(root) => {
|
|
||||||
unsafe {
|
|
||||||
(*tracer).debugPrinter = ptr::null();
|
|
||||||
(*tracer).debugPrintIndex = -1;
|
|
||||||
do "root".to_c_str().with_ref |name| {
|
|
||||||
(*tracer).debugPrintArg = name as *libc::c_void;
|
|
||||||
debug!("tracing root node");
|
|
||||||
JS_CallTracer(tracer as *JSTracer,
|
|
||||||
root.reflector().get_jsobject(),
|
|
||||||
JSTRACE_OBJECT as u32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,9 @@
|
||||||
use dom::bindings::codegen::DOMParserBinding;
|
use dom::bindings::codegen::DOMParserBinding;
|
||||||
use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml};
|
use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml};
|
||||||
use dom::bindings::utils::{DOMString, Fallible, Reflector, Reflectable, reflect_dom_object};
|
use dom::bindings::utils::{DOMString, Fallible, Reflector, Reflectable, reflect_dom_object};
|
||||||
|
use dom::bindings::utils::FailureUnknown;
|
||||||
use dom::document::{AbstractDocument, Document, XML};
|
use dom::document::{AbstractDocument, Document, XML};
|
||||||
use dom::element::HTMLHtmlElementTypeId;
|
|
||||||
use dom::htmldocument::HTMLDocument;
|
use dom::htmldocument::HTMLDocument;
|
||||||
use dom::htmlelement::HTMLElement;
|
|
||||||
use dom::htmlhtmlelement::HTMLHtmlElement;
|
|
||||||
use dom::node::Node;
|
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSObject};
|
use js::jsapi::{JSContext, JSObject};
|
||||||
|
@ -42,25 +39,17 @@ impl DOMParser {
|
||||||
ty: DOMParserBinding::SupportedType)
|
ty: DOMParserBinding::SupportedType)
|
||||||
-> Fallible<AbstractDocument> {
|
-> Fallible<AbstractDocument> {
|
||||||
let cx = self.owner.get_cx();
|
let cx = self.owner.get_cx();
|
||||||
let document = match ty {
|
match ty {
|
||||||
Text_html => {
|
Text_html => {
|
||||||
HTMLDocument::new(self.owner)
|
Ok(HTMLDocument::new(self.owner))
|
||||||
}
|
}
|
||||||
Text_xml => {
|
Text_xml => {
|
||||||
AbstractDocument::as_abstract(cx, @mut Document::new(self.owner, XML))
|
Ok(AbstractDocument::as_abstract(cx, @mut Document::new(self.owner, XML)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fail!("unsupported document type")
|
Err(FailureUnknown)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let root = @HTMLHtmlElement {
|
|
||||||
htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document)
|
|
||||||
};
|
|
||||||
let root = unsafe { Node::as_abstract_node(cx, root) };
|
|
||||||
document.set_root(root);
|
|
||||||
|
|
||||||
Ok(document)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ impl ReflectableDocument for HTMLDocument {
|
||||||
fn init_reflector(@mut self, cx: *JSContext) {
|
fn init_reflector(@mut self, cx: *JSContext) {
|
||||||
self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
|
self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_node(@mut self, doc: AbstractDocument) {
|
||||||
|
self.parent.node.set_owner_doc(doc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLDocument {
|
impl HTMLDocument {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||||
use dom::bindings::utils::{DOMString, null_str_as_empty};
|
use dom::bindings::utils::{DOMString, null_str_as_empty};
|
||||||
use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest};
|
use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest};
|
||||||
use dom::characterdata::CharacterData;
|
use dom::characterdata::CharacterData;
|
||||||
use dom::document::AbstractDocument;
|
use dom::document::{AbstractDocument, DocumentTypeId};
|
||||||
use dom::documenttype::DocumentType;
|
use dom::documenttype::DocumentType;
|
||||||
use dom::element::{Element, ElementTypeId, HTMLImageElementTypeId, HTMLIframeElementTypeId};
|
use dom::element::{Element, ElementTypeId, HTMLImageElementTypeId, HTMLIframeElementTypeId};
|
||||||
use dom::element::{HTMLStyleElementTypeId};
|
use dom::element::{HTMLStyleElementTypeId};
|
||||||
|
@ -88,7 +88,7 @@ pub struct Node<View> {
|
||||||
prev_sibling: Option<AbstractNode<View>>,
|
prev_sibling: Option<AbstractNode<View>>,
|
||||||
|
|
||||||
/// The document that this node belongs to.
|
/// The document that this node belongs to.
|
||||||
priv owner_doc: AbstractDocument,
|
priv owner_doc: Option<AbstractDocument>,
|
||||||
|
|
||||||
/// The live list of children return by .childNodes.
|
/// The live list of children return by .childNodes.
|
||||||
child_list: Option<@mut NodeList>,
|
child_list: Option<@mut NodeList>,
|
||||||
|
@ -103,6 +103,7 @@ pub enum NodeTypeId {
|
||||||
DoctypeNodeTypeId,
|
DoctypeNodeTypeId,
|
||||||
DocumentFragmentNodeTypeId,
|
DocumentFragmentNodeTypeId,
|
||||||
CommentNodeTypeId,
|
CommentNodeTypeId,
|
||||||
|
DocumentNodeTypeId(DocumentTypeId),
|
||||||
ElementNodeTypeId(ElementTypeId),
|
ElementNodeTypeId(ElementTypeId),
|
||||||
TextNodeTypeId,
|
TextNodeTypeId,
|
||||||
}
|
}
|
||||||
|
@ -204,6 +205,13 @@ impl<'self, View> AbstractNode<View> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allow consumers to upcast from derived classes.
|
||||||
|
pub fn from_document(doc: AbstractDocument) -> AbstractNode<View> {
|
||||||
|
unsafe {
|
||||||
|
cast::transmute(doc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience accessors
|
// Convenience accessors
|
||||||
|
|
||||||
/// Returns the type ID of this node. Fails if this node is borrowed mutably.
|
/// Returns the type ID of this node. Fails if this node is borrowed mutably.
|
||||||
|
@ -331,6 +339,13 @@ impl<'self, View> AbstractNode<View> {
|
||||||
self.transmute_mut(f)
|
self.transmute_mut(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_document(self) -> bool {
|
||||||
|
match self.type_id() {
|
||||||
|
DocumentNodeTypeId(*) => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
// 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: &fn(&Element) -> R) -> R {
|
||||||
if !self.is_element() {
|
if !self.is_element() {
|
||||||
|
@ -431,27 +446,7 @@ impl<'self, View> AbstractNode<View> {
|
||||||
|
|
||||||
// Issue #1030: should not walk the tree
|
// Issue #1030: should not walk the tree
|
||||||
pub fn is_in_doc(&self) -> bool {
|
pub fn is_in_doc(&self) -> bool {
|
||||||
let document = self.node().owner_doc();
|
self.ancestors().any(|node| node.is_document())
|
||||||
match document.document().GetDocumentElement() {
|
|
||||||
None => false,
|
|
||||||
Some(root) => {
|
|
||||||
let mut node = *self;
|
|
||||||
let mut in_doc;
|
|
||||||
loop {
|
|
||||||
match node.parent_node() {
|
|
||||||
Some(parent) => {
|
|
||||||
node = parent;
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
// Issue #1029: this is horrible.
|
|
||||||
in_doc = unsafe { node.raw_object() as uint == root.raw_object() as uint };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
in_doc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,11 +490,11 @@ impl<View> Iterator<AbstractNode<View>> for AbstractNodeChildrenIterator<View> {
|
||||||
|
|
||||||
impl<View> Node<View> {
|
impl<View> Node<View> {
|
||||||
pub fn owner_doc(&self) -> AbstractDocument {
|
pub fn owner_doc(&self) -> AbstractDocument {
|
||||||
self.owner_doc
|
self.owner_doc.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_owner_doc(&mut self, document: AbstractDocument) {
|
pub fn set_owner_doc(&mut self, document: AbstractDocument) {
|
||||||
self.owner_doc = document;
|
self.owner_doc = Some(document);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,6 +523,14 @@ impl Node<ScriptView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(type_id: NodeTypeId, doc: AbstractDocument) -> Node<ScriptView> {
|
pub fn new(type_id: NodeTypeId, doc: AbstractDocument) -> Node<ScriptView> {
|
||||||
|
Node::new_(type_id, Some(doc))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_without_doc(type_id: NodeTypeId) -> Node<ScriptView> {
|
||||||
|
Node::new_(type_id, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_(type_id: NodeTypeId, doc: Option<AbstractDocument>) -> Node<ScriptView> {
|
||||||
Node {
|
Node {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
type_id: type_id,
|
type_id: type_id,
|
||||||
|
@ -546,32 +549,16 @@ impl Node<ScriptView> {
|
||||||
layout_data: LayoutData::new(),
|
layout_data: LayoutData::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNextSibling(&mut self) -> Option<&mut AbstractNode<ScriptView>> {
|
|
||||||
match self.next_sibling {
|
|
||||||
// transmute because the compiler can't deduce that the reference
|
|
||||||
// is safe outside of with_mut_base blocks.
|
|
||||||
Some(ref mut n) => Some(unsafe { cast::transmute(n) }),
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getFirstChild(&mut self) -> Option<&mut AbstractNode<ScriptView>> {
|
|
||||||
match self.first_child {
|
|
||||||
// transmute because the compiler can't deduce that the reference
|
|
||||||
// is safe outside of with_mut_base blocks.
|
|
||||||
Some(ref mut n) => Some(unsafe { cast::transmute(n) }),
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node<ScriptView> {
|
impl Node<ScriptView> {
|
||||||
|
// http://dom.spec.whatwg.org/#dom-node-nodetype
|
||||||
pub fn NodeType(&self) -> u16 {
|
pub fn NodeType(&self) -> u16 {
|
||||||
match self.type_id {
|
match self.type_id {
|
||||||
ElementNodeTypeId(_) => 1,
|
ElementNodeTypeId(_) => 1,
|
||||||
TextNodeTypeId => 3,
|
TextNodeTypeId => 3,
|
||||||
CommentNodeTypeId => 8,
|
CommentNodeTypeId => 8,
|
||||||
|
DocumentNodeTypeId(_)=> 9,
|
||||||
DoctypeNodeTypeId => 10,
|
DoctypeNodeTypeId => 10,
|
||||||
DocumentFragmentNodeTypeId => 11,
|
DocumentFragmentNodeTypeId => 11,
|
||||||
}
|
}
|
||||||
|
@ -592,6 +579,7 @@ impl Node<ScriptView> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DocumentFragmentNodeTypeId => ~"#document-fragment",
|
DocumentFragmentNodeTypeId => ~"#document-fragment",
|
||||||
|
DocumentNodeTypeId(_) => ~"#document"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +594,7 @@ impl Node<ScriptView> {
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
DoctypeNodeTypeId |
|
DoctypeNodeTypeId |
|
||||||
DocumentFragmentNodeTypeId => Some(self.owner_doc()),
|
DocumentFragmentNodeTypeId => Some(self.owner_doc()),
|
||||||
// DocumentNodeTypeId => None
|
DocumentNodeTypeId(_) => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,7 +663,7 @@ impl Node<ScriptView> {
|
||||||
characterdata.Data()
|
characterdata.Data()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DoctypeNodeTypeId => {
|
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,7 +711,7 @@ impl Node<ScriptView> {
|
||||||
|
|
||||||
// Step 1.
|
// Step 1.
|
||||||
match parent.type_id() {
|
match parent.type_id() {
|
||||||
// DocumentNodeTypeId |
|
DocumentNodeTypeId(*) |
|
||||||
DocumentFragmentNodeTypeId |
|
DocumentFragmentNodeTypeId |
|
||||||
ElementNodeTypeId(*) => (),
|
ElementNodeTypeId(*) => (),
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -754,21 +742,21 @@ impl Node<ScriptView> {
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
// ProcessingInstructionNodeTypeId |
|
// ProcessingInstructionNodeTypeId |
|
||||||
CommentNodeTypeId => (),
|
CommentNodeTypeId => (),
|
||||||
/*_ => { XXX #838
|
DocumentNodeTypeId(*) => return Err(HierarchyRequest),
|
||||||
return Err(HierarchyRequest);
|
|
||||||
},*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5.
|
// Step 5.
|
||||||
match node.type_id() {
|
match node.type_id() {
|
||||||
TextNodeTypeId => {
|
TextNodeTypeId => {
|
||||||
if false { // XXX #838
|
match node.parent_node() {
|
||||||
return Err(HierarchyRequest);
|
Some(parent) if parent.is_document() => return Err(HierarchyRequest),
|
||||||
|
_ => ()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DoctypeNodeTypeId => {
|
DoctypeNodeTypeId => {
|
||||||
if true { // XXX #838
|
match node.parent_node() {
|
||||||
return Err(HierarchyRequest);
|
Some(parent) if !parent.is_document() => return Err(HierarchyRequest),
|
||||||
|
_ => ()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -899,7 +887,7 @@ impl Node<ScriptView> {
|
||||||
document.document().content_changed();
|
document.document().content_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DoctypeNodeTypeId => {}
|
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ impl Page {
|
||||||
/// This function fails if there is no root frame.
|
/// This function fails if there is no root frame.
|
||||||
fn reflow(&mut self, goal: ReflowGoal, script_chan: ScriptChan, compositor: @ScriptListener) {
|
fn reflow(&mut self, goal: ReflowGoal, script_chan: ScriptChan, compositor: @ScriptListener) {
|
||||||
let root = match self.frame {
|
let root = match self.frame {
|
||||||
None => fail!(~"Tried to relayout with no root frame!"),
|
None => return,
|
||||||
Some(ref frame) => {
|
Some(ref frame) => {
|
||||||
frame.document.document().GetDocumentElement()
|
frame.document.document().GetDocumentElement()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="div1"></div>
|
<div id="div1"></div>
|
||||||
<script>
|
<script>
|
||||||
// FIXME: This should be HTMLDocument.
|
is_a(document.documentElement.parentNode, HTMLDocument);
|
||||||
//isnot(document.documentElement.parentNode, null);
|
|
||||||
is(document.documentElement.parentElement, null);
|
is(document.documentElement.parentElement, null);
|
||||||
|
|
||||||
var elem = document.createElement("p");
|
var elem = document.createElement("p");
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
<body>
|
<body>
|
||||||
<foo-á>foo</foo-á>
|
<foo-á>foo</foo-á>
|
||||||
<script>
|
<script>
|
||||||
|
gc(); // ensure that our document rooting works; subsequent accesses should be valid.
|
||||||
|
is_a(window.document, Node);
|
||||||
|
is(window.document.nodeType, Node.DOCUMENT_NODE);
|
||||||
is_a(window.document.documentElement, Node);
|
is_a(window.document.documentElement, Node);
|
||||||
is_a(window.document.documentElement, Element);
|
is_a(window.document.documentElement, Element);
|
||||||
is_a(window.document.documentElement, HTMLElement);
|
is_a(window.document.documentElement, HTMLElement);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue