mirror of
https://github.com/servo/servo.git
synced 2025-06-10 09:33:13 +00:00
Implement ProcessingInstruction DOM interface
Spec: http://dom.spec.whatwg.org/#interface-processinginstruction Closes #1619.
This commit is contained in:
parent
5a7d22c437
commit
aa4b5bb948
8 changed files with 153 additions and 56 deletions
|
@ -36,7 +36,8 @@ use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNo
|
|||
use gfx::font_context::FontContext;
|
||||
use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId};
|
||||
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
|
||||
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, TextNodeTypeId};
|
||||
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
|
||||
use script::dom::node::{TextNodeTypeId};
|
||||
use style::computed_values::{display, position, float, white_space};
|
||||
use style::ComputedValues;
|
||||
|
||||
|
@ -633,7 +634,8 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
|||
CommentNodeTypeId |
|
||||
DoctypeNodeTypeId |
|
||||
DocumentFragmentNodeTypeId |
|
||||
DocumentNodeTypeId(_) => (display::none, float::none, position::static_),
|
||||
DocumentNodeTypeId(_) |
|
||||
ProcessingInstructionNodeTypeId => (display::none, float::none, position::static_),
|
||||
};
|
||||
|
||||
debug!("building flow for node: {:?} {:?}", display, float);
|
||||
|
@ -701,6 +703,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
|||
fn is_replaced_content(self) -> bool {
|
||||
match self.type_id() {
|
||||
TextNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId |
|
||||
DoctypeNodeTypeId |
|
||||
DocumentFragmentNodeTypeId |
|
||||
|
|
|
@ -583,6 +583,7 @@ def addExternalIface(iface, nativeType=None, headerFile=None, pointerType=None):
|
|||
domInterface['pointerType'] = pointerType
|
||||
DOMInterfaces[iface] = domInterface
|
||||
|
||||
# FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625
|
||||
def addHTMLElement(element, concrete=None, needsAbstract=[]):
|
||||
DOMInterfaces[element] = {
|
||||
'nativeType': 'AbstractNode',
|
||||
|
@ -596,6 +597,7 @@ addHTMLElement('Comment')
|
|||
addHTMLElement('DocumentFragment', concrete='DocumentFragment')
|
||||
addHTMLElement('DocumentType')
|
||||
addHTMLElement('Text')
|
||||
addHTMLElement('ProcessingInstruction')
|
||||
|
||||
addHTMLElement('HTMLAnchorElement')
|
||||
addHTMLElement('HTMLAppletElement')
|
||||
|
|
|
@ -107,6 +107,9 @@ generate_traceable_node!(DocumentType)
|
|||
generate_cacheable_wrapper!(Text, TextBinding::Wrap)
|
||||
generate_traceable!(Text)
|
||||
|
||||
generate_cacheable_wrapper!(ProcessingInstruction, ProcessingInstruction::Wrap)
|
||||
generate_traceable!(ProcessingInstruction)
|
||||
|
||||
generate_cacheable_wrapper_htmlelement!(HTMLHeadElement, HTMLHeadElementBinding::Wrap)
|
||||
generate_traceable_htmlelement!(HTMLHeadElement)
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
use servo_util::namespace;
|
||||
use dom::attr::Attr;
|
||||
use dom::node::NodeIterator;
|
||||
use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, CommentNodeTypeId, DocumentNodeTypeId, ElementNodeTypeId, TextNodeTypeId, AbstractNode};
|
||||
use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, CommentNodeTypeId};
|
||||
use dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
|
||||
use dom::node::{TextNodeTypeId, AbstractNode};
|
||||
|
||||
pub fn serialize(iterator: &mut NodeIterator) -> ~str {
|
||||
let mut html = ~"";
|
||||
|
@ -29,6 +31,9 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
|
|||
DoctypeNodeTypeId => {
|
||||
serialize_doctype(node)
|
||||
}
|
||||
ProcessingInstructionNodeTypeId => {
|
||||
serialize_processing_instruction(node)
|
||||
}
|
||||
DocumentFragmentNodeTypeId => {
|
||||
~""
|
||||
}
|
||||
|
@ -70,6 +75,12 @@ fn serialize_text(node: AbstractNode) -> ~str {
|
|||
})
|
||||
}
|
||||
|
||||
fn serialize_processing_instruction(node: AbstractNode) -> ~str {
|
||||
node.with_imm_processing_instruction(|processing_instruction| {
|
||||
~"<?" + processing_instruction.target + " " + processing_instruction.element.data + "?>"
|
||||
})
|
||||
}
|
||||
|
||||
fn serialize_doctype(node: AbstractNode) -> ~str {
|
||||
node.with_imm_doctype(|doctype| {
|
||||
~"<!DOCTYPE" + doctype.name + ">"
|
||||
|
|
|
@ -18,6 +18,7 @@ use dom::htmliframeelement::HTMLIFrameElement;
|
|||
use dom::htmlimageelement::HTMLImageElement;
|
||||
use dom::nodelist::{NodeList};
|
||||
use dom::text::Text;
|
||||
use dom::processinginstruction::ProcessingInstruction;
|
||||
use layout_interface::{LayoutChan, ReapLayoutDataMsg, UntrustedNodeAddress};
|
||||
|
||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||
|
@ -199,6 +200,7 @@ pub enum NodeTypeId {
|
|||
DocumentNodeTypeId(DocumentTypeId),
|
||||
ElementNodeTypeId(ElementTypeId),
|
||||
TextNodeTypeId,
|
||||
ProcessingInstructionNodeTypeId,
|
||||
}
|
||||
|
||||
impl Clone for AbstractNode {
|
||||
|
@ -362,8 +364,7 @@ impl<'a> AbstractNode {
|
|||
|
||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||
pub fn is_characterdata(self) -> bool {
|
||||
// FIXME: ProcessingInstruction
|
||||
self.is_text() || self.is_comment()
|
||||
self.is_text() || self.is_comment() || self.is_processing_instruction()
|
||||
}
|
||||
|
||||
pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R {
|
||||
|
@ -432,6 +433,18 @@ impl<'a> AbstractNode {
|
|||
self.transmute_mut(f)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_processing_instruction(self) -> bool {
|
||||
self.type_id() == ProcessingInstructionNodeTypeId
|
||||
}
|
||||
|
||||
pub fn with_imm_processing_instruction<R>(self, f: |&ProcessingInstruction| -> R) -> R {
|
||||
if !self.is_processing_instruction() {
|
||||
fail!("node is not processing instruction");
|
||||
}
|
||||
self.transmute(f)
|
||||
}
|
||||
|
||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||
pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R {
|
||||
if !self.is_element() {
|
||||
|
@ -920,8 +933,9 @@ impl Node {
|
|||
match self.type_id {
|
||||
ElementNodeTypeId(_) => 1,
|
||||
TextNodeTypeId => 3,
|
||||
ProcessingInstructionNodeTypeId => 7,
|
||||
CommentNodeTypeId => 8,
|
||||
DocumentNodeTypeId(_)=> 9,
|
||||
DocumentNodeTypeId(_) => 9,
|
||||
DoctypeNodeTypeId => 10,
|
||||
DocumentFragmentNodeTypeId => 11,
|
||||
}
|
||||
|
@ -934,8 +948,13 @@ impl Node {
|
|||
element.TagName()
|
||||
})
|
||||
}
|
||||
CommentNodeTypeId => ~"#comment",
|
||||
TextNodeTypeId => ~"#text",
|
||||
ProcessingInstructionNodeTypeId => {
|
||||
abstract_self.with_imm_processing_instruction(|processing_instruction| {
|
||||
processing_instruction.Target()
|
||||
})
|
||||
}
|
||||
CommentNodeTypeId => ~"#comment",
|
||||
DoctypeNodeTypeId => {
|
||||
abstract_self.with_imm_doctype(|doctype| {
|
||||
doctype.name.clone()
|
||||
|
@ -955,6 +974,7 @@ impl Node {
|
|||
ElementNodeTypeId(..) |
|
||||
CommentNodeTypeId |
|
||||
TextNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId |
|
||||
DoctypeNodeTypeId |
|
||||
DocumentFragmentNodeTypeId => Some(self.owner_doc()),
|
||||
DocumentNodeTypeId(_) => None
|
||||
|
@ -991,8 +1011,9 @@ impl Node {
|
|||
|
||||
pub fn GetNodeValue(&self, abstract_self: AbstractNode) -> Option<DOMString> {
|
||||
match self.type_id {
|
||||
// ProcessingInstruction
|
||||
CommentNodeTypeId | TextNodeTypeId => {
|
||||
CommentNodeTypeId |
|
||||
TextNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId => {
|
||||
abstract_self.with_imm_characterdata(|characterdata| {
|
||||
Some(characterdata.Data())
|
||||
})
|
||||
|
@ -1010,7 +1031,8 @@ 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() {
|
||||
|
@ -1021,12 +1043,15 @@ impl Node {
|
|||
}
|
||||
Some(content)
|
||||
}
|
||||
CommentNodeTypeId | TextNodeTypeId => {
|
||||
CommentNodeTypeId |
|
||||
TextNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId => {
|
||||
abstract_self.with_imm_characterdata(|characterdata| {
|
||||
Some(characterdata.Data())
|
||||
})
|
||||
}
|
||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
|
||||
DoctypeNodeTypeId |
|
||||
DocumentNodeTypeId(_) => {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -1101,7 +1126,7 @@ impl Node {
|
|||
}
|
||||
DocumentFragmentNodeTypeId |
|
||||
ElementNodeTypeId(_) |
|
||||
// ProcessingInstructionNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId => (),
|
||||
DocumentNodeTypeId(..) => return Err(HierarchyRequest)
|
||||
}
|
||||
|
@ -1175,7 +1200,7 @@ impl Node {
|
|||
}
|
||||
},
|
||||
TextNodeTypeId |
|
||||
// ProcessingInstructionNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId => (),
|
||||
DocumentNodeTypeId(_) => unreachable!(),
|
||||
}
|
||||
|
@ -1319,7 +1344,8 @@ 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
|
||||
|
@ -1330,7 +1356,9 @@ impl Node {
|
|||
// Step 3.
|
||||
Node::replace_all(node, abstract_self);
|
||||
}
|
||||
CommentNodeTypeId | TextNodeTypeId => {
|
||||
CommentNodeTypeId |
|
||||
TextNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId => {
|
||||
self.wait_until_safe_to_modify_dom();
|
||||
|
||||
abstract_self.with_mut_characterdata(|characterdata| {
|
||||
|
@ -1341,7 +1369,8 @@ impl Node {
|
|||
document.document().content_changed();
|
||||
})
|
||||
}
|
||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
|
||||
DoctypeNodeTypeId |
|
||||
DocumentNodeTypeId(_) => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1390,7 +1419,7 @@ impl Node {
|
|||
DoctypeNodeTypeId |
|
||||
ElementNodeTypeId(..) |
|
||||
TextNodeTypeId |
|
||||
// ProcessingInstructionNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId => (),
|
||||
DocumentNodeTypeId(..) => return Err(HierarchyRequest)
|
||||
}
|
||||
|
@ -1443,7 +1472,7 @@ impl Node {
|
|||
}
|
||||
},
|
||||
TextNodeTypeId |
|
||||
// ProcessingInstructionNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId => (),
|
||||
DocumentNodeTypeId(..) => unreachable!()
|
||||
}
|
||||
|
|
36
src/components/script/dom/processinginstruction.rs
Normal file
36
src/components/script/dom/processinginstruction.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* 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::codegen::ProcessingInstructionBinding;
|
||||
use dom::bindings::utils::DOMString;
|
||||
use dom::characterdata::CharacterData;
|
||||
use dom::document::AbstractDocument;
|
||||
use dom::node::{AbstractNode, Node, ProcessingInstructionNodeTypeId};
|
||||
|
||||
/// An HTML processing instruction node.
|
||||
pub struct ProcessingInstruction {
|
||||
// FIXME: s/element/characterdata/ https://github.com/mozilla/servo/issues/1594
|
||||
element: CharacterData,
|
||||
target: DOMString,
|
||||
}
|
||||
|
||||
impl ProcessingInstruction {
|
||||
pub fn new_inherited(target: DOMString, data: DOMString, document: AbstractDocument) -> ProcessingInstruction {
|
||||
ProcessingInstruction {
|
||||
element: CharacterData::new_inherited(ProcessingInstructionNodeTypeId, data, document),
|
||||
target: target
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(target: DOMString, data: DOMString, document: AbstractDocument) -> AbstractNode {
|
||||
let node = ProcessingInstruction::new_inherited(target, data, document);
|
||||
Node::reflect_node(@mut node, document, ProcessingInstructionBinding::Wrap)
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessingInstruction {
|
||||
pub fn Target(&self) -> DOMString {
|
||||
self.target.clone()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* -*- 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dom.spec.whatwg.org/#interface-processinginstruction
|
||||
*/
|
||||
|
||||
interface ProcessingInstruction : CharacterData {
|
||||
readonly attribute DOMString target;
|
||||
};
|
|
@ -140,6 +140,7 @@ pub mod dom {
|
|||
pub mod navigator;
|
||||
pub mod node;
|
||||
pub mod nodelist;
|
||||
pub mod processinginstruction;
|
||||
pub mod uievent;
|
||||
pub mod text;
|
||||
pub mod validitystate;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue