From 624d78fe1af7ba07904e65792b2629719b61debc Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 4 May 2021 12:26:32 +0300 Subject: [PATCH] Methods to serialize CHtmlElement back to string --- nel/include/nel/gui/html_element.h | 12 ++++ nel/src/gui/html_element.cpp | 98 ++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/nel/include/nel/gui/html_element.h b/nel/include/nel/gui/html_element.h index 22f037cd4..d96b00508 100644 --- a/nel/include/nel/gui/html_element.h +++ b/nel/include/nel/gui/html_element.h @@ -75,6 +75,18 @@ namespace NLGUI // update Children index/parent/next/prevSibling pointers void reindexChilds(); + // escape text tag or attribute value + std::string htmlEscape(std::string val, bool isAttribute = false) const; + + // serialize element attributes as string + std::string serializeAttributes() const; + + // serialize child elements as html string + std::string serializeChilds() const; + + // serialize itself and children as html string + std::string serialize() const; + // debug std::string toString(bool tree = false, uint depth = 0) const; diff --git a/nel/src/gui/html_element.cpp b/nel/src/gui/html_element.cpp index 8735cc56e..454833a5a 100644 --- a/nel/src/gui/html_element.cpp +++ b/nel/src/gui/html_element.cpp @@ -18,6 +18,7 @@ #include "stdpch.h" #include "nel/gui/html_element.h" +#include "nel/gui/libwww.h" using namespace std; using namespace NLMISC; @@ -137,6 +138,103 @@ namespace NLGUI return ""; } + // *************************************************************************** + std::string CHtmlElement::htmlEscape(std::string val, bool isAttribute) const + { + static const std::vector searchReplace = { + "&", "&", + "<", "<", + ">", ">", + "\xA0", " ", + }; + + for(uint i = 0; i < searchReplace.size(); i+=2) + val = strFindReplaceAll(val, searchReplace[i], searchReplace[i+1]); + + if (isAttribute) + { + static const std::string q = "\""; + static const std::string quot = """; + val = strFindReplaceAll(val, q, quot); + } + + return val; + } + + // *************************************************************************** + std::string CHtmlElement::serializeAttributes() const + { + std::string result; + for(std::map::const_iterator it = Attributes.begin(); it != Attributes.end(); ++it) + { + if (it->first == "class") + { + result += " class=\""; + for(std::set::const_iterator it2 = ClassNames.begin(); it2 != ClassNames.end(); ++it2) + { + if (it2 != ClassNames.begin()) + { + result += " "; + } + result += htmlEscape(*it2, true); + } + result += "\""; + } + else + { + result += " " + it->first + "=\"" + htmlEscape(it->second, true) + "\""; + } + } + return result; + } + + // *************************************************************************** + std::string CHtmlElement::serializeChilds() const + { + std::string result; + for(std::list::const_iterator it = Children.begin(); it != Children.end(); ++it) + result += it->serialize(); + + return result; + } + + // *************************************************************************** + std::string CHtmlElement::serialize() const + { + if (Type == TEXT_NODE) + { + if (parent && (parent->ID == HTML_SCRIPT || parent->ID == HTML_STYLE || + parent->ID == HTML_IFRAME || parent->ID == HTML_NOEMBED || + parent->ID == HTML_NOSCRIPT)) + { + return Value; + } else { + return htmlEscape(Value); + } + } + + std::string result = "<" + Value + serializeAttributes() + ">"; + + if (ID == HTML_AREA || ID == HTML_BASE || ID == HTML_BR || + ID == HTML_COL || ID == HTML_EMBED || ID == HTML_HR || + ID == HTML_IMG || ID == HTML_INPUT || ID == HTML_LINK || + ID == HTML_META || ID == HTML_PARAM || ID == HTML_WBR) + { + return result; + } + + // first linebreak that will be ignored on parse time + if (ID == HTML_PRE || ID == HTML_TEXTAREA) + result += "\n"; + + if (!Children.empty()) + result += serializeChilds(); + + result += ""; + + return result; + } + // *************************************************************************** std::string CHtmlElement::toString(bool tree, uint depth) const {