Implement DocumentFragment.

This commit is contained in:
Ms2ger 2013-10-12 11:39:44 +02:00
parent fc9fdf30a6
commit 438d121cd8
10 changed files with 78 additions and 15 deletions

View file

@ -27,6 +27,7 @@ use newcss::values::{CSSFloatNone, CSSFloatLeft, CSSFloatRight};
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};
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};
use std::cell::Cell; use std::cell::Cell;
@ -398,7 +399,9 @@ impl LayoutTreeBuilder {
ElementNodeTypeId(_) => CSSDisplayInline, ElementNodeTypeId(_) => CSSDisplayInline,
TextNodeTypeId => CSSDisplayInline, TextNodeTypeId => CSSDisplayInline,
DoctypeNodeTypeId | CommentNodeTypeId => return NoGenerator, DoctypeNodeTypeId |
DocumentFragmentNodeTypeId |
CommentNodeTypeId => return NoGenerator,
} }
}; };

View file

@ -141,10 +141,16 @@ DOMInterfaces = {
}, },
'Document': { 'Document': {
'nativeType': 'AbstractDocument', 'nativeType': 'AbstractDocument',
'pointerType': '', 'pointerType': '',
'customTrace': 'trace', 'customTrace': 'trace',
'needsAbstract': ['title', 'createElement', 'createTextNode', 'createComment'], 'needsAbstract': [
'createComment',
'createDocumentFragment',
'createElement',
'createTextNode',
'title',
],
}, },
'DOMParser': { 'DOMParser': {
@ -568,6 +574,7 @@ def addHTMLElement(element, concrete=None, needsAbstract=[]):
} }
addHTMLElement('Comment') addHTMLElement('Comment')
addHTMLElement('DocumentFragment', concrete='DocumentFragment<ScriptView>')
addHTMLElement('DocumentType', concrete='DocumentType<ScriptView>') addHTMLElement('DocumentType', concrete='DocumentType<ScriptView>')
addHTMLElement('Text') addHTMLElement('Text')

View file

@ -44,8 +44,8 @@ interface Document /*: Node*/ { //XXXjdm Requires servo/#623
Element createElement(DOMString localName); Element createElement(DOMString localName);
[Creator, Throws] [Creator, Throws]
Element createElementNS(DOMString? namespace, DOMString qualifiedName); Element createElementNS(DOMString? namespace, DOMString qualifiedName);
/*[Creator] [Creator]
DocumentFragment createDocumentFragment();*/ DocumentFragment createDocumentFragment();
[Creator] [Creator]
Text createTextNode(DOMString data); Text createTextNode(DOMString data);
[Creator] [Creator]

View file

@ -0,0 +1,9 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// http://dom.spec.whatwg.org/#interface-documentfragment
[Constructor]
interface DocumentFragment : Node {
};

View file

@ -129,6 +129,9 @@ macro_rules! generate_traceable_node(
generate_cacheable_wrapper!(Comment, CommentBinding::Wrap) generate_cacheable_wrapper!(Comment, CommentBinding::Wrap)
generate_binding_object!(Comment) generate_binding_object!(Comment)
generate_traceable!(Comment) generate_traceable!(Comment)
generate_cacheable_wrapper_node!(DocumentFragment<ScriptView>, DocumentFragmentBinding::Wrap)
generate_binding_object_node!(DocumentFragment<ScriptView>)
generate_traceable_node!(DocumentFragment<ScriptView>)
generate_cacheable_wrapper_node!(DocumentType<ScriptView>, DocumentTypeBinding::Wrap) generate_cacheable_wrapper_node!(DocumentType<ScriptView>, DocumentTypeBinding::Wrap)
generate_binding_object_node!(DocumentType<ScriptView>) generate_binding_object_node!(DocumentType<ScriptView>)
generate_traceable_node!(DocumentType<ScriptView>) generate_traceable_node!(DocumentType<ScriptView>)

View file

@ -6,7 +6,7 @@ use dom::bindings::utils::{Reflectable, Reflector, Traceable};
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, ScriptView}; use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, ScriptView};
use std::cast; use std::cast;
use std::libc; use std::libc;
@ -91,8 +91,9 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject
ElementNodeTypeId(HTMLUnknownElementTypeId) => generate_element!(HTMLUnknownElement), ElementNodeTypeId(HTMLUnknownElementTypeId) => generate_element!(HTMLUnknownElement),
CommentNodeTypeId => generate_element!(Comment), CommentNodeTypeId => generate_element!(Comment),
DoctypeNodeTypeId => generate_element!(DocumentType<ScriptView>), DoctypeNodeTypeId => generate_element!(DocumentType<ScriptView>),
TextNodeTypeId => generate_element!(Text) DocumentFragmentNodeTypeId => generate_element!(DocumentFragment<ScriptView>),
} TextNodeTypeId => generate_element!(Text),
}
} }
impl Reflectable for AbstractNode<ScriptView> { impl Reflectable for AbstractNode<ScriptView> {

View file

@ -7,6 +7,7 @@ use dom::bindings::codegen::DocumentBinding;
use dom::bindings::utils::{DOMString, Reflector, ErrorResult, Fallible}; use dom::bindings::utils::{DOMString, Reflector, ErrorResult, Fallible};
use dom::bindings::utils::{BindingObject, Reflectable, DerivedWrapper}; use dom::bindings::utils::{BindingObject, Reflectable, 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::element::{Element}; use dom::element::{Element};
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId}; use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::event::Event; use dom::event::Event;
@ -283,6 +284,12 @@ impl Document {
fail!("stub") fail!("stub")
} }
pub fn CreateDocumentFragment(&self, abstract_self: AbstractDocument) -> AbstractNode<ScriptView> {
let cx = self.get_cx();
let fragment = @DocumentFragment::new(abstract_self);
unsafe { Node::as_abstract_node(cx, fragment) }
}
pub fn CreateTextNode(&self, abstract_self: AbstractDocument, data: &DOMString) -> AbstractNode<ScriptView> { pub fn CreateTextNode(&self, abstract_self: AbstractDocument, data: &DOMString) -> AbstractNode<ScriptView> {
let cx = self.get_cx(); let cx = self.get_cx();
let text = @Text::new(null_str_as_empty(data), abstract_self); let text = @Text::new(null_str_as_empty(data), abstract_self);

View file

@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::utils::Fallible;
use dom::document::AbstractDocument;
use dom::node::{ScriptView, Node, DocumentFragmentNodeTypeId};
use dom::node::{AbstractNode};
use dom::window::Window;
pub struct DocumentFragment<View> {
node: Node<View>,
}
impl DocumentFragment<ScriptView> {
/// Creates a new DocumentFragment.
pub fn new(document: AbstractDocument) -> DocumentFragment<ScriptView> {
DocumentFragment {
node: Node::new(DocumentFragmentNodeTypeId, document),
}
}
pub fn Constructor(owner: @mut Window) -> Fallible<AbstractNode<ScriptView>> {
let cx = (*owner.page).js_info.get_ref().js_compartment.cx.ptr;
let fragment = @DocumentFragment::new(owner.Document());
Ok(unsafe { Node::as_abstract_node(cx, fragment) })
}
}

View file

@ -101,6 +101,7 @@ pub struct Node<View> {
#[deriving(Eq)] #[deriving(Eq)]
pub enum NodeTypeId { pub enum NodeTypeId {
DoctypeNodeTypeId, DoctypeNodeTypeId,
DocumentFragmentNodeTypeId,
CommentNodeTypeId, CommentNodeTypeId,
ElementNodeTypeId(ElementTypeId), ElementNodeTypeId(ElementTypeId),
TextNodeTypeId, TextNodeTypeId,
@ -531,7 +532,8 @@ impl Node<ScriptView> {
ElementNodeTypeId(_) => 1, ElementNodeTypeId(_) => 1,
TextNodeTypeId => 3, TextNodeTypeId => 3,
CommentNodeTypeId => 8, CommentNodeTypeId => 8,
DoctypeNodeTypeId => 10 DoctypeNodeTypeId => 10,
DocumentFragmentNodeTypeId => 11,
} }
} }
@ -548,7 +550,8 @@ impl Node<ScriptView> {
do abstract_self.with_imm_doctype |doctype| { do abstract_self.with_imm_doctype |doctype| {
doctype.name.clone() doctype.name.clone()
} }
} },
DocumentFragmentNodeTypeId => ~"#document-fragment",
}) })
} }
@ -561,7 +564,8 @@ impl Node<ScriptView> {
ElementNodeTypeId(*) | ElementNodeTypeId(*) |
CommentNodeTypeId | CommentNodeTypeId |
TextNodeTypeId | TextNodeTypeId |
DoctypeNodeTypeId => Some(self.owner_doc), DoctypeNodeTypeId |
DocumentFragmentNodeTypeId => Some(self.owner_doc),
// DocumentNodeTypeId => None // DocumentNodeTypeId => None
} }
} }
@ -614,7 +618,7 @@ impl Node<ScriptView> {
pub fn GetTextContent(&self, abstract_self: AbstractNode<ScriptView>) -> DOMString { pub fn GetTextContent(&self, abstract_self: AbstractNode<ScriptView>) -> DOMString {
match self.type_id { match self.type_id {
ElementNodeTypeId(*) => { DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
let mut content = ~""; let mut content = ~"";
for node in abstract_self.traverse_preorder() { for node in abstract_self.traverse_preorder() {
if node.is_text() { if node.is_text() {
@ -679,7 +683,7 @@ impl Node<ScriptView> {
_ => false _ => false
}; };
match self.type_id { match self.type_id {
ElementNodeTypeId(*) => { DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
let node = if is_empty { let node = if is_empty {
None None
} else { } else {

View file

@ -50,6 +50,7 @@ pub mod dom {
pub mod clientrectlist; pub mod clientrectlist;
pub mod comment; pub mod comment;
pub mod document; pub mod document;
pub mod documentfragment;
pub mod documenttype; pub mod documenttype;
pub mod domparser; pub mod domparser;
pub mod element; pub mod element;