Welcome to mirror list, hosted at ThFree Co, Russian Federation.

no_plain_nodes.rb « linter « haml_lint - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d0d9c165a1948a43f6b0793bd09af0c0f61a6571 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# frozen_string_literal: true

require 'active_support/core_ext/array/grouping'

module HamlLint
  class Linter
    class NoPlainNodes < Linter
      include ::HamlLint::LinterRegistry

      def visit_tag(node)
        if inline_plain_node?(node)
          check_inline(node)
        elsif !node.script.empty?
          check_script(node)
        else
          check(node)
        end
      end

      private

      def check(node)
        text_in_node(node).each { |string| record(node, string) }
      end

      def check_inline(node)
        text = inline_text(node)
        record(node, text) unless text.empty?
      end

      def check_script(node)
        text = inline_text(node)
        record(node, text) unless text.start_with?('=') || text.empty?
      end

      # Build an array of all strings in child text nodes.
      # non text nodes are nil, where we'll split the sentences.
      def text_in_node(node)
        texts = node.children.map do |child|
          child.text.strip if text_node?(child)
        end

        texts.split(nil).map { |sentence| sentence.join(' ') unless sentence.empty? }.compact
      end

      # Removes a node's attributes and tag from the source code,
      # returning the inline text of a node.
      def inline_text(node)
        text = node.source_code.gsub("%#{node.tag_name}", '')

        attributes = node.attributes_source.map(&:last)
        attributes.each { |attribute| text = text.gsub(attribute, '') }

        text = strip_html_entities(text)
        text.strip
      end

      def record(node, string)
        record_lint(node, message(string))
      end

      def message(string)
        "`#{string}` is a plain node. Please use an i18n method like `#{fixed(string)}`"
      end

      def fixed(string)
        "= _('#{string}')"
      end

      def inline_plain_node?(node)
        node.children.empty? && node.script.empty?
      end

      def plain_node?(node)
        node.is_a?(::HamlLint::Tree::PlainNode)
      end

      def text_node?(node)
        return false unless plain_node?(node)

        text = strip_html_entities(node.text)
        !text.empty?
      end

      def strip_html_entities(text)
        text.gsub(/&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});/i, "")
      end
    end
  end
end