1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

net.html: add &Tag get_tag methods to find first occurrence (#18139)

This commit is contained in:
Turiiya
2023-05-08 23:22:52 +02:00
committed by GitHub
parent 1e56a69c02
commit e2e6c9660c
2 changed files with 72 additions and 2 deletions

View File

@ -69,6 +69,19 @@ pub fn (tag &Tag) str() string {
return html_str.str()
}
// get_tag retrieves the first found child tag in the tag that has the given tag name.
pub fn (tag &Tag) get_tag(name string) ?&Tag {
for child in tag.children {
if child.name == name {
return child
}
if c := child.get_tag(name) {
return c
}
}
return none
}
// get_tags retrieves all the child tags recursively in the tag that has the given tag name.
pub fn (tag &Tag) get_tags(name string) []&Tag {
mut res := []&Tag{}
@ -81,6 +94,20 @@ pub fn (tag &Tag) get_tags(name string) []&Tag {
return res
}
// get_tag_by_attribute retrieves the first found child tag in the tag that has the given attribute name.
pub fn (tag &Tag) get_tag_by_attribute(name string) ?&Tag {
// mut res := &Tag{}
for child in tag.children {
if child.attributes[name] != '' {
return child
}
if c := child.get_tag_by_attribute(name) {
return c
}
}
return none
}
// get_tags_by_attribute retrieves all the child tags recursively in the tag that has the given attribute name.
pub fn (tag &Tag) get_tags_by_attribute(name string) []&Tag {
mut res := []&Tag{}
@ -93,6 +120,19 @@ pub fn (tag &Tag) get_tags_by_attribute(name string) []&Tag {
return res
}
// get_tag_by_attribute_value retrieves the first found child tag in the tag that has the given attribute name and value.
pub fn (tag &Tag) get_tag_by_attribute_value(name string, value string) ?&Tag {
for child in tag.children {
if child.attributes[name] == value {
return child
}
if c := child.get_tag_by_attribute_value(name, value) {
return c
}
}
return none
}
// get_tags_by_attribute_value retrieves all the child tags recursively in the tag that has the given attribute name and value.
pub fn (tag &Tag) get_tags_by_attribute_value(name string, value string) []&Tag {
mut res := []&Tag{}
@ -105,6 +145,26 @@ pub fn (tag &Tag) get_tags_by_attribute_value(name string, value string) []&Tag
return res
}
// get_tag_by_class_name retrieves the first found child tag in the tag that has the given class name(s).
pub fn (tag &Tag) get_tag_by_class_name(names ...string) ?&Tag {
for child in tag.children {
mut matched := true
for name in names {
matched = child.class_set.exists(name)
if !matched {
break
}
}
if matched {
return child
}
if c := child.get_tag_by_class_name(...names) {
return c
}
}
return none
}
// get_tags_by_class_name retrieves all the child tags recursively in the tag that has the given class name(s).
pub fn (tag &Tag) get_tags_by_class_name(names ...string) []&Tag {
mut res := []&Tag{}

View File

@ -8,7 +8,7 @@ const (
<head></head>
<body>
<div id="1st">
<div class="bar"></div>
<div class="foo bar"></div>
</div>
<div id="2nd">
<div class="foo">
@ -30,7 +30,17 @@ const (
</html>'
)
fn test_search_by_tag_type() {
fn test_search_tag_by_type() {
mut dom := parse(html.html)
tag := dom.get_tag('body')[0]
assert tag.get_tag('div') or { assert false }.attributes['id'] == '1st'
assert tag.get_tag_by_attribute('href') or { assert false }.content == 'V'
// TODO: update after improved parsing to not add trailing white space to attribute values
assert tag.get_tag_by_attribute_value('id', '3rd') or { assert false }.str() == '<div id="3rd" ></div>'
assert tag.get_tag_by_class_name('foo') or { assert false }.attributes['class'] == 'foo bar'
}
fn test_search_tags_by_type() {
mut dom := parse(html.html)
tag := dom.get_tag_by_attribute_value('id', '2nd')[0]
assert tag.get_tags('div').len == 5