mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
net.html: add get_tags_by_class_name (#17024)
This commit is contained in:
parent
6688c0f3d7
commit
d850d3caba
@ -185,3 +185,8 @@ pub fn (dom DocumentObjectModel) get_root() &Tag {
|
||||
pub fn (dom DocumentObjectModel) get_tags() []&Tag {
|
||||
return dom.all_tags
|
||||
}
|
||||
|
||||
// get_tags_by_class_name retrieves all the tags recursively in the document that has the given class name(s).
|
||||
pub fn (dom DocumentObjectModel) get_tags_by_class_name(names ...string) []&Tag {
|
||||
return dom.root.get_tags_by_class_name(...names)
|
||||
}
|
||||
|
@ -54,3 +54,33 @@ fn test_access_tag_fields() {
|
||||
assert id_tags[0].name == 'div'
|
||||
assert id_tags[1].attributes['class'] == 'several-1'
|
||||
}
|
||||
|
||||
fn generate_temp_html_with_classes() string {
|
||||
mut temp_html := strings.new_builder(400)
|
||||
temp_html.write_string('<!doctype html><html><head><title>Giant String</title></head><body>')
|
||||
temp_html.write_string("<div class='single'>Single</div>")
|
||||
for counter := 0; counter < 4; counter++ {
|
||||
temp_html.write_string("<div id='name_${counter}' ")
|
||||
temp_html.write_string("class='common'>Common No. ${counter}</div>")
|
||||
}
|
||||
temp_html.write_string("<div class='complex-0 complex-1 complex-2'>Complex</div>")
|
||||
temp_html.write_string("<div class='complex-0 complex-2'>Partial</div>")
|
||||
temp_html.write_string('</body></html>')
|
||||
return temp_html.str()
|
||||
}
|
||||
|
||||
fn test_search_by_class() {
|
||||
dom := parse(generate_temp_html_with_classes())
|
||||
single_class_tags := dom.get_tags_by_class_name('single')
|
||||
common_class_tags := dom.get_tags_by_class_name('common')
|
||||
complex_class_tags := dom.get_tags_by_class_name('complex-0', 'complex-1', 'complex-2')
|
||||
partial_class_tags := dom.get_tags_by_class_name('complex-0', 'complex-2')
|
||||
shuffled_class_tags := dom.get_tags_by_class_name('complex-2', 'complex-0', 'complex-1')
|
||||
assert single_class_tags.len == 1
|
||||
assert common_class_tags.len == 4
|
||||
assert complex_class_tags.len == 1
|
||||
assert complex_class_tags[0].attributes['class'] == 'complex-0 complex-1 complex-2'
|
||||
assert partial_class_tags.len == 2
|
||||
assert shuffled_class_tags.len == 1
|
||||
assert shuffled_class_tags[0].attributes['class'] == 'complex-0 complex-1 complex-2'
|
||||
}
|
||||
|
@ -151,6 +151,13 @@ pub fn (mut parser Parser) split_parse(data string) {
|
||||
nval := temp_lexeme.substr(1, temp_lexeme.len - 1)
|
||||
// parser.print_debug(lattr + " = " + temp_lexeme)
|
||||
parser.lexical_attributes.current_tag.attributes[lattr] = nval
|
||||
if lattr == 'class' {
|
||||
for class_name in nval.split_any('\t\r\n \x0D') {
|
||||
if class_name != '' {
|
||||
parser.lexical_attributes.current_tag.class_set.add(class_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.lexical_attributes.current_tag.last_attribute = ''
|
||||
} else {
|
||||
parser.lexical_attributes.current_tag.attributes[temp_lexeme.to_lower()] = ''
|
||||
|
@ -1,6 +1,7 @@
|
||||
module html
|
||||
|
||||
import strings
|
||||
import datatypes
|
||||
|
||||
enum CloseTagType {
|
||||
in_name
|
||||
@ -16,6 +17,7 @@ pub mut:
|
||||
children []&Tag
|
||||
attributes map[string]string // attributes will be like map[name]value
|
||||
last_attribute string
|
||||
class_set datatypes.Set[string]
|
||||
parent &Tag = unsafe { nil }
|
||||
position_in_parent int
|
||||
closed bool
|
||||
@ -102,3 +104,22 @@ pub fn (tag &Tag) get_tags_by_attribute_value(name string, value string) []&Tag
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 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{}
|
||||
for child in tag.children {
|
||||
mut matched := true
|
||||
for name in names {
|
||||
matched = child.class_set.exists(name)
|
||||
if !matched {
|
||||
break
|
||||
}
|
||||
}
|
||||
if matched {
|
||||
res << child
|
||||
}
|
||||
res << child.get_tags_by_class_name(...names)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
module html
|
||||
|
||||
import strings
|
||||
|
||||
const (
|
||||
html = '<!doctype html>
|
||||
<html>
|
||||
@ -34,4 +36,36 @@ fn test_search_by_tag_type() {
|
||||
assert tag.get_tags('div').len == 5
|
||||
assert tag.get_tags_by_attribute('href')[2].content == 'vpm'
|
||||
assert tag.get_tags_by_attribute_value('class', 'bar').len == 3
|
||||
assert tag.get_tags_by_class_name('bar').len == 3
|
||||
}
|
||||
|
||||
fn generate_temp_html_with_classes() string {
|
||||
mut temp_html := strings.new_builder(400)
|
||||
temp_html.write_string('<!doctype html><html><head><title>Giant String</title></head><body>')
|
||||
temp_html.write_string("<div class='single'>Single</div>")
|
||||
for counter := 0; counter < 4; counter++ {
|
||||
temp_html.write_string("<div id='name_${counter}' ")
|
||||
temp_html.write_string("class='common'>Common No. ${counter}</div>")
|
||||
}
|
||||
temp_html.write_string("<div class='complex-0 complex-1 complex-2'>Complex</div>")
|
||||
temp_html.write_string("<div class='complex-0 complex-2'>Partial</div>")
|
||||
temp_html.write_string('</body></html>')
|
||||
return temp_html.str()
|
||||
}
|
||||
|
||||
fn test_search_by_class() {
|
||||
mut dom := parse(generate_temp_html_with_classes())
|
||||
tag := dom.get_tag('body')[0]
|
||||
single_class_tags := tag.get_tags_by_class_name('single')
|
||||
common_class_tags := tag.get_tags_by_class_name('common')
|
||||
complex_class_tags := tag.get_tags_by_class_name('complex-0', 'complex-1', 'complex-2')
|
||||
partial_class_tags := tag.get_tags_by_class_name('complex-0', 'complex-2')
|
||||
shuffled_class_tags := tag.get_tags_by_class_name('complex-2', 'complex-0', 'complex-1')
|
||||
assert single_class_tags.len == 1
|
||||
assert common_class_tags.len == 4
|
||||
assert complex_class_tags.len == 1
|
||||
assert complex_class_tags[0].attributes['class'] == 'complex-0 complex-1 complex-2'
|
||||
assert partial_class_tags.len == 2
|
||||
assert shuffled_class_tags.len == 1
|
||||
assert shuffled_class_tags[0].attributes['class'] == 'complex-0 complex-1 complex-2'
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user