summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-09-20 14:50:46 +0200
committerTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-09-22 00:31:47 +0200
commitd42813db533b0a4930528ba1ccd34f33498ffe36 (patch)
tree519cf354a36b3885671a3aecd947062b282e24a0
parent0ce8533ee2b3202922e0ff7ba9f9212080965167 (diff)
Extend HTMLWriter: flush the stack, more values for attribute(..)
Change-Id: I733426ba5f82ee25751387f88942dbc66689821d
-rw-r--r--include/svtools/HtmlWriter.hxx31
-rw-r--r--svtools/qa/unit/testHtmlWriter.cxx124
-rw-r--r--svtools/source/svhtml/HtmlWriter.cxx49
3 files changed, 193 insertions, 11 deletions
diff --git a/include/svtools/HtmlWriter.hxx b/include/svtools/HtmlWriter.hxx
index fc2c5c5b6c08..3c065ffd6259 100644
--- a/include/svtools/HtmlWriter.hxx
+++ b/include/svtools/HtmlWriter.hxx
@@ -12,6 +12,7 @@
#define INCLUDED_SVTOOLS_HTMLWRITER_HXX
#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
#include <tools/stream.hxx>
#include <vector>
#include <svtools/svtdllapi.h>
@@ -20,11 +21,13 @@ class SVT_DLLPUBLIC HtmlWriter
{
private:
std::vector<OString> maElementStack;
- SvStream& mrStream;
- bool mbElementOpen;
- bool mbContentWritten;
- bool mbPrettyPrint;
+ SvStream& mrStream;
+
+ bool mbElementOpen;
+ bool mbContentWritten;
+ bool mbPrettyPrint;
+ rtl_TextEncoding maEncoding;
public:
HtmlWriter(SvStream& rStream);
@@ -32,11 +35,23 @@ public:
void prettyPrint(bool bChoice);
- void start(const OString &aElement);
+ void start(const OString& aElement);
+
void end();
- void write(const OString &aContent);
- void attribute(const OString &aAttribute, const OString &aValue);
- void single(const OString &aContent);
+
+ void flushStack();
+ void flushStack(const OString& aElement);
+
+ void write(const OString& aContent);
+
+ void attribute(const OString& aAttribute, const char* aValue);
+ void attribute(const OString& aAttribute, sal_Int32 aValue);
+ void attribute(const OString& aAttribute, const OString& aValue);
+ void attribute(const OString& aAttribute, const OUString& aValue);
+ // boolean attribute e.g. <img ismap>
+ void attribute(const OString& aAttribute);
+
+ void single(const OString& aContent);
void endAttribute();
};
diff --git a/svtools/qa/unit/testHtmlWriter.cxx b/svtools/qa/unit/testHtmlWriter.cxx
index 59cdb241dfed..7c9d38f45a6b 100644
--- a/svtools/qa/unit/testHtmlWriter.cxx
+++ b/svtools/qa/unit/testHtmlWriter.cxx
@@ -40,6 +40,8 @@ public:
void testSingleElementWithContent();
void testSingleElementWithContentAndAttributes();
void testNested();
+ void testAttributeValues();
+ void testFlushStack();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testSingleElement);
@@ -47,6 +49,8 @@ public:
CPPUNIT_TEST(testSingleElementWithContent);
CPPUNIT_TEST(testSingleElementWithContentAndAttributes);
CPPUNIT_TEST(testNested);
+ CPPUNIT_TEST(testAttributeValues);
+ CPPUNIT_TEST(testFlushStack);
CPPUNIT_TEST_SUITE_END();
};
@@ -162,6 +166,126 @@ void Test::testNested()
CPPUNIT_ASSERT_EQUAL(OString("<abc><xyz>xxx</xyz></abc>"), aString);
}
+void Test::testAttributeValues()
+{
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("abc");
+ aHtml.attribute("one", OString("one"));
+ aHtml.attribute("two", OUString("two"));
+ aHtml.attribute("three", sal_Int32(12));
+ aHtml.end();
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<abc one=\"one\" two=\"two\" three=\"12\"/>"), aString);
+}
+
+void Test::testFlushStack()
+{
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.flushStack("a"); // simple ,end element "a" = like end()
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a/>"), aString);
+ }
+
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.start("b");
+ aHtml.flushStack("b"); // end at first element "b", don't output "a" yet
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a><b/>"), aString);
+ }
+
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.start("b");
+ aHtml.flushStack("a"); // end at first element "a"
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a><b/></a>"), aString);
+ }
+
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.start("b");
+ aHtml.start("c");
+ aHtml.flushStack("a"); // end at first element "a"
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b></a>"), aString);
+ }
+
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.start("b");
+ aHtml.start("c");
+ aHtml.flushStack("b"); // end at first element "b"
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b>"), aString);
+ }
+
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.start("b");
+ aHtml.start("c");
+ aHtml.flushStack("x"); // no known element - ends when stack is empty
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b></a>"), aString);
+ }
+
+ {
+ SvMemoryStream aStream;
+
+ HtmlWriter aHtml(aStream);
+ aHtml.prettyPrint(false);
+ aHtml.start("a");
+ aHtml.start("b");
+ aHtml.start("c");
+ aHtml.flushStack(); // flush the whole stack
+
+ OString aString = extractFromStream(aStream);
+
+ CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b></a>"), aString);
+ }
+}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svtools/source/svhtml/HtmlWriter.cxx b/svtools/source/svhtml/HtmlWriter.cxx
index 5accc5de633e..f075d40f7804 100644
--- a/svtools/source/svhtml/HtmlWriter.cxx
+++ b/svtools/source/svhtml/HtmlWriter.cxx
@@ -14,7 +14,8 @@ HtmlWriter::HtmlWriter(SvStream& rStream) :
mrStream(rStream),
mbElementOpen(false),
mbContentWritten(false),
- mbPrettyPrint(true)
+ mbPrettyPrint(true),
+ maEncoding(RTL_TEXTENCODING_UTF8)
{}
HtmlWriter::~HtmlWriter()
@@ -25,7 +26,7 @@ void HtmlWriter::prettyPrint(bool bChoice)
mbPrettyPrint = bChoice;
}
-void HtmlWriter::start(const OString &aElement)
+void HtmlWriter::start(const OString& aElement)
{
if (mbElementOpen)
{
@@ -66,6 +67,24 @@ void HtmlWriter::endAttribute()
}
}
+void HtmlWriter::flushStack()
+{
+ while (!maElementStack.empty())
+ {
+ end();
+ }
+}
+
+void HtmlWriter::flushStack(const OString& aElement)
+{
+ OString sCurrentElement;
+ do
+ {
+ sCurrentElement = maElementStack.back();
+ end();
+ } while (!maElementStack.empty() && aElement != sCurrentElement);
+}
+
void HtmlWriter::end()
{
if (mbElementOpen)
@@ -105,7 +124,7 @@ void HtmlWriter::write(const OString &aContent)
mrStream.WriteOString(aContent);
}
-void HtmlWriter::attribute(const OString &aAttribute, const OString &aValue)
+void HtmlWriter::attribute(const OString &aAttribute, const OString& aValue)
{
if (mbElementOpen && !aAttribute.isEmpty() && !aValue.isEmpty())
{
@@ -118,5 +137,29 @@ void HtmlWriter::attribute(const OString &aAttribute, const OString &aValue)
}
}
+void HtmlWriter::attribute(const OString& aAttribute, const sal_Int32 aValue)
+{
+ attribute(aAttribute, OString::number(aValue));
+}
+
+void HtmlWriter::attribute(const OString& aAttribute, const char* pValue)
+{
+ attribute(aAttribute, OString(pValue));
+}
+
+void HtmlWriter::attribute(const OString& aAttribute, const OUString& aValue)
+{
+ attribute(aAttribute, OUStringToOString(aValue, maEncoding));
+}
+
+void HtmlWriter::attribute(const OString& aAttribute)
+{
+ if (mbElementOpen && !aAttribute.isEmpty())
+ {
+ mrStream.WriteChar(' ');
+ mrStream.WriteOString(aAttribute);
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */