Class: ORB::Temple::AttributesCompiler

Inherits:
Object
  • Object
show all
Defined in:
lib/orb/temple/attributes_compiler.rb

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ AttributesCompiler



6
7
8
# File 'lib/orb/temple/attributes_compiler.rb', line 6

def initialize(options = {})
  @options = options
end

Instance Method Details

#compile_attribute(attribute) ⇒ Object

Compile a single attribute into Temple core abstraction an attribute can be a static string, a dynamic expression, or a boolean attribute (an attribute without a value, e.g. disabled, checked, etc.)

For boolean attributes, we return a [:dynamic, “nil”] expression, so that the final render for the attribute will be ‘attribute` instead of `attribute=“true”`



77
78
79
80
81
82
83
84
85
# File 'lib/orb/temple/attributes_compiler.rb', line 77

def compile_attribute(attribute)
  if attribute.string?
    [:html, :attr, attribute.name, [:static, attribute.value]]
  elsif attribute.bool?
    [:html, :attr, attribute.name, [:dynamic, "nil"]]
  elsif attribute.expression?
    [:html, :attr, attribute.name, [:dynamic, attribute.value]]
  end
end

#compile_attributes(attributes) ⇒ Object

Compile the attributes of a node into a Temple core abstraction



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/orb/temple/attributes_compiler.rb', line 52

def compile_attributes(attributes)
  temple = [:html, :attrs]

  attributes.each do |attribute|
    # Ignore splat attributes
    next if attribute.splat?

    temple << compile_attribute(attribute)
  end

  temple
end

#compile_captures(attributes, prefix) ⇒ Object

Compile the given array of AST::Attribute objects into Temple capture expressions using the given prefix in variable names



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/orb/temple/attributes_compiler.rb', line 12

def compile_captures(attributes, prefix)
  result = []

  attributes.each do |attribute|
    # TODO: handle splat attributes
    next if attribute.splat?

    # generate a unique variable name for the attribute
    var_name = prefixed_variable_name(attribute.name, prefix)

    # inject a code expression for the attribute value and assign to the variable
    if attribute.string?
      result << [:code, "#{var_name} = \"#{attribute.value}\""]
    elsif attribute.bool?
      result << [:code, "#{var_name} = true"]
    elsif attribute.expression?
      result << [:code, "#{var_name} = #{attribute.value}"]
    end
  end

  result
end

#compile_komponent_args(attributes, prefix) ⇒ Object

Compile the given array of AST::Attribute objects into a string of arguments the can be used in a ViewComponent constructor call, as long as the compiled captures are available in the same scope.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/orb/temple/attributes_compiler.rb', line 38

def compile_komponent_args(attributes, prefix)
  args = {}
  attributes.each do |attribute|
    # TODO: handle splat attributes
    next if attribute.splat?

    var_name = prefixed_variable_name(attribute.name, prefix)
    args = args.deep_merge(dash_to_hash(attribute.name, var_name))
  end

  hash_to_args_list(args)
end

#compile_splat_attributes(attributes) ⇒ Object

Compile splat attributes to a code string



67
68
69
# File 'lib/orb/temple/attributes_compiler.rb', line 67

def compile_splat_attributes(attributes)
  attributes.map(&:value).join(',')
end

#dash_to_hash(name, value) ⇒ Object



87
88
89
90
# File 'lib/orb/temple/attributes_compiler.rb', line 87

def dash_to_hash(name, value)
  parts = name.split('-')
  parts.reverse.inject(value) { |a, n| { n => a } }
end

#hash_to_args_list(obj, level = -1)) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/orb/temple/attributes_compiler.rb', line 92

def hash_to_args_list(obj, level = -1)
  case obj
  when String
    obj
  when Array
    obj.map { |v| hash_to_args_list(v, level + 1) }.join(", ")
  when Hash
    down_the_rabbit_hole = obj.map { |k, v| "#{k}: #{hash_to_args_list(v, level + 1)}" }.join(", ")
    return down_the_rabbit_hole if level.negative?

    "{#{down_the_rabbit_hole}}"

  else
    raise "Invalid argument passed to hash_to_args_list: #{obj.inspect}"
  end
end

#prefixed_variable_name(name, prefix) ⇒ Object



109
110
111
# File 'lib/orb/temple/attributes_compiler.rb', line 109

def prefixed_variable_name(name, prefix)
  "#{prefix}_arg_#{name.underscore}"
end