diff options
author | Ms2ger <ms2ger@gmail.com> | 2014-05-24 21:29:52 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-05-27 18:44:21 +0200 |
commit | d1ca38048210ee214d6335156bd546069ee81fea (patch) | |
tree | ec96c4ae17c3b0131368389d47125d939a8f22fd /src/components/script/dom/htmlserializer.rs | |
parent | 2717ab65ecae6cf4ab38b6c1b9ea3f02d4913252 (diff) | |
download | servo-d1ca38048210ee214d6335156bd546069ee81fea.tar.gz servo-d1ca38048210ee214d6335156bd546069ee81fea.zip |
Use StrBuf more efficiently in htmlserializer.
Diffstat (limited to 'src/components/script/dom/htmlserializer.rs')
-rw-r--r-- | src/components/script/dom/htmlserializer.rs | 134 |
1 files changed, 74 insertions, 60 deletions
diff --git a/src/components/script/dom/htmlserializer.rs b/src/components/script/dom/htmlserializer.rs index 2021762f96d..ebda79fe416 100644 --- a/src/components/script/dom/htmlserializer.rs +++ b/src/components/script/dom/htmlserializer.rs @@ -25,51 +25,53 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { for node in *iterator { while open_elements.len() > iterator.depth { - html.push_str("</".to_owned() + open_elements.pop().unwrap().as_slice() + ">"); + html.push_str("</"); + html.push_str(open_elements.pop().unwrap().as_slice()); + html.push_str(">"); } - html.push_str( - match node.type_id() { - ElementNodeTypeId(..) => { - let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap(); - serialize_elem(elem, &mut open_elements) - } - CommentNodeTypeId => { - let comment: &JSRef<Comment> = CommentCast::to_ref(&node).unwrap(); - serialize_comment(comment) - } - TextNodeTypeId => { - let text: &JSRef<Text> = TextCast::to_ref(&node).unwrap(); - serialize_text(text) - } - DoctypeNodeTypeId => { - let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(&node).unwrap(); - serialize_doctype(doctype) - } - ProcessingInstructionNodeTypeId => { - let processing_instruction: &JSRef<ProcessingInstruction> = - ProcessingInstructionCast::to_ref(&node).unwrap(); - serialize_processing_instruction(processing_instruction) - } - DocumentFragmentNodeTypeId => { - "".to_owned() - } - DocumentNodeTypeId => { - fail!("It shouldn't be possible to serialize a document node") - } + match node.type_id() { + ElementNodeTypeId(..) => { + let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap(); + serialize_elem(elem, &mut open_elements, &mut html) } - ); + CommentNodeTypeId => { + let comment: &JSRef<Comment> = CommentCast::to_ref(&node).unwrap(); + serialize_comment(comment, &mut html) + } + TextNodeTypeId => { + let text: &JSRef<Text> = TextCast::to_ref(&node).unwrap(); + serialize_text(text, &mut html) + } + DoctypeNodeTypeId => { + let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(&node).unwrap(); + serialize_doctype(doctype, &mut html) + } + ProcessingInstructionNodeTypeId => { + let processing_instruction: &JSRef<ProcessingInstruction> = + ProcessingInstructionCast::to_ref(&node).unwrap(); + serialize_processing_instruction(processing_instruction, &mut html) + } + DocumentFragmentNodeTypeId => {} + DocumentNodeTypeId => { + fail!("It shouldn't be possible to serialize a document node") + } + } } while open_elements.len() > 0 { - html.push_str("</".to_owned() + open_elements.pop().unwrap().as_slice() + ">"); + html.push_str("</"); + html.push_str(open_elements.pop().unwrap().as_slice()); + html.push_str(">"); } html.into_owned() } -fn serialize_comment(comment: &JSRef<Comment>) -> ~str { - "<!--".to_owned() + comment.deref().characterdata.data + "-->" +fn serialize_comment(comment: &JSRef<Comment>, html: &mut StrBuf) { + html.push_str("<!--"); + html.push_str(comment.deref().characterdata.data); + html.push_str("-->"); } -fn serialize_text(text: &JSRef<Text>) -> ~str { +fn serialize_text(text: &JSRef<Text>, html: &mut StrBuf) { let text_node: &JSRef<Node> = NodeCast::from_ref(text); match text_node.parent_node().map(|node| node.root()) { Some(ref parent) if parent.is_element() => { @@ -77,33 +79,39 @@ fn serialize_text(text: &JSRef<Text>) -> ~str { match elem.deref().local_name.as_slice() { "style" | "script" | "xmp" | "iframe" | "noembed" | "noframes" | "plaintext" | - "noscript" if elem.deref().namespace == namespace::HTML => { - text.deref().characterdata.data.clone() - }, - _ => escape(text.deref().characterdata.data, false) + "noscript" if elem.deref().namespace == namespace::HTML + => html.push_str(text.deref().characterdata.data), + _ => html.push_str(escape(text.deref().characterdata.data, false)) } } - _ => escape(text.deref().characterdata.data, false) + _ => html.push_str(escape(text.deref().characterdata.data, false)) } } -fn serialize_processing_instruction(processing_instruction: &JSRef<ProcessingInstruction>) -> ~str { - "<?".to_owned() + processing_instruction.deref().target + " " + processing_instruction.deref().characterdata.data + "?>" +fn serialize_processing_instruction(processing_instruction: &JSRef<ProcessingInstruction>, + html: &mut StrBuf) { + html.push_str("<?"); + html.push_str(processing_instruction.deref().target); + html.push_char(' '); + html.push_str(processing_instruction.deref().characterdata.data); + html.push_str("?>"); } -fn serialize_doctype(doctype: &JSRef<DocumentType>) -> ~str { - "<!DOCTYPE".to_owned() + doctype.deref().name + ">" +fn serialize_doctype(doctype: &JSRef<DocumentType>, html: &mut StrBuf) { + html.push_str("<!DOCTYPE"); + html.push_str(doctype.deref().name); + html.push_char('>'); } -fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>) -> ~str { - let mut rv = StrBuf::new(); - rv.push_str("<"); - rv.push_str(elem.deref().local_name); +fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>, html: &mut StrBuf) { + html.push_char('<'); + html.push_str(elem.deref().local_name); for attr in elem.deref().attrs.iter() { let attr = attr.root(); - rv.push_str(serialize_attr(&*attr)); + serialize_attr(&*attr, html); }; - rv.push_str(">"); + html.push_char('>'); + match elem.deref().local_name.as_slice() { "pre" | "listing" | "textarea" if elem.deref().namespace == namespace::HTML => { let node: &JSRef<Node> = NodeCast::from_ref(elem); @@ -111,7 +119,7 @@ fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>) -> ~str Some(ref child) if child.is_text() => { let text: &JSRef<CharacterData> = CharacterDataCast::to_ref(&**child).unwrap(); if text.deref().data.len() > 0 && text.deref().data[0] == 0x0A as u8 { - rv.push_str("\x0A"); + html.push_char('\x0A'); } }, _ => {} @@ -119,26 +127,32 @@ fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>) -> ~str }, _ => {} } + if !elem.deref().is_void() { open_elements.push(elem.deref().local_name.clone()); } - rv.into_owned() } -fn serialize_attr(attr: &JSRef<Attr>) -> ~str { - let attr_name = if attr.deref().namespace == namespace::XML { - "xml:".to_owned() + attr.deref().local_name.clone() +fn serialize_attr(attr: &JSRef<Attr>, html: &mut StrBuf) { + html.push_char(' '); + if attr.deref().namespace == namespace::XML { + html.push_str("xml:"); + html.push_str(attr.deref().local_name); } else if attr.deref().namespace == namespace::XMLNS && attr.deref().local_name.as_slice() == "xmlns" { - "xmlns".to_owned() + html.push_str("xmlns"); } else if attr.deref().namespace == namespace::XMLNS { - "xmlns:".to_owned() + attr.deref().local_name.clone() + html.push_str("xmlns:"); + html.push_str(attr.deref().local_name); } else if attr.deref().namespace == namespace::XLink { - "xlink:".to_owned() + attr.deref().local_name.clone() + html.push_str("xlink:"); + html.push_str(attr.deref().local_name); } else { - attr.deref().name.clone() + html.push_str(attr.deref().name); }; - " ".to_owned() + attr_name + "=\"" + escape(attr.deref().value, true) + "\"" + html.push_str("=\""); + html.push_str(escape(attr.deref().value, true)); + html.push_char('"'); } fn escape(string: &str, attr_mode: bool) -> ~str { |