Module: ERBLint::Linters::TagTreeHelpers

Included in:
BaseLinter, DisallowActionList, TwoColumnLayoutMigrationCounter
Defined in:
lib/primer/view_components/linters/tag_tree_helpers.rb

Overview

Helpers used by linters to organize HTML tags into abstract syntax trees.

Constant Summary collapse

SELF_CLOSING_TAGS =
%w[
  area base br col command embed hr input keygen
  link menuitem meta param source track wbr img
].freeze

Instance Method Summary collapse

Instance Method Details

#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

#self_closing?(tag) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

56
57
58
# File 'lib/primer/view_components/linters/tag_tree_helpers.rb', line 56

def self_closing?(tag)
  tag.self_closing? || SELF_CLOSING_TAGS.include?(tag.name)
end