Module: Ruwi::Template::BuildConditionalGroup

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

Class Method Summary collapse

Class Method Details

.build_conditional_group(elements, start_index) ⇒ Array

Build conditional group (r-if, r-elsif, r-else)

Parameters:

  • elements (JS.Array)

    Array of elements

  • start_index (Integer)

    Starting index

Returns:

  • (Array)

    [conditional_code, next_index]



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

def build_conditional_group(elements, start_index)
  conditions = []
  current_index = start_index
  elements_length = elements[:length].to_i

  # Process all consecutive conditional elements
  while current_index < elements_length
    element = elements[current_index]
    # Skip text nodes (whitespace between elements)
    if element[:nodeType] == JS.global[:Node][:TEXT_NODE]
      current_index += 1
      next
    end

    # Break if this is not an element with conditional attributes
    unless element[:nodeType] == JS.global[:Node][:ELEMENT_NODE] && has_conditional_attribute?(element)
      break
    end

    conditional_type = get_conditional_type(element)

    # If we encounter a new r-if after the first one, break the group
    if conditions.any? && conditional_type == 'r-if'
      break
    end

    condition = get_conditional_expression(element)
    content = build_single_conditional_content(element)

    case conditional_type
    when 'r-if'
      conditions << "if #{condition}"
      conditions << "  #{content}"
    when 'r-elsif'
      conditions << "elsif #{condition}"
      conditions << "  #{content}"
    when 'r-else'
      conditions << "else"
      conditions << "  #{content}"
      current_index += 1
      break
    end

    current_index += 1
  end

  # Add final else clause if not present
  unless conditions.any? { |c| c == 'else' }
    conditions << "else"
    conditions << "  Ruwi::Vdom.h_fragment([])"
  end

  conditions << "end"

  [conditions.join("\n"), current_index]
end

.build_single_conditional_content(element) ⇒ String

Build content for a single conditional element

Parameters:

  • element (JS.Object)

Returns:

  • (String)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ruwi/runtime/template/build_conditional_group.rb', line 87

def build_single_conditional_content(element)
  tag_name = element[:tagName].to_s.downcase
  filtered_attributes = filter_conditional_attributes(element[:attributes])

  if tag_name == 'template' || (tag_name == 'div' && BuildVdom.has_data_template_attribute?(element))
    # For template elements, render the content directly
    BuildVdom.build_fragment(element, tag_name)
  elsif BuildVdom.is_component?(tag_name)
    # For components, render the component
    BuildVdom.build_component(element, tag_name, filtered_attributes)
  else
    # For regular HTML elements, render the element
    BuildVdom.build_element(element, tag_name, filtered_attributes)
  end
end

.filter_conditional_attributes(attributes) ⇒ Array

Filter out conditional attributes from the attributes list

Parameters:

  • attributes (JS.Object)

Returns:

  • (Array)


136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ruwi/runtime/template/build_conditional_group.rb', line 136

def filter_conditional_attributes(attributes)
  filtered = []
  length = attributes[:length].to_i
  length.times do |i|
    attribute = attributes[i]
    key = attribute[:name].to_s
    unless %w[r-if r-elsif r-else data-template].include?(key)
      filtered << attribute
    end
  end
  filtered
end

.get_conditional_expression(element) ⇒ String

Get conditional expression from element attributes

Parameters:

  • element (JS.Object)

Returns:

  • (String)


106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ruwi/runtime/template/build_conditional_group.rb', line 106

def get_conditional_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 %w[r-if r-elsif].include?(key)
      return BuildVdom.embed_script?(value) ? BuildVdom.get_embed_script(value) : value
    end
  end
  'true' # fallback for r-else
end

.get_conditional_type(element) ⇒ String

Get conditional type from element attributes

Parameters:

  • element (JS.Object)

Returns:

  • (String)


123
124
125
126
127
128
129
130
131
# File 'lib/ruwi/runtime/template/build_conditional_group.rb', line 123

def get_conditional_type(element)
  length = element[:attributes][:length].to_i
  length.times do |i|
    attribute = element[:attributes][i]
    key = attribute[:name].to_s
    return key if %w[r-if r-elsif r-else].include?(key)
  end
  'r-if' # fallback
end

.has_conditional_attribute?(element) ⇒ Boolean

Check if element has conditional attributes (r-if, r-elsif, r-else)

Parameters:

  • element (JS.Object)

Returns:

  • (Boolean)


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

def has_conditional_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 %w[r-if r-elsif r-else].include?(key)
  end
  false
end