mirror of
https://github.com/servo/servo.git
synced 2025-06-15 11:54:28 +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 gfx::font_context::FontContext;
|
||||||
use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId};
|
use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId};
|
||||||
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
|
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::computed_values::{display, position, float, white_space};
|
||||||
use style::ComputedValues;
|
use style::ComputedValues;
|
||||||
|
|
||||||
|
@ -633,7 +634,8 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
||||||
CommentNodeTypeId |
|
CommentNodeTypeId |
|
||||||
DoctypeNodeTypeId |
|
DoctypeNodeTypeId |
|
||||||
DocumentFragmentNodeTypeId |
|
DocumentFragmentNodeTypeId |
|
||||||
DocumentNodeTypeId(_) => (display::none, float::none, position::static_),
|
DocumentNodeTypeId(_) |
|
||||||
|
ProcessingInstructionNodeTypeId => (display::none, float::none, position::static_),
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("building flow for node: {:?} {:?}", display, float);
|
debug!("building flow for node: {:?} {:?}", display, float);
|
||||||
|
@ -701,6 +703,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
||||||
fn is_replaced_content(self) -> bool {
|
fn is_replaced_content(self) -> bool {
|
||||||
match self.type_id() {
|
match self.type_id() {
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
|
ProcessingInstructionNodeTypeId |
|
||||||
CommentNodeTypeId |
|
CommentNodeTypeId |
|
||||||
DoctypeNodeTypeId |
|
DoctypeNodeTypeId |
|
||||||
DocumentFragmentNodeTypeId |
|
DocumentFragmentNodeTypeId |
|
||||||
|
|
|
@ -583,6 +583,7 @@ def addExternalIface(iface, nativeType=None, headerFile=None, pointerType=None):
|
||||||
domInterface['pointerType'] = pointerType
|
domInterface['pointerType'] = pointerType
|
||||||
DOMInterfaces[iface] = domInterface
|
DOMInterfaces[iface] = domInterface
|
||||||
|
|
||||||
|
# FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625
|
||||||
def addHTMLElement(element, concrete=None, needsAbstract=[]):
|
def addHTMLElement(element, concrete=None, needsAbstract=[]):
|
||||||
DOMInterfaces[element] = {
|
DOMInterfaces[element] = {
|
||||||
'nativeType': 'AbstractNode',
|
'nativeType': 'AbstractNode',
|
||||||
|
@ -596,6 +597,7 @@ addHTMLElement('Comment')
|
||||||
addHTMLElement('DocumentFragment', concrete='DocumentFragment')
|
addHTMLElement('DocumentFragment', concrete='DocumentFragment')
|
||||||
addHTMLElement('DocumentType')
|
addHTMLElement('DocumentType')
|
||||||
addHTMLElement('Text')
|
addHTMLElement('Text')
|
||||||
|
addHTMLElement('ProcessingInstruction')
|
||||||
|
|
||||||
addHTMLElement('HTMLAnchorElement')
|
addHTMLElement('HTMLAnchorElement')
|
||||||
addHTMLElement('HTMLAppletElement')
|
addHTMLElement('HTMLAppletElement')
|
||||||
|
|
|
@ -107,6 +107,9 @@ generate_traceable_node!(DocumentType)
|
||||||
generate_cacheable_wrapper!(Text, TextBinding::Wrap)
|
generate_cacheable_wrapper!(Text, TextBinding::Wrap)
|
||||||
generate_traceable!(Text)
|
generate_traceable!(Text)
|
||||||
|
|
||||||
|
generate_cacheable_wrapper!(ProcessingInstruction, ProcessingInstruction::Wrap)
|
||||||
|
generate_traceable!(ProcessingInstruction)
|
||||||
|
|
||||||
generate_cacheable_wrapper_htmlelement!(HTMLHeadElement, HTMLHeadElementBinding::Wrap)
|
generate_cacheable_wrapper_htmlelement!(HTMLHeadElement, HTMLHeadElementBinding::Wrap)
|
||||||
generate_traceable_htmlelement!(HTMLHeadElement)
|
generate_traceable_htmlelement!(HTMLHeadElement)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
use servo_util::namespace;
|
use servo_util::namespace;
|
||||||
use dom::attr::Attr;
|
use dom::attr::Attr;
|
||||||
use dom::node::NodeIterator;
|
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 {
|
pub fn serialize(iterator: &mut NodeIterator) -> ~str {
|
||||||
let mut html = ~"";
|
let mut html = ~"";
|
||||||
|
@ -29,6 +31,9 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
|
||||||
DoctypeNodeTypeId => {
|
DoctypeNodeTypeId => {
|
||||||
serialize_doctype(node)
|
serialize_doctype(node)
|
||||||
}
|
}
|
||||||
|
ProcessingInstructionNodeTypeId => {
|
||||||
|
serialize_processing_instruction(node)
|
||||||
|
}
|
||||||
DocumentFragmentNodeTypeId => {
|
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 {
|
fn serialize_doctype(node: AbstractNode) -> ~str {
|
||||||
node.with_imm_doctype(|doctype| {
|
node.with_imm_doctype(|doctype| {
|
||||||
~"<!DOCTYPE" + doctype.name + ">"
|
~"<!DOCTYPE" + doctype.name + ">"
|
||||||
|
|
|
@ -18,6 +18,7 @@ use dom::htmliframeelement::HTMLIFrameElement;
|
||||||
use dom::htmlimageelement::HTMLImageElement;
|
use dom::htmlimageelement::HTMLImageElement;
|
||||||
use dom::nodelist::{NodeList};
|
use dom::nodelist::{NodeList};
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
|
use dom::processinginstruction::ProcessingInstruction;
|
||||||
use layout_interface::{LayoutChan, ReapLayoutDataMsg, UntrustedNodeAddress};
|
use layout_interface::{LayoutChan, ReapLayoutDataMsg, UntrustedNodeAddress};
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||||
|
@ -199,6 +200,7 @@ pub enum NodeTypeId {
|
||||||
DocumentNodeTypeId(DocumentTypeId),
|
DocumentNodeTypeId(DocumentTypeId),
|
||||||
ElementNodeTypeId(ElementTypeId),
|
ElementNodeTypeId(ElementTypeId),
|
||||||
TextNodeTypeId,
|
TextNodeTypeId,
|
||||||
|
ProcessingInstructionNodeTypeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for AbstractNode {
|
impl Clone for AbstractNode {
|
||||||
|
@ -362,8 +364,7 @@ impl<'a> AbstractNode {
|
||||||
|
|
||||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||||
pub fn is_characterdata(self) -> bool {
|
pub fn is_characterdata(self) -> bool {
|
||||||
// FIXME: ProcessingInstruction
|
self.is_text() || self.is_comment() || self.is_processing_instruction()
|
||||||
self.is_text() || self.is_comment()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R {
|
pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R {
|
||||||
|
@ -432,6 +433,18 @@ impl<'a> AbstractNode {
|
||||||
self.transmute_mut(f)
|
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.
|
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||||
pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R {
|
pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R {
|
||||||
if !self.is_element() {
|
if !self.is_element() {
|
||||||
|
@ -920,8 +933,9 @@ impl Node {
|
||||||
match self.type_id {
|
match self.type_id {
|
||||||
ElementNodeTypeId(_) => 1,
|
ElementNodeTypeId(_) => 1,
|
||||||
TextNodeTypeId => 3,
|
TextNodeTypeId => 3,
|
||||||
|
ProcessingInstructionNodeTypeId => 7,
|
||||||
CommentNodeTypeId => 8,
|
CommentNodeTypeId => 8,
|
||||||
DocumentNodeTypeId(_)=> 9,
|
DocumentNodeTypeId(_) => 9,
|
||||||
DoctypeNodeTypeId => 10,
|
DoctypeNodeTypeId => 10,
|
||||||
DocumentFragmentNodeTypeId => 11,
|
DocumentFragmentNodeTypeId => 11,
|
||||||
}
|
}
|
||||||
|
@ -934,8 +948,13 @@ impl Node {
|
||||||
element.TagName()
|
element.TagName()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
CommentNodeTypeId => ~"#comment",
|
|
||||||
TextNodeTypeId => ~"#text",
|
TextNodeTypeId => ~"#text",
|
||||||
|
ProcessingInstructionNodeTypeId => {
|
||||||
|
abstract_self.with_imm_processing_instruction(|processing_instruction| {
|
||||||
|
processing_instruction.Target()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CommentNodeTypeId => ~"#comment",
|
||||||
DoctypeNodeTypeId => {
|
DoctypeNodeTypeId => {
|
||||||
abstract_self.with_imm_doctype(|doctype| {
|
abstract_self.with_imm_doctype(|doctype| {
|
||||||
doctype.name.clone()
|
doctype.name.clone()
|
||||||
|
@ -955,6 +974,7 @@ impl Node {
|
||||||
ElementNodeTypeId(..) |
|
ElementNodeTypeId(..) |
|
||||||
CommentNodeTypeId |
|
CommentNodeTypeId |
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
|
ProcessingInstructionNodeTypeId |
|
||||||
DoctypeNodeTypeId |
|
DoctypeNodeTypeId |
|
||||||
DocumentFragmentNodeTypeId => Some(self.owner_doc()),
|
DocumentFragmentNodeTypeId => Some(self.owner_doc()),
|
||||||
DocumentNodeTypeId(_) => None
|
DocumentNodeTypeId(_) => None
|
||||||
|
@ -991,8 +1011,9 @@ impl Node {
|
||||||
|
|
||||||
pub fn GetNodeValue(&self, abstract_self: AbstractNode) -> Option<DOMString> {
|
pub fn GetNodeValue(&self, abstract_self: AbstractNode) -> Option<DOMString> {
|
||||||
match self.type_id {
|
match self.type_id {
|
||||||
// ProcessingInstruction
|
CommentNodeTypeId |
|
||||||
CommentNodeTypeId | TextNodeTypeId => {
|
TextNodeTypeId |
|
||||||
|
ProcessingInstructionNodeTypeId => {
|
||||||
abstract_self.with_imm_characterdata(|characterdata| {
|
abstract_self.with_imm_characterdata(|characterdata| {
|
||||||
Some(characterdata.Data())
|
Some(characterdata.Data())
|
||||||
})
|
})
|
||||||
|
@ -1010,7 +1031,8 @@ impl Node {
|
||||||
|
|
||||||
pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> {
|
pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> {
|
||||||
match self.type_id {
|
match self.type_id {
|
||||||
DocumentFragmentNodeTypeId | 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() {
|
||||||
|
@ -1021,12 +1043,15 @@ impl Node {
|
||||||
}
|
}
|
||||||
Some(content)
|
Some(content)
|
||||||
}
|
}
|
||||||
CommentNodeTypeId | TextNodeTypeId => {
|
CommentNodeTypeId |
|
||||||
|
TextNodeTypeId |
|
||||||
|
ProcessingInstructionNodeTypeId => {
|
||||||
abstract_self.with_imm_characterdata(|characterdata| {
|
abstract_self.with_imm_characterdata(|characterdata| {
|
||||||
Some(characterdata.Data())
|
Some(characterdata.Data())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
|
DoctypeNodeTypeId |
|
||||||
|
DocumentNodeTypeId(_) => {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1126,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
DocumentFragmentNodeTypeId |
|
DocumentFragmentNodeTypeId |
|
||||||
ElementNodeTypeId(_) |
|
ElementNodeTypeId(_) |
|
||||||
// ProcessingInstructionNodeTypeId |
|
ProcessingInstructionNodeTypeId |
|
||||||
CommentNodeTypeId => (),
|
CommentNodeTypeId => (),
|
||||||
DocumentNodeTypeId(..) => return Err(HierarchyRequest)
|
DocumentNodeTypeId(..) => return Err(HierarchyRequest)
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1200,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
// ProcessingInstructionNodeTypeId |
|
ProcessingInstructionNodeTypeId |
|
||||||
CommentNodeTypeId => (),
|
CommentNodeTypeId => (),
|
||||||
DocumentNodeTypeId(_) => unreachable!(),
|
DocumentNodeTypeId(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -1319,7 +1344,8 @@ impl Node {
|
||||||
-> ErrorResult {
|
-> ErrorResult {
|
||||||
let value = null_str_as_empty(&value);
|
let value = null_str_as_empty(&value);
|
||||||
match self.type_id {
|
match self.type_id {
|
||||||
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
|
DocumentFragmentNodeTypeId |
|
||||||
|
ElementNodeTypeId(..) => {
|
||||||
// Step 1-2.
|
// Step 1-2.
|
||||||
let node = if value.len() == 0 {
|
let node = if value.len() == 0 {
|
||||||
None
|
None
|
||||||
|
@ -1330,7 +1356,9 @@ impl Node {
|
||||||
// Step 3.
|
// Step 3.
|
||||||
Node::replace_all(node, abstract_self);
|
Node::replace_all(node, abstract_self);
|
||||||
}
|
}
|
||||||
CommentNodeTypeId | TextNodeTypeId => {
|
CommentNodeTypeId |
|
||||||
|
TextNodeTypeId |
|
||||||
|
ProcessingInstructionNodeTypeId => {
|
||||||
self.wait_until_safe_to_modify_dom();
|
self.wait_until_safe_to_modify_dom();
|
||||||
|
|
||||||
abstract_self.with_mut_characterdata(|characterdata| {
|
abstract_self.with_mut_characterdata(|characterdata| {
|
||||||
|
@ -1341,7 +1369,8 @@ impl Node {
|
||||||
document.document().content_changed();
|
document.document().content_changed();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
|
DoctypeNodeTypeId |
|
||||||
|
DocumentNodeTypeId(_) => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1390,7 +1419,7 @@ impl Node {
|
||||||
DoctypeNodeTypeId |
|
DoctypeNodeTypeId |
|
||||||
ElementNodeTypeId(..) |
|
ElementNodeTypeId(..) |
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
// ProcessingInstructionNodeTypeId |
|
ProcessingInstructionNodeTypeId |
|
||||||
CommentNodeTypeId => (),
|
CommentNodeTypeId => (),
|
||||||
DocumentNodeTypeId(..) => return Err(HierarchyRequest)
|
DocumentNodeTypeId(..) => return Err(HierarchyRequest)
|
||||||
}
|
}
|
||||||
|
@ -1443,7 +1472,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TextNodeTypeId |
|
TextNodeTypeId |
|
||||||
// ProcessingInstructionNodeTypeId |
|
ProcessingInstructionNodeTypeId |
|
||||||
CommentNodeTypeId => (),
|
CommentNodeTypeId => (),
|
||||||
DocumentNodeTypeId(..) => unreachable!()
|
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 navigator;
|
||||||
pub mod node;
|
pub mod node;
|
||||||
pub mod nodelist;
|
pub mod nodelist;
|
||||||
|
pub mod processinginstruction;
|
||||||
pub mod uievent;
|
pub mod uievent;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod validitystate;
|
pub mod validitystate;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue