diff --git a/modules/web/html/html_parser.cpp b/modules/web/html/html_parser.cpp index f32d111a3..dd5e9ac54 100644 --- a/modules/web/html/html_parser.cpp +++ b/modules/web/html/html_parser.cpp @@ -3,29 +3,50 @@ #include "core/error_macros.h" #include "core/log/logger.h" +String HTMLParserAttribute::get_attribute() { + return _attribute; +} +void HTMLParserAttribute::set_attribute(const String &val) { + _attribute = val; +} + +String HTMLParserAttribute::get_data() { + return _data; +} +void HTMLParserAttribute::set_data(const String &val) { + _data = val; +} + +bool HTMLParserAttribute::get_single() { + return _single; +} +void HTMLParserAttribute::set_single(const bool &val) { + _single = val; +} + bool HTMLParserAttribute::match_attrib(const String &attrib) { - return attribute == attrib; + return _attribute == attrib; } bool HTMLParserAttribute::match_data(const String &d) { - return data == d; + return _data == d; } bool HTMLParserAttribute::match_data(const Vector &d) { // todo return false; } bool HTMLParserAttribute::contains_data(const String &d) { - return data.find(d) != -1; + return _data.find(d) != -1; } String HTMLParserAttribute::convert_to_string() const { - if (single) { - return attribute; + if (_single) { + return _attribute; } - if (data.find("\"") == -1) { - return attribute + "=\"" + data + "\""; + if (_data.find("\"") == -1) { + return _attribute + "=\"" + _data + "\""; } else { - return attribute + "=\'" + data + "\'"; + return _attribute + "=\'" + _data + "\'"; } } @@ -34,19 +55,91 @@ void HTMLParserAttribute::print() const { } HTMLParserAttribute::HTMLParserAttribute() { - single = false; + _single = false; } HTMLParserAttribute::~HTMLParserAttribute() { } +void HTMLParserTag::add_child_tag(const Ref &tag) { + _tags.push_back(tag); +} +void HTMLParserTag::remote_child_tag(const int index) { + ERR_FAIL_INDEX(index, _tags.size()); + + _tags.remove(index); +} +Ref HTMLParserTag::get_child_tag(const int index) { + ERR_FAIL_INDEX_V(index, _tags.size(), Ref()); + + return _tags[index]; +} +int HTMLParserTag::get_child_tag_count() const { + return _tags.size(); +} +void HTMLParserTag::clear_child_tags() { + _tags.clear(); +} + +Vector HTMLParserTag::get_child_tags() { + Vector r; + for (int i = 0; i < _tags.size(); i++) { + r.push_back(_tags[i].get_ref_ptr()); + } + return r; +} + +void HTMLParserTag::set_child_tags(const Vector &val) { + _tags.clear(); + for (int i = 0; i < val.size(); i++) { + Ref e = Ref(val[i]); + _tags.push_back(e); + } +} + +void HTMLParserTag::add_child_attribute(const Ref &tag) { + _attributes.push_back(tag); +} +void HTMLParserTag::remote_child_attribute(const int index) { + ERR_FAIL_INDEX(index, _tags.size()); + + _attributes.remove(index); +} +Ref HTMLParserTag::get_child_attribute(const int index) { + ERR_FAIL_INDEX_V(index, _tags.size(), Ref()); + + return _attributes[index]; +} +int HTMLParserTag::get_child_attribute_count() const { + return _attributes.size(); +} +void HTMLParserTag::clear_child_attributes() { + _attributes.clear(); +} + +Vector HTMLParserTag::get_attributes() { + Vector r; + for (int i = 0; i < _attributes.size(); i++) { + r.push_back(_attributes[i].get_ref_ptr()); + } + return r; +} + +void HTMLParserTag::set_attributes(const Vector &val) { + _attributes.clear(); + for (int i = 0; i < val.size(); i++) { + Ref e = Ref(val[i]); + _attributes.push_back(e); + } +} + Ref HTMLParserTag::get_first(const String &t) { - if (tag == t) { + if (_tag == t) { return Ref(this); } - for (int i = 0; i < tags.size(); ++i) { - Ref ht = tags.write[i]->get_first(t); + for (int i = 0; i < _tags.size(); ++i) { + Ref ht = _tags.write[i]->get_first(t); if (ht.is_valid()) { return ht; @@ -57,14 +150,14 @@ Ref HTMLParserTag::get_first(const String &t) { } Ref HTMLParserTag::get_first(const String &t, const String &attrib, const String &val) { - if (tag == t) { + if (_tag == t) { if (has_attribute(attrib, val)) { return Ref(this); } } - for (int i = 0; i < tags.size(); ++i) { - Ref ht = tags.write[i]->get_first(t, attrib, val); + for (int i = 0; i < _tags.size(); ++i) { + Ref ht = _tags.write[i]->get_first(t, attrib, val); if (ht.is_valid()) { return ht; @@ -78,15 +171,15 @@ String HTMLParserTag::get_attribute_value(const String &attrib) { Ref a = get_attribute(attrib); if (a.is_valid()) { - return a->data; + return a->get_data(); } return ""; } Ref HTMLParserTag::get_attribute(const String &attrib) { - for (int i = 0; i < attributes.size(); ++i) { - Ref a = attributes[i]; + for (int i = 0; i < _attributes.size(); ++i) { + Ref a = _attributes[i]; if (a->match_attrib(attrib)) { return a; @@ -97,8 +190,8 @@ Ref HTMLParserTag::get_attribute(const String &attrib) { } bool HTMLParserTag::has_attribute(const String &attrib) { - for (int i = 0; i < attributes.size(); ++i) { - Ref a = attributes[i]; + for (int i = 0; i < _attributes.size(); ++i) { + Ref a = _attributes[i]; if (a->match_attrib(attrib)) { return true; @@ -109,8 +202,8 @@ bool HTMLParserTag::has_attribute(const String &attrib) { } Ref HTMLParserTag::get_attribute(const String &attrib, const String &contains_val) { - for (int i = 0; i < attributes.size(); ++i) { - Ref a = attributes[i]; + for (int i = 0; i < _attributes.size(); ++i) { + Ref a = _attributes[i]; if (a->match_attrib(attrib) && a->contains_data(contains_val)) { return a; @@ -121,8 +214,8 @@ Ref HTMLParserTag::get_attribute(const String &attrib, cons } bool HTMLParserTag::has_attribute(const String &attrib, const String &contains_val) { - for (int i = 0; i < attributes.size(); ++i) { - Ref a = attributes[i]; + for (int i = 0; i < _attributes.size(); ++i) { + Ref a = _attributes[i]; if (a->match_attrib(attrib) && a->contains_data(contains_val)) { return true; @@ -133,81 +226,81 @@ bool HTMLParserTag::has_attribute(const String &attrib, const String &contains_v } void HTMLParserTag::process() { - if (type != HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE) { + if (_type != HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE) { return; } - if (data.size() < 2) { + if (_data.size() < 2) { return; } - ERR_FAIL_COND(data[0] != '<'); - ERR_FAIL_COND(data[data.size() - 1] != '>'); + ERR_FAIL_COND(_data[0] != '<'); + ERR_FAIL_COND(_data[_data.size() - 1] != '>'); int start_index = 1; - if (data[1] == '/') { + if (_data[1] == '/') { ++start_index; - type = HTMLParserTag::HTML_PARSER_TAG_TYPE_CLOSING_TAG; - } else if (data[1] == '!') { - if (data.size() < 8) { + _type = HTMLParserTag::HTML_PARSER_TAG_TYPE_CLOSING_TAG; + } else if (_data[1] == '!') { + if (_data.size() < 8) { return; } // test for comment. ++start_index; - if (data[2] == '-' && data[3] == '-') { - type = HTMLParserTag::HTML_PARSER_TAG_TYPE_COMMENT; + if (_data[2] == '-' && _data[3] == '-') { + _type = HTMLParserTag::HTML_PARSER_TAG_TYPE_COMMENT; - int comment_start_index = data.find_char(' ', 3); + int comment_start_index = _data.find_char(' ', 3); if (comment_start_index == -1) { comment_start_index = 4; } - tag = data.substr(comment_start_index, data.size() - comment_start_index - 3); + _tag = _data.substr(comment_start_index, _data.size() - comment_start_index - 3); } - if (data.size() < 11) { + if (_data.size() < 11) { return; } // test for doctype. - int doctype_start_index = data.find("doctype ", 2); + int doctype_start_index = _data.find("doctype ", 2); if (doctype_start_index == -1) { return; } - type = HTMLParserTag::HTML_PARSER_TAG_TYPE_DOCTYPE; + _type = HTMLParserTag::HTML_PARSER_TAG_TYPE_DOCTYPE; - tag = data.substr(doctype_start_index + 8, data.size() - doctype_start_index - 8 - 1); + _tag = _data.substr(doctype_start_index + 8, _data.size() - doctype_start_index - 8 - 1); } else { String tag_text; - if (data[data.size() - 2] == '/') { + if (_data[_data.size() - 2] == '/') { // will catch all that looks like
// tags that look like
will be caught later in a post process, in a way // which also tries to catch erroneously not closed tags that supposed to be closed - type = HTMLParserTag::HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG; + _type = HTMLParserTag::HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG; - tag_text = data.substr(1, data.size() - 3); + tag_text = _data.substr(1, _data.size() - 3); } else { - type = HTMLParserTag::HTML_PARSER_TAG_TYPE_OPENING_TAG; + _type = HTMLParserTag::HTML_PARSER_TAG_TYPE_OPENING_TAG; - tag_text = data.substr(1, data.size() - 2); + tag_text = _data.substr(1, _data.size() - 2); } int fspc_index = tag_text.find_char(' '); if (fspc_index == -1) { // no args - tag = tag_text; + _tag = tag_text; return; } // grab the tag itself - tag = tag_text.substr(0, fspc_index); + _tag = tag_text.substr(0, fspc_index); if (fspc_index + 1 == tag_text.size()) { // no args, but had a space like
@@ -218,17 +311,17 @@ void HTMLParserTag::process() { parse_args(args); } - int tag_end_index = data.find_char(' ', start_index); + int tag_end_index = _data.find_char(' ', start_index); if (tag_end_index == -1) { // simple tag - tag = data.substr(start_index, data.size() - start_index - 1); + _tag = _data.substr(start_index, _data.size() - start_index - 1); return; } } void HTMLParserTag::parse_args(const String &args) { - attributes.clear(); + _attributes.clear(); int i = 0; while (i < args.size()) { @@ -244,14 +337,14 @@ void HTMLParserTag::parse_args(const String &args) { a.instance(); if (equals_index == -1) { - a->attribute = args.substr(i, args.size() - i); - a->single = true; - attributes.push_back(a); + a->set_attribute(args.substr(i, args.size() - i)); + a->set_single(true); + _attributes.push_back(a); return; } - a->attribute = args.substr(i, equals_index - i); + a->set_attribute(args.substr(i, equals_index - i)); // todo // a.trim(); @@ -260,7 +353,7 @@ void HTMLParserTag::parse_args(const String &args) { if (next_char_index >= args.size()) { // an attribute looks like this "... attrib=" - attributes.push_back(a); + _attributes.push_back(a); return; } @@ -270,7 +363,7 @@ void HTMLParserTag::parse_args(const String &args) { if (next_char_index >= args.size()) { // an attribute looks like this "... attrib= " - attributes.push_back(a); + _attributes.push_back(a); return; } } @@ -289,13 +382,13 @@ void HTMLParserTag::parse_args(const String &args) { // missing closing ' or " if c is ' or " // else missing parameter - a->data = args.substr(next_char_index, args.size() - next_char_index - 1); - attributes.push_back(a); + a->set_data(args.substr(next_char_index, args.size() - next_char_index - 1)); + _attributes.push_back(a); return; } - a->data = args.substr(next_char_index, end_index - next_char_index); - attributes.push_back(a); + a->set_data(args.substr(next_char_index, end_index - next_char_index)); + _attributes.push_back(a); i = end_index + 1; } @@ -306,90 +399,90 @@ String HTMLParserTag::convert_to_string(const int level) const { s += String(" ").repeat(level); - if (type == HTML_PARSER_TAG_TYPE_CONTENT) { - s += data + "\n"; + if (_type == HTML_PARSER_TAG_TYPE_CONTENT) { + s += _data + "\n"; - if (tags.size() != 0) { + if (_tags.size() != 0) { s += String(" ").repeat(level); s += "(!CONTENT TAG HAS TAGS!)\n"; - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(level + 1) + "\n"; + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(level + 1) + "\n"; } } - } else if (type == HTML_PARSER_TAG_TYPE_OPENING_TAG) { + } else if (_type == HTML_PARSER_TAG_TYPE_OPENING_TAG) { int ln = level + 1; - s += "<" + tag; + s += "<" + _tag; - for (int i = 0; i < attributes.size(); ++i) { - s += " " + attributes[i]->convert_to_string(); + for (int i = 0; i < _attributes.size(); ++i) { + s += " " + _attributes[i]->convert_to_string(); } s += ">\n"; - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(ln); + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(ln); } s += String(" ").repeat(level); - s += "\n"; - } else if (type == HTML_PARSER_TAG_TYPE_CLOSING_TAG) { + s += "\n"; + } else if (_type == HTML_PARSER_TAG_TYPE_CLOSING_TAG) { // HTMLParserTag should handle this automatically // it's here for debugging purposes though - s += ""; + s += ""; - if (tags.size() != 0) { + if (_tags.size() != 0) { s += String(" ").repeat(level); s += "(!CLOSING TAG HAS TAGS!)\n"; - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(level + 1) + "\n"; + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(level + 1) + "\n"; } } - } else if (type == HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG) { - s += "<" + tag; + } else if (_type == HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG) { + s += "<" + _tag; - for (int i = 0; i < attributes.size(); ++i) { - s += " " + attributes[i]->convert_to_string(); + for (int i = 0; i < _attributes.size(); ++i) { + s += " " + _attributes[i]->convert_to_string(); } s += "/>\n"; - if (tags.size() != 0) { + if (_tags.size() != 0) { s += String(" ").repeat(level); s += "(!SELF CLOSING TAG HAS TAGS!)\n"; - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(level + 1) + "\n"; + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(level + 1) + "\n"; } } - } else if (type == HTML_PARSER_TAG_TYPE_COMMENT) { - s += "\n"; + } else if (_type == HTML_PARSER_TAG_TYPE_COMMENT) { + s += "\n"; - if (tags.size() != 0) { + if (_tags.size() != 0) { s += String(" ").repeat(level); s += "(!COMMENT TAG HAS TAGS!)\n"; - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(level + 1) + "\n"; + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(level + 1) + "\n"; } } - } else if (type == HTML_PARSER_TAG_TYPE_DOCTYPE) { - s += data + "\n"; + } else if (_type == HTML_PARSER_TAG_TYPE_DOCTYPE) { + s += _data + "\n"; - if (tags.size() != 0) { + if (_tags.size() != 0) { s += String(" ").repeat(level); s += "(!DOCTYPE TAG HAS TAGS!)\n"; - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(level + 1) + "\n"; + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(level + 1) + "\n"; } } - } else if (type == HTML_PARSER_TAG_TYPE_NONE) { - for (int i = 0; i < tags.size(); ++i) { - s += tags[i]->convert_to_string(level) + "\n"; + } else if (_type == HTML_PARSER_TAG_TYPE_NONE) { + for (int i = 0; i < _tags.size(); ++i) { + s += _tags[i]->convert_to_string(level) + "\n"; s += String(" ").repeat(level); } } @@ -401,12 +494,16 @@ void HTMLParserTag::print() const { } HTMLParserTag::HTMLParserTag() { - type = HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE; + _type = HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE; } HTMLParserTag::~HTMLParserTag() { - tags.clear(); - attributes.clear(); + _tags.clear(); + _attributes.clear(); +} + +Ref HTMLParser::get_root() { + return _root; } void HTMLParser::parse(const String &data) { @@ -436,7 +533,7 @@ void HTMLParser::parse(const String &data) { if (data[j] == '>') { Ref t = memnew(HTMLParserTag); - t->data = data.substr(i, j - i + 1); + t->set_data(data.substr(i, j - i + 1)); t->process(); tags.push_back(t); @@ -452,8 +549,8 @@ void HTMLParser::parse(const String &data) { if (data[j] == '<') { Ref t = memnew(HTMLParserTag); - t->data = data.substr(i, j - i); - t->type = HTMLParserTag::HTML_PARSER_TAG_TYPE_CONTENT; + t->set_data(data.substr(i, j - i)); + t->set_type(HTMLParserTag::HTML_PARSER_TAG_TYPE_CONTENT); tags.push_back(t); @@ -508,8 +605,8 @@ void HTMLParser::parse(const String &data) { state = STATE_NONE; Ref t = memnew(HTMLParserTag); - t->data = data.substr(i, j - i); - t->type = HTMLParserTag::HTML_PARSER_TAG_TYPE_CONTENT; + t->set_data(data.substr(i, j - i)); + t->set_type(HTMLParserTag::HTML_PARSER_TAG_TYPE_CONTENT); tags.push_back(t); @@ -520,7 +617,7 @@ void HTMLParser::parse(const String &data) { } } - root.instance(); + _root.instance(); // process tags into hierarchical order Vector> tag_stack; @@ -529,53 +626,53 @@ void HTMLParser::parse(const String &data) { ERR_CONTINUE(!t.is_valid()); - if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE) { + if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE) { ERR_PRINT("HTMLParser::parse: t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_NONE!"); //memdelete(t); tags.write[i].unref(); continue; - } else if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_OPENING_TAG) { + } else if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_OPENING_TAG) { tag_stack.push_back(t); tags.write[i].unref(); continue; - } else if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG) { + } else if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG) { if (tag_stack.size() == 0) { - root->tags.push_back(t); + _root->add_child_tag(t); } else { - tag_stack.write[tag_stack.size() - 1]->tags.push_back(t); + tag_stack.write[tag_stack.size() - 1]->add_child_tag(t); } tags.write[i].unref(); continue; - } else if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_CONTENT) { + } else if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_CONTENT) { if (tag_stack.size() == 0) { - root->tags.push_back(t); + _root->add_child_tag(t); } else { - tag_stack.write[tag_stack.size() - 1]->tags.push_back(t); + tag_stack.write[tag_stack.size() - 1]->add_child_tag(t); } tags.write[i].unref(); continue; - } else if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_COMMENT) { + } else if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_COMMENT) { if (tag_stack.size() == 0) { - root->tags.push_back(t); + _root->add_child_tag(t); } else { - tag_stack.write[tag_stack.size() - 1]->tags.push_back(t); + tag_stack.write[tag_stack.size() - 1]->add_child_tag(t); } tags.write[i].unref(); continue; - } else if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_DOCTYPE) { + } else if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_DOCTYPE) { if (tag_stack.size() == 0) { - root->tags.push_back(t); + _root->add_child_tag(t); } else { - tag_stack.write[tag_stack.size() - 1]->tags.push_back(t); + tag_stack.write[tag_stack.size() - 1]->add_child_tag(t); } tags.write[i].unref(); continue; - } else if (t->type == HTMLParserTag::HTML_PARSER_TAG_TYPE_CLOSING_TAG) { + } else if (t->get_type() == HTMLParserTag::HTML_PARSER_TAG_TYPE_CLOSING_TAG) { if (tag_stack.size() == 0) { tags.write[i].unref(); @@ -589,7 +686,7 @@ void HTMLParser::parse(const String &data) { Ref ts = tag_stack[j]; // we sould only have opening tags on the stack - if (ts->tag == t->tag) { + if (ts->get_tag() == t->get_tag()) { // found tag_index = j; break; @@ -603,16 +700,16 @@ void HTMLParser::parse(const String &data) { for (int j = tag_index + 1; j < tag_stack.size(); ++j) { Ref ts = tag_stack[j]; - ts->type = HTMLParserTag::HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG; - opening_tag->tags.push_back(ts); + ts->set_type(HTMLParserTag::HTML_PARSER_TAG_TYPE_SELF_CLOSING_TAG); + opening_tag->add_child_tag(ts); } tag_stack.resize(tag_index); if (tag_stack.size() == 0) { - root->tags.push_back(opening_tag); + _root->add_child_tag(opening_tag); } else { - tag_stack.write[tag_stack.size() - 1]->tags.push_back(opening_tag); + tag_stack.write[tag_stack.size() - 1]->add_child_tag(opening_tag); } tags.write[i].unref(); @@ -621,9 +718,9 @@ void HTMLParser::parse(const String &data) { } } - // add everything remaining on the stack to root + // add everything remaining on the stack to _root for (int i = 0; i < tag_stack.size(); ++i) { - root->tags.push_back(tag_stack[i]); + _root->add_child_tag(tag_stack[i]); } for (int i = 0; i < tags.size(); ++i) { @@ -637,15 +734,15 @@ void HTMLParser::parse(const String &data) { } String HTMLParser::convert_to_string() const { - if (!root.is_valid()) { + if (!_root.is_valid()) { return ""; } - return root->convert_to_string(); + return _root->convert_to_string(); } void HTMLParser::print() const { - if (root.is_valid()) { - root->print(); + if (_root.is_valid()) { + _root->print(); } } @@ -653,5 +750,5 @@ HTMLParser::HTMLParser() { } HTMLParser::~HTMLParser() { - root.unref(); + _root.unref(); } diff --git a/modules/web/html/html_parser.h b/modules/web/html/html_parser.h index 42a3ef39d..8289eacdf 100644 --- a/modules/web/html/html_parser.h +++ b/modules/web/html/html_parser.h @@ -10,9 +10,14 @@ class HTMLParserAttribute : public Reference { GDCLASS(HTMLParserAttribute, Reference); public: - String attribute; - String data; - bool single; + String get_attribute(); + void set_attribute(const String &val); + + String get_data(); + void set_data(const String &val); + + bool get_single(); + void set_single(const bool &val); bool match_attrib(const String &attrib); bool match_data(const String &d); @@ -24,6 +29,11 @@ public: HTMLParserAttribute(); virtual ~HTMLParserAttribute(); + +protected: + String _attribute; + String _data; + bool _single; }; class HTMLParserTag : public Reference { @@ -40,13 +50,32 @@ public: HTML_PARSER_TAG_TYPE_CONTENT }; - int type; + int get_type(); + void set_type(const int &val); - String tag; - String data; + String get_tag(); + void set_tag(const String &val); - Vector> tags; - Vector> attributes; + String get_data(); + void set_data(const String &val); + + void add_child_tag(const Ref &tag); + void remote_child_tag(const int index); + Ref get_child_tag(const int index); + int get_child_tag_count() const; + void clear_child_tags(); + + Vector get_child_tags(); + void set_child_tags(const Vector &val); + + void add_child_attribute(const Ref &tag); + void remote_child_attribute(const int index); + Ref get_child_attribute(const int index); + int get_child_attribute_count() const; + void clear_child_attributes(); + + Vector get_attributes(); + void set_attributes(const Vector &val); Ref get_first(const String &t); Ref get_first(const String &t, const String &attrib, const String &val); @@ -67,13 +96,22 @@ public: HTMLParserTag(); virtual ~HTMLParserTag(); + +protected: + int _type; + + String _tag; + String _data; + + Vector> _tags; + Vector> _attributes; }; class HTMLParser : public Reference { GDCLASS(HTMLParser, Reference); public: - Ref root; + Ref get_root(); void parse(const String &data); //void parse_tag(const String &data, const int index); @@ -83,6 +121,9 @@ public: HTMLParser(); virtual ~HTMLParser(); + +protected: + Ref _root; }; #endif