Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ProcessingInstruction DOM interface #1620

Merged
merged 1 commit into from Feb 6, 2014
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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() {
@@ -918,12 +931,13 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-nodetype
pub fn NodeType(&self) -> u16 {
match self.type_id {
ElementNodeTypeId(_) => 1,
TextNodeTypeId => 3,
CommentNodeTypeId => 8,
DocumentNodeTypeId(_)=> 9,
DoctypeNodeTypeId => 10,
DocumentFragmentNodeTypeId => 11,
ElementNodeTypeId(_) => 1,
TextNodeTypeId => 3,
ProcessingInstructionNodeTypeId => 7,
CommentNodeTypeId => 8,
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,25 +1031,29 @@ impl Node {

pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> {
match self.type_id {
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
let mut content = ~"";
for node in abstract_self.traverse_preorder() {
if node.is_text() {
node.with_imm_text(|text| {
content = content + text.element.Data();
})
DocumentFragmentNodeTypeId |
ElementNodeTypeId(..) => {
let mut content = ~"";
for node in abstract_self.traverse_preorder() {
if node.is_text() {
node.with_imm_text(|text| {
content = content + text.element.Data();
})
}
}
Some(content)
}
CommentNodeTypeId |
TextNodeTypeId |
ProcessingInstructionNodeTypeId => {
abstract_self.with_imm_characterdata(|characterdata| {
Some(characterdata.Data())
})
}
DoctypeNodeTypeId |
DocumentNodeTypeId(_) => {
None
}
Some(content)
}
CommentNodeTypeId | TextNodeTypeId => {
abstract_self.with_imm_characterdata(|characterdata| {
Some(characterdata.Data())
})
}
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,29 +1344,33 @@ impl Node {
-> ErrorResult {
let value = null_str_as_empty(&value);
match self.type_id {
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
// Step 1-2.
let node = if value.len() == 0 {
None
} else {
let document = self.owner_doc();
Some(document.document().CreateTextNode(document, value))
};
// Step 3.
Node::replace_all(node, abstract_self);
}
CommentNodeTypeId | TextNodeTypeId => {
self.wait_until_safe_to_modify_dom();

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(_) => {}
DocumentFragmentNodeTypeId |
ElementNodeTypeId(..) => {
// Step 1-2.
let node = if value.len() == 0 {
None
} else {
let document = self.owner_doc();
Some(document.document().CreateTextNode(document, value))
};
// Step 3.
Node::replace_all(node, abstract_self);
}
CommentNodeTypeId |
TextNodeTypeId |
ProcessingInstructionNodeTypeId => {
self.wait_until_safe_to_modify_dom();

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(_) => {}
}
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!()
}
@@ -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;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.