Module: Heartml::ServerEffects

Included in:
Heartml
Defined in:
lib/heartml/server_effects.rb

Defined Under Namespace

Modules: ClassMethods, JSPropertyAliases

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included_extras(klass) ⇒ void

This method returns an undefined value.

Parameters:

  • klass (Class)


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
# File 'lib/heartml/server_effects.rb', line 39

def self.included_extras(klass) # rubocop:disable Metrics
  klass.attribute_binding "server-effect", :_server_effect_binding
  klass.attribute_binding "iso-effect", :_iso_effect_binding

  klass.singleton_class.attr_reader :directives

  klass.extend ClassMethods

  klass.class_eval do
    directive :show, ->(_, node, value) { node["hidden"] = "" unless value }

    directive :hide, ->(_, node, value) { node["hidden"] = "" if value }

    directive :classMap, ->(_, node, obj) {
      obj.each do |k, v|
        node.add_class k.to_s if v
      end
    }

    directive :attribute, ->(_, node, name, value) {
      node[name] = value if name.match?(%r{^aria[A-Z-]}) || value
    }

    directive :appendUnsafe, ->(_, node, value) {
      node.swap(value.is_a?(Nokolexbor::Node) ? value : value.to_s)
    }

    directive :append, ->(_, node, value) {
      span = node.document.create_element("span")
      span.content = value.to_s
      node.swap(span.inner_html)
    }
  end
end

Instance Method Details

#_convert_effect_arg_to_value(arg_str, node) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/heartml/server_effects.rb', line 128

def _convert_effect_arg_to_value(arg_str, node)
  return node if arg_str == "@"

  return arg_str[1...-1] if arg_str.start_with?("'") # string literal

  if arg_str.match(/^[0-9]/)
    return arg_str.include?(".") ? arg_str.to_f : arg_str.to_i
  end

  send(arg_str[1..])
end

#_iso_effect_binding(attribute:, node:) ⇒ Object

rubocop:disable Metrics



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/heartml/server_effects.rb', line 79

def _iso_effect_binding(attribute:, node:) # rubocop:disable Metrics
  syntax = attribute.value
  statements = syntax.split(";").map(&:strip)

  statements.each do |statement| # rubocop:disable Metrics
    if statement.start_with?(".")
      # shortcut for text content
      statement = "@textContent=#{statement}"
    end

    if statement.start_with?("@")
      # property assignment
      expression = statement.split("=").map(&:strip)
      expression[0] = expression[0][1..]

      value = send(expression[1][1..])
      attribute_value = if expression[0].match?(%r{^aria[A-Z-]}) && [true, false].include?(value)
                          value
                        else
                          value_to_attribute(value)
                        end

      node.send("#{expression[0]}=", attribute_value) unless attribute_value.nil?
    elsif statement.start_with?("$")
      # directive
      directive_name, args_str = statement.strip.match(/(.*)\((.*)\)/).captures
      arg_strs = args_str.split(",").map(&:strip)
      arg_strs.unshift("@")

      if self.class.directives[directive_name.strip[1..]]
        args = arg_strs.map { _convert_effect_arg_to_value _1, node }

        self.class.directives[directive_name.strip[1..]]&.(self, *args)
      end
    else
      # method call
      method_name, args_str = statement.strip.match(/(.*)\((.*)\)/).captures
      arg_strs = args_str.split(",").map(&:strip)
      arg_strs.unshift("@")

      args = arg_strs.map { _convert_effect_arg_to_value _1, node }

      send(method_name.strip, *args)
    end

    attribute.name = "host-lazy-effect"
  end
end

#_server_effect_binding(attribute:, node:) ⇒ Object



74
75
76
77
# File 'lib/heartml/server_effects.rb', line 74

def _server_effect_binding(attribute:, node:)
  _iso_effect_binding(attribute:, node:)
  node.remove_attribute "host-lazy-effect"
end