Method: ERBLint::Linters::TagTreeHelpers#build_tag_tree

Defined in:
lib/primer/view_components/linters/tag_tree_helpers.rb

#build_tag_tree(processed_source) ⇒ Object

This assumes that the AST provided represents valid HTML, where each tag has a corresponding closing tag. From the tags, we build a structured tree which represents the tag hierarchy. With this, we are able to know where the tags start and end.

[View source]

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/primer/view_components/linters/tag_tree_helpers.rb', line 16

def build_tag_tree(processed_source)
  nodes = processed_source.ast.children
  tag_tree = {}
  tags = []
  current_opened_tag = nil

  nodes.each do |node|
    if node.type == :tag
      # get the tag from previously calculated list so the references are the same
      tag = BetterHtml::Tree::Tag.from_node(node)
      tags << tag

      if tag.closing?
        if current_opened_tag && tag.name == current_opened_tag.name
          tag_tree[current_opened_tag][:closing] = tag
          current_opened_tag = tag_tree[current_opened_tag][:parent]
        end

        next
      end

      self_closing = self_closing?(tag)

      tag_tree[tag] = {
        tag: tag,
        closing: self_closing ? tag : nil,
        parent: current_opened_tag,
        children: []
      }

      tag_tree[current_opened_tag][:children] << tag_tree[tag] if current_opened_tag
      current_opened_tag = tag unless self_closing
    elsif current_opened_tag
      tag_tree[current_opened_tag][:children] << node
    end
  end

  [tags, tag_tree]
end