Class: Herb::Engine::Validators::NestingValidator
Instance Attribute Summary
#diagnostics, #enabled
Instance Method Summary
collapse
#add_diagnostic, #clear_diagnostics, #diagnostic_count, #enabled?, #error, #errors, #errors?, #hint, #info, #initialize, #validate, #warning, #warnings, #warnings?
Methods inherited from Visitor
#visit, #visit_all, #visit_cdata_node, #visit_child_nodes, #visit_document_node, #visit_erb_begin_node, #visit_erb_block_node, #visit_erb_case_match_node, #visit_erb_case_node, #visit_erb_content_node, #visit_erb_else_node, #visit_erb_end_node, #visit_erb_ensure_node, #visit_erb_for_node, #visit_erb_if_node, #visit_erb_in_node, #visit_erb_node, #visit_erb_open_tag_node, #visit_erb_render_node, #visit_erb_rescue_node, #visit_erb_strict_locals_node, #visit_erb_unless_node, #visit_erb_until_node, #visit_erb_when_node, #visit_erb_while_node, #visit_erb_yield_node, #visit_html_attribute_name_node, #visit_html_attribute_node, #visit_html_attribute_value_node, #visit_html_close_tag_node, #visit_html_comment_node, #visit_html_conditional_element_node, #visit_html_conditional_open_tag_node, #visit_html_doctype_node, #visit_html_omitted_close_tag_node, #visit_html_open_tag_node, #visit_html_text_node, #visit_html_virtual_close_tag_node, #visit_literal_node, #visit_node, #visit_ruby_html_attributes_splat_node, #visit_ruby_literal_node, #visit_ruby_parameter_node, #visit_ruby_render_keywords_node, #visit_ruby_render_local_node, #visit_whitespace_node, #visit_xml_declaration_node
#erb_comment?, #erb_graphql?, #erb_output?, #erb_outputs?, #inline_ruby_comment?
Instance Method Details
#add_validation_error(type, location, message) ⇒ Object
89
90
91
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 89
def add_validation_error(type, location, message)
error(message, location, code: type, source: "NestingValidator")
end
|
#find_nested_elements(node, tag_name, &block) ⇒ void
This method returns an undefined value.
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 77
def find_nested_elements(node, tag_name, &block)
node.body.each do |child|
if child.is_a?(Herb::AST::HTMLElementNode)
if child.tag_name&.value&.downcase == tag_name
yield child
else
find_nested_elements(child, tag_name, &block)
end
end
end
end
|
#validate_html_nesting(node) ⇒ Object
19
20
21
22
23
24
25
26
27
28
29
30
31
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 19
def validate_html_nesting(node)
tag_name = node.tag_name&.value&.downcase
return unless tag_name
case tag_name
when "p"
validate_no_block_elements_in_paragraph(node)
when "a"
validate_no_nested_anchors(node)
when "button"
validate_no_interactive_in_button(node)
end
end
|
#validate_no_block_elements_in_paragraph(node) ⇒ Object
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 33
def validate_no_block_elements_in_paragraph(node)
block_elements = ["div", "section", "article", "header", "footer", "nav", "aside", "p", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "dl", "table", "form"]
node.body.each do |child|
next unless child.is_a?(Herb::AST::HTMLElementNode)
child_tag = child.tag_name&.value&.downcase
next unless child_tag && block_elements.include?(child_tag)
add_validation_error(
"InvalidNestingError",
child.location,
"Block element <#{child_tag}> cannot be nested inside <p> at line #{child.location.start.line}"
)
end
end
|
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 60
def validate_no_interactive_in_button(node)
interactive_elements = ["a", "button", "input", "select", "textarea"]
node.body.each do |child|
next unless child.is_a?(Herb::AST::HTMLElementNode)
child_tag = child.tag_name&.value&.downcase
next unless child_tag && interactive_elements.include?(child_tag)
add_validation_error(
"InvalidNestingError",
child.location,
"Interactive element <#{child_tag}> cannot be nested inside <button> at line #{child.location.start.line}"
)
end
end
|
#validate_no_nested_anchors(node) ⇒ Object
50
51
52
53
54
55
56
57
58
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 50
def validate_no_nested_anchors(node)
find_nested_elements(node, "a") do |nested|
add_validation_error(
"NestedAnchorError",
nested.location,
"Anchor <a> cannot be nested inside another anchor at line #{nested.location.start.line}"
)
end
end
|
#visit_html_element_node(node) ⇒ Object
12
13
14
15
|
# File 'lib/herb/engine/validators/nesting_validator.rb', line 12
def visit_html_element_node(node)
validate_html_nesting(node)
super
end
|