Loading src/html.cpp +139 −32 Original line number Diff line number Diff line Loading @@ -276,6 +276,15 @@ void libhtmlpp::HtmlString::_buildtreenode( Element *prev_el_in_tree = nullptr; auto checkContainer = [&](const std::string &tag) { for (size_t i = 0; ContainerTypes[i]; ++i) { if (tag == ContainerTypes[i]) { return true; } } return false; }; auto skip_empty = [](DocElements *cur, const DocElements *stop) -> DocElements* { while (cur && cur != stop && (!cur->element)) { cur = cur->nextel.get(); Loading @@ -283,7 +292,7 @@ void libhtmlpp::HtmlString::_buildtreenode( return cur; }; auto find_terminator = [&skip_empty](DocElements *open, const DocElements *bound) -> DocElements* { auto find_terminator = [&skip_empty, checkContainer](DocElements *open, const DocElements *bound) -> DocElements* { if (!open || !open->element || open->terminator || open->element->getType() != HtmlEl) return nullptr; Loading Loading @@ -312,14 +321,12 @@ void libhtmlpp::HtmlString::_buildtreenode( cur = cur->nextel.get(); } for (size_t i = 0; ContainerTypes[i]; ++i) { if (tag == ContainerTypes[i]) { if (checkContainer(tag)) { HTMLException e; e[HTMLException::Error] << tag << " must be terminated ! " << static_cast<HtmlElement*>(open->element.get())->getAtributte("id"); throw e; } } return nullptr; }; Loading Loading @@ -487,6 +494,36 @@ void libhtmlpp::HtmlString::_buildTree() { } ++ii; } }else if( (ii+3) < _Data.size() && std::equal(_Data.begin()+ii,_Data.begin()+(ii+9),"<testarea")){ size_t start=ii; while(ii<_Data.size()){ if(_Data[ii]==HTMLTAG_CLOSE) { addelement(&lastEl); lastEl->element=std::make_unique<TextArea>(); std::vector<char> tel; std::copy(_Data.begin()+start,_Data.begin()+ii,std::back_inserter(tel)); _serialelize(tel,(TextArea*)lastEl->element.get()); break; } ++ii; } size_t close=++ii; while(ii<_Data.size()){ if( std::equal(_Data.begin()+ii,_Data.begin()+(ii+10),"</testarea")) { std::copy(_Data.begin()+close,_Data.begin()+ii, std::back_inserter(static_cast<TextArea*>(lastEl->element.get())->_Text)); ii+=5; break; } ++ii; } }else { size_t start=ii; addelement(&lastEl); Loading Loading @@ -913,6 +950,9 @@ namespace libhtmlpp { case SvgEL: ((libhtmlpp::HtmlElement*)dest)->_childElement = std::make_unique<SvgElement>(); break; case TextAreaEL: ((libhtmlpp::HtmlElement*)dest)->_childElement = std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown html element found !"; Loading Loading @@ -959,6 +999,24 @@ namespace libhtmlpp { } } ((SvgElement*)dest)->_Svg=(((SvgElement*)src)->_Svg); }else if(src->getType()==libhtmlpp::TextAreaEL&& dest->getType()== libhtmlpp::TextAreaEL){ ((libhtmlpp::TextArea*)dest)->_TagName=(((libhtmlpp::TextArea*)src)->_TagName); for(libhtmlpp::TextArea::Attributes *cattr=((libhtmlpp::TextArea*)src)->_firstAttr.get(); cattr; cattr=cattr->_nextAttr.get()){ if(!cattr->_Value.empty()){ ((libhtmlpp::TextArea*)dest)->setAttribute( std::string( cattr->_Key.begin(), cattr->_Key.end() ),std::string( cattr->_Value.begin(), cattr->_Value.end() ) ); }else{ ((libhtmlpp::TextArea*)dest)->setAttribute(std::string(cattr->_Key.begin(),cattr->_Key.end()),""); } } ((TextArea*)dest)->_Text=(((TextArea*)src)->_Text); }else if(src->getType()==libhtmlpp::TextEl && dest->getType()== libhtmlpp::TextEl){ ((TextElement*)dest)->_Text=(((TextElement*)src)->_Text); }else if(src->getType()==libhtmlpp::CommentEl && dest->getType()== libhtmlpp::CommentEl){ Loading Loading @@ -987,6 +1045,9 @@ namespace libhtmlpp { case SvgEL: dest->_nextElement= std::make_unique<SvgElement>(); break; case TextAreaEL: dest->_nextElement= std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown next html element found !"; Loading @@ -1013,22 +1074,28 @@ namespace libhtmlpp { void libhtmlpp::Element::insertBefore(libhtmlpp::Element* el){ std::unique_ptr<Element> nel; switch(el->getType()){ case HtmlEl:{ nel=std::make_unique<HtmlElement>(); case HtmlEl: nel->_nextElement= std::make_unique<HtmlElement>(); break; } case TextEl:{ nel=std::make_unique<TextElement>(); case TextEl: nel->_nextElement= std::make_unique<TextElement>(); break; } case CommentEl:{ nel=std::make_unique<CommentElement>(); case CommentEl: nel->_nextElement= std::make_unique<CommentElement>(); break; } case ScriptEL:{ nel=std::make_unique<ScriptElement>(); case ScriptEL: nel->_nextElement= std::make_unique<ScriptElement>(); break; } case SvgEL: nel->_nextElement= std::make_unique<SvgElement>(); break; case TextAreaEL: nel->_nextElement= std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown next html element found !"; throw ex; } _copy(nel.get(),el); std::unique_ptr<Element> prev=std::move(_prevElement->_nextElement); Loading @@ -1040,22 +1107,28 @@ void libhtmlpp::Element::insertAfter(libhtmlpp::Element* el){ Element *nexel=nullptr,*prev=nullptr; switch(el->getType()){ case HtmlEl:{ case HtmlEl: _nextElement= std::make_unique<HtmlElement>(); break; } case TextEl:{ case TextEl: _nextElement= std::make_unique<TextElement>(); break; } case CommentEl:{ case CommentEl: _nextElement= std::make_unique<CommentElement>(); break; } case ScriptEL:{ case ScriptEL: _nextElement= std::make_unique<ScriptElement>(); break; } case SvgEL: _nextElement= std::make_unique<SvgElement>(); break; case TextAreaEL: _nextElement= std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown next html element found !"; throw ex; } _copy(_nextElement.get(),el); Loading Loading @@ -1263,6 +1336,40 @@ int libhtmlpp::SvgElement::getType() const{ return ElementType::SvgEL; } libhtmlpp::TextArea::TextArea() : HtmlElement("svg"){ } libhtmlpp::TextArea::TextArea(const TextArea &textsrc) : HtmlElement("text"){ _copy(this,&textsrc); } libhtmlpp::TextArea::~TextArea(){ } libhtmlpp::TextArea &libhtmlpp::TextArea::operator=(const libhtmlpp::Element& hel){ _copy(this,&hel); return *this; } libhtmlpp::TextArea &libhtmlpp::TextArea::operator=(const libhtmlpp::Element* hel){ _copy(this,hel); return *this; } void libhtmlpp::TextArea::setText(const std::string& text){ std::copy(text.begin(),text.end(), std::insert_iterator<std::vector<char>>(_Text,_Text.begin())); } const std::vector<char>libhtmlpp::TextArea::getText(){ return _Text; } int libhtmlpp::TextArea::getType() const{ return ElementType::TextAreaEL; } libhtmlpp::HtmlPage::HtmlPage(){ } Loading src/html.h +36 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ namespace libhtmlpp { HtmlEl=1, CommentEl=2, ScriptEL=3, SvgEL=4 SvgEL=4, TextAreaEL=5 }; /** * @brief Abstract base class for all nodes in the HTML tree. Provides linkage and common operations. Loading Loading @@ -275,6 +276,40 @@ namespace libhtmlpp { friend void print(const Element& element, HtmlString &output,bool formated); friend void _copy(libhtmlpp::Element *dest,const libhtmlpp::Element *src); }; /** * @brief Element representing an embedded <textarea> tag and its attributes/content. */ class TextArea : public HtmlElement{ public: TextArea(); TextArea(const TextArea &textsrc); ~TextArea(); TextArea& operator=(const Element &hel); TextArea& operator=(const Element *hel); const std::vector<char> getText(); void setText(const std::string &text); int getType() const; void insertChild(const Element* el)=delete; void insertChild(const Element& el)=delete; void appendChild(const Element* el)=delete; void appendChild(const Element& el)=delete; protected: std::unique_ptr<Element> _childElement=nullptr; std::vector<char> _Text; friend class HtmlString; friend void print(const Element& element, HtmlString &output,bool formated); friend void _copy(libhtmlpp::Element *dest,const libhtmlpp::Element *src); }; /** * @brief Serializes an element (and its subtree) into an HtmlString. * @param element Root element to print. Loading Loading
src/html.cpp +139 −32 Original line number Diff line number Diff line Loading @@ -276,6 +276,15 @@ void libhtmlpp::HtmlString::_buildtreenode( Element *prev_el_in_tree = nullptr; auto checkContainer = [&](const std::string &tag) { for (size_t i = 0; ContainerTypes[i]; ++i) { if (tag == ContainerTypes[i]) { return true; } } return false; }; auto skip_empty = [](DocElements *cur, const DocElements *stop) -> DocElements* { while (cur && cur != stop && (!cur->element)) { cur = cur->nextel.get(); Loading @@ -283,7 +292,7 @@ void libhtmlpp::HtmlString::_buildtreenode( return cur; }; auto find_terminator = [&skip_empty](DocElements *open, const DocElements *bound) -> DocElements* { auto find_terminator = [&skip_empty, checkContainer](DocElements *open, const DocElements *bound) -> DocElements* { if (!open || !open->element || open->terminator || open->element->getType() != HtmlEl) return nullptr; Loading Loading @@ -312,14 +321,12 @@ void libhtmlpp::HtmlString::_buildtreenode( cur = cur->nextel.get(); } for (size_t i = 0; ContainerTypes[i]; ++i) { if (tag == ContainerTypes[i]) { if (checkContainer(tag)) { HTMLException e; e[HTMLException::Error] << tag << " must be terminated ! " << static_cast<HtmlElement*>(open->element.get())->getAtributte("id"); throw e; } } return nullptr; }; Loading Loading @@ -487,6 +494,36 @@ void libhtmlpp::HtmlString::_buildTree() { } ++ii; } }else if( (ii+3) < _Data.size() && std::equal(_Data.begin()+ii,_Data.begin()+(ii+9),"<testarea")){ size_t start=ii; while(ii<_Data.size()){ if(_Data[ii]==HTMLTAG_CLOSE) { addelement(&lastEl); lastEl->element=std::make_unique<TextArea>(); std::vector<char> tel; std::copy(_Data.begin()+start,_Data.begin()+ii,std::back_inserter(tel)); _serialelize(tel,(TextArea*)lastEl->element.get()); break; } ++ii; } size_t close=++ii; while(ii<_Data.size()){ if( std::equal(_Data.begin()+ii,_Data.begin()+(ii+10),"</testarea")) { std::copy(_Data.begin()+close,_Data.begin()+ii, std::back_inserter(static_cast<TextArea*>(lastEl->element.get())->_Text)); ii+=5; break; } ++ii; } }else { size_t start=ii; addelement(&lastEl); Loading Loading @@ -913,6 +950,9 @@ namespace libhtmlpp { case SvgEL: ((libhtmlpp::HtmlElement*)dest)->_childElement = std::make_unique<SvgElement>(); break; case TextAreaEL: ((libhtmlpp::HtmlElement*)dest)->_childElement = std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown html element found !"; Loading Loading @@ -959,6 +999,24 @@ namespace libhtmlpp { } } ((SvgElement*)dest)->_Svg=(((SvgElement*)src)->_Svg); }else if(src->getType()==libhtmlpp::TextAreaEL&& dest->getType()== libhtmlpp::TextAreaEL){ ((libhtmlpp::TextArea*)dest)->_TagName=(((libhtmlpp::TextArea*)src)->_TagName); for(libhtmlpp::TextArea::Attributes *cattr=((libhtmlpp::TextArea*)src)->_firstAttr.get(); cattr; cattr=cattr->_nextAttr.get()){ if(!cattr->_Value.empty()){ ((libhtmlpp::TextArea*)dest)->setAttribute( std::string( cattr->_Key.begin(), cattr->_Key.end() ),std::string( cattr->_Value.begin(), cattr->_Value.end() ) ); }else{ ((libhtmlpp::TextArea*)dest)->setAttribute(std::string(cattr->_Key.begin(),cattr->_Key.end()),""); } } ((TextArea*)dest)->_Text=(((TextArea*)src)->_Text); }else if(src->getType()==libhtmlpp::TextEl && dest->getType()== libhtmlpp::TextEl){ ((TextElement*)dest)->_Text=(((TextElement*)src)->_Text); }else if(src->getType()==libhtmlpp::CommentEl && dest->getType()== libhtmlpp::CommentEl){ Loading Loading @@ -987,6 +1045,9 @@ namespace libhtmlpp { case SvgEL: dest->_nextElement= std::make_unique<SvgElement>(); break; case TextAreaEL: dest->_nextElement= std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown next html element found !"; Loading @@ -1013,22 +1074,28 @@ namespace libhtmlpp { void libhtmlpp::Element::insertBefore(libhtmlpp::Element* el){ std::unique_ptr<Element> nel; switch(el->getType()){ case HtmlEl:{ nel=std::make_unique<HtmlElement>(); case HtmlEl: nel->_nextElement= std::make_unique<HtmlElement>(); break; } case TextEl:{ nel=std::make_unique<TextElement>(); case TextEl: nel->_nextElement= std::make_unique<TextElement>(); break; } case CommentEl:{ nel=std::make_unique<CommentElement>(); case CommentEl: nel->_nextElement= std::make_unique<CommentElement>(); break; } case ScriptEL:{ nel=std::make_unique<ScriptElement>(); case ScriptEL: nel->_nextElement= std::make_unique<ScriptElement>(); break; } case SvgEL: nel->_nextElement= std::make_unique<SvgElement>(); break; case TextAreaEL: nel->_nextElement= std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown next html element found !"; throw ex; } _copy(nel.get(),el); std::unique_ptr<Element> prev=std::move(_prevElement->_nextElement); Loading @@ -1040,22 +1107,28 @@ void libhtmlpp::Element::insertAfter(libhtmlpp::Element* el){ Element *nexel=nullptr,*prev=nullptr; switch(el->getType()){ case HtmlEl:{ case HtmlEl: _nextElement= std::make_unique<HtmlElement>(); break; } case TextEl:{ case TextEl: _nextElement= std::make_unique<TextElement>(); break; } case CommentEl:{ case CommentEl: _nextElement= std::make_unique<CommentElement>(); break; } case ScriptEL:{ case ScriptEL: _nextElement= std::make_unique<ScriptElement>(); break; } case SvgEL: _nextElement= std::make_unique<SvgElement>(); break; case TextAreaEL: _nextElement= std::make_unique<TextArea>(); break; default: HTMLException ex; ex[HTMLException::Critical] << "_copy: Unknown next html element found !"; throw ex; } _copy(_nextElement.get(),el); Loading Loading @@ -1263,6 +1336,40 @@ int libhtmlpp::SvgElement::getType() const{ return ElementType::SvgEL; } libhtmlpp::TextArea::TextArea() : HtmlElement("svg"){ } libhtmlpp::TextArea::TextArea(const TextArea &textsrc) : HtmlElement("text"){ _copy(this,&textsrc); } libhtmlpp::TextArea::~TextArea(){ } libhtmlpp::TextArea &libhtmlpp::TextArea::operator=(const libhtmlpp::Element& hel){ _copy(this,&hel); return *this; } libhtmlpp::TextArea &libhtmlpp::TextArea::operator=(const libhtmlpp::Element* hel){ _copy(this,hel); return *this; } void libhtmlpp::TextArea::setText(const std::string& text){ std::copy(text.begin(),text.end(), std::insert_iterator<std::vector<char>>(_Text,_Text.begin())); } const std::vector<char>libhtmlpp::TextArea::getText(){ return _Text; } int libhtmlpp::TextArea::getType() const{ return ElementType::TextAreaEL; } libhtmlpp::HtmlPage::HtmlPage(){ } Loading
src/html.h +36 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ namespace libhtmlpp { HtmlEl=1, CommentEl=2, ScriptEL=3, SvgEL=4 SvgEL=4, TextAreaEL=5 }; /** * @brief Abstract base class for all nodes in the HTML tree. Provides linkage and common operations. Loading Loading @@ -275,6 +276,40 @@ namespace libhtmlpp { friend void print(const Element& element, HtmlString &output,bool formated); friend void _copy(libhtmlpp::Element *dest,const libhtmlpp::Element *src); }; /** * @brief Element representing an embedded <textarea> tag and its attributes/content. */ class TextArea : public HtmlElement{ public: TextArea(); TextArea(const TextArea &textsrc); ~TextArea(); TextArea& operator=(const Element &hel); TextArea& operator=(const Element *hel); const std::vector<char> getText(); void setText(const std::string &text); int getType() const; void insertChild(const Element* el)=delete; void insertChild(const Element& el)=delete; void appendChild(const Element* el)=delete; void appendChild(const Element& el)=delete; protected: std::unique_ptr<Element> _childElement=nullptr; std::vector<char> _Text; friend class HtmlString; friend void print(const Element& element, HtmlString &output,bool formated); friend void _copy(libhtmlpp::Element *dest,const libhtmlpp::Element *src); }; /** * @brief Serializes an element (and its subtree) into an HtmlString. * @param element Root element to print. Loading