Generating closing element & Doctype XML

This commit fixes two problems:

1. Doctypes introducing too many newlines
2. Elements with siblings and a common parent not being closed properly

== Doctypes

When generating the XML for a doctype the XML::Generator class would
append a trailing newline. This however meant that if the next text node
was also a newline you'd now have two newlines. In previous versions of
Oga this worked because the old XML generation code would call
String#strip on the XML to add after the doctype.

To support this in the new version we perform a lookahead in
XML::Generator#on_doctype to remove any trailing newlines added by this
method in case the first child node is a newline text node.

== Closing Elements

When an element has a sibling following it _and_ does not have any child
nodes it would not be closed properly when generating XML. This is due
to the "until next_node = ..." expression evaluating to true, thus never
executing its body.

There's probably some way to work around this by using the "loop"
method, but considering it's 02:09 I think the current approach is good
enough. Future me will probably hate me for it.
This commit is contained in:
Yorick Peterse committed 2016-09-27 02:10:16 +02:00
1 parent 01fa1513f4
commit e0e0687dc2
3 files changed
+69 -2

No files matched your search

+14 -2
View File
@@ -17,8 +17,8 @@ module Oga
def initialize(root)
@start = root
if @start.respond_to?(:root_node)
@html_mode = @start.root_node.html?
if @start.respond_to?(:html?)
@html_mode = @start.html?
else
@html_mode = false
end
@@ -75,6 +75,10 @@ module Oga
break
else
# Make sure to always close the current element before
# moving to any siblings.
after_element(current, output) if current.is_a?(Element)
until next_node = current.is_a?(Node) && current.next
if current.is_a?(Node) && current != @start
current = current.parent
@@ -177,6 +181,14 @@ module Oga
on_doctype(doc.doctype, output)
output << "\n"
end
first_child = doc.children[0]
# Prevent excessive newlines in case the next node is a newline text
# node.
if first_child.is_a?(Text) && first_child.text.start_with?("\r\n", "\n")
output.chomp!
end
end
# @param [Oga::XML::XmlDeclaration] node