Module: Ruwi::Template::BuildForGroup

Defined in:
lib/ruwi/runtime/template/build_for_group.rb

Class Method Summary collapse

Class Method Details

.build_component_for_item(element, tag_name, filtered_attributes, item_var) ⇒ String

Build component code for a single item in the loop

Parameters:

  • element (JS.Object)
  • tag_name (String)
  • filtered_attributes (Array)
  • item_var (String)

Returns:

  • (String)


102
103
104
105
106
107
108
109
# File 'lib/ruwi/runtime/template/build_for_group.rb', line 102

def build_component_for_item(element, tag_name, filtered_attributes, item_var)
  attributes_str = Ruwi::Template::BuildVdom.parse_attributes(filtered_attributes)
  children = Ruwi::Template::BuildVdom.build(element[:childNodes])

  # Convert kebab-case to PascalCase for component name
  component_name = tag_name.split('-').map(&:capitalize).join
  "Ruwi::Vdom.h(#{component_name}, {#{attributes_str}}, [#{children}])"
end

.build_element_for_item(element, tag_name, filtered_attributes, item_var) ⇒ String

Build element code for a single item in the loop

Parameters:

  • element (JS.Object)
  • tag_name (String)
  • filtered_attributes (Array)
  • item_var (String)

Returns:

  • (String)


117
118
119
120
121
122
# File 'lib/ruwi/runtime/template/build_for_group.rb', line 117

def build_element_for_item(element, tag_name, filtered_attributes, item_var)
  attributes_str = Ruwi::Template::BuildVdom.parse_attributes(filtered_attributes)
  children = Ruwi::Template::BuildVdom.build(element[:childNodes])

  "Ruwi::Vdom.h('#{tag_name}', {#{attributes_str}}, [#{children}])"
end

.build_for_loop(element) ⇒ String

Build for loop code for r-for attribute

Parameters:

  • element (JS.Object)

Returns:

  • (String)


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
# File 'lib/ruwi/runtime/template/build_for_group.rb', line 26

def build_for_loop(element)
  for_expression = get_for_expression(element)
  return '' unless for_expression

  # Parse r-for expression like "{todo in todos}"
  # Remove curly braces and parse
  clean_expression = for_expression.gsub(/^\{|\}$/, '').strip

  # Match pattern: "item in collection"
  if clean_expression.match(/^(\w+)\s+in\s+(.+)$/)
    item_var = $1
    collection_expr = $2

    # Get the tag name and filtered attributes (excluding r-for)
    tag_name = element[:tagName].to_s.downcase
    filtered_attributes = filter_for_attributes(element[:attributes])

    # Generate the map code
    if Ruwi::Template::BuildVdom.is_component?(tag_name)
      component_code = build_component_for_item(element, tag_name, filtered_attributes, item_var)
      "#{collection_expr}.map do |#{item_var}|\n  #{component_code}\nend"
    else
      element_code = build_element_for_item(element, tag_name, filtered_attributes, item_var)
      "#{collection_expr}.map do |#{item_var}|\n  #{element_code}\nend"
    end
  else
    # Fallback for invalid r-for syntax
    ''
  end
end

.filter_for_attributes(attributes) ⇒ Array

Filter out r-for attribute from the attributes list

Parameters:

  • attributes (JS.Object)

Returns:

  • (Array)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/ruwi/runtime/template/build_for_group.rb', line 77

def filter_for_attributes(attributes)
  filtered = []
  length = attributes[:length].to_i

  length.times do |i|
    attribute = attributes[i]
    key = attribute[:name].to_s
    value = attribute[:value].to_s

    # Skip r-for attribute
    next if key == 'r-for'

    # Create attribute object in the format expected by parse_attributes
    filtered << { name: key, value: value }
  end

  filtered
end

.get_for_expression(element) ⇒ String?

Get r-for expression from element attributes

Parameters:

  • element (JS.Object)

Returns:

  • (String, nil)


60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ruwi/runtime/template/build_for_group.rb', line 60

def get_for_expression(element)
  length = element[:attributes][:length].to_i
  length.times do |i|
    attribute = element[:attributes][i]
    key = attribute[:name].to_s
    value = attribute[:value].to_s

    if key == 'r-for'
      return Ruwi::Template::BuildVdom.embed_script?(value) ? Ruwi::Template::BuildVdom.get_embed_script(value) : value
    end
  end
  nil
end

.has_for_attribute?(element) ⇒ Boolean

Check if element has r-for attribute

Parameters:

  • element (JS.Object)

Returns:

  • (Boolean)


11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ruwi/runtime/template/build_for_group.rb', line 11

def has_for_attribute?(element)
  return false unless element[:attributes]

  length = element[:attributes][:length].to_i
  length.times do |i|
    attribute = element[:attributes][i]
    key = attribute[:name].to_s
    return true if key == 'r-for'
  end
  false
end