Module: Ruwi::Dom::MountDom

Defined in:
lib/ruwi/runtime/dom/mount_dom.rb

Class Method Summary collapse

Class Method Details

.add_props(el, vdom, hostComponent) ⇒ Object

Parameters:

  • el (JS::Object)

    Element to add props to

  • vdom (Ruwi::Vdom)

    VDOM node

  • hostComponent (Ruwi::Component, nil)

    Host component



75
76
77
78
79
80
81
82
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 75

def self.add_props(el, vdom, hostComponent)
  extracted = Ruwi::Utils::Props.extract_props_and_events(vdom)
  events = extracted[:events]
  attrs = extracted[:props]

  vdom.listeners = Events.add_event_listeners(el, events, hostComponent) if events
  Ruwi::Dom::Attributes.set_attributes(el, attrs) if attrs.any?
end

.create_component_node(vdom, parent_el, index, host_component) ⇒ void

This method returns an undefined value.

Parameters:

  • vdom (Ruwi::Vdom)
  • parent_el (JS::Object)

    Parent element

  • index (Integer, nil)

    Index position to insert at

  • host_component (Ruwi::Component, nil)

    Host component



97
98
99
100
101
102
103
104
105
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 97

def self.create_component_node(vdom, parent_el, index, host_component)
  component_class = vdom.tag
  extracted = Ruwi::Utils::Props.extract_props_and_events(vdom)
  component = component_class.new(extracted[:props], extracted[:events], host_component)

  component.mount(parent_el, index)
  vdom.component = component
  vdom.el = component.first_element
end

.create_element_node(vdom, parent_el, index, hostComponent) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 60

def self.create_element_node(vdom, parent_el, index, hostComponent)
  element = JS.global[:document].createElement(vdom.tag)
  add_props(element, vdom, hostComponent)
  vdom.el = element

  vdom.children&.each do |child|
    execute(child, element, nil, hostComponent)
  end

  insert(element, parent_el, index)
end

.create_fragment_nodes(vdom, parent_el, index, hostComponent) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 84

def self.create_fragment_nodes(vdom, parent_el, index, hostComponent)
  vdom.el = parent_el

  vdom.children&.each_with_index do |child, i|
    execute(child, parent_el, index ? index + i : nil, hostComponent)
  end
end

.create_text_node(vdom, parent_el, index) ⇒ Object



54
55
56
57
58
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 54

def self.create_text_node(vdom, parent_el, index)
  text_node = JS.global[:document].createTextNode(vdom.value)
  vdom.el = text_node
  insert(text_node, parent_el, index)
end

.execute(vdom, parent_el, index = nil, hostComponent = nil) ⇒ Object

Parameters:

  • vdom (Ruwi::Vdom)
  • parent_el (JS::Object)
  • index (Integer, nil) (defaults to: nil)

    Index position to insert at

  • hostComponent (Ruwi::Component, nil) (defaults to: nil)

    Host component



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 8

def execute(vdom, parent_el, index = nil, hostComponent = nil)
  case vdom.type
  when Ruwi::Vdom::DOM_TYPES[:TEXT]
    create_text_node(vdom, parent_el, index)
  when Ruwi::Vdom::DOM_TYPES[:ELEMENT]
    create_element_node(vdom, parent_el, index, hostComponent)
  when Ruwi::Vdom::DOM_TYPES[:FRAGMENT]
    create_fragment_nodes(vdom, parent_el, index, hostComponent)
  when Ruwi::Vdom::DOM_TYPES[:COMPONENT]
    create_component_node(vdom, parent_el, index, hostComponent)
    Ruwi::Dom::Scheduler.enqueue_job(-> { vdom.component.on_mounted })
  else
    raise "Can't mount DOM of type: #{vdom.type}"
  end
end

.insert(el, parent_el, index) ⇒ Object

Parameters:

  • el (JS::Object)

    Element to insert

  • parent_el (JS::Object)

    Parent element

  • index (Integer, nil)

    Index position to insert at



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ruwi/runtime/dom/mount_dom.rb', line 27

def insert(el, parent_el, index)
  # If index is nil or undefined, simply append to the end
  if index.nil?
    parent_el.append(el)
    return
  end

  # If index is negative, raise an error
  if index < 0
    raise "Index must be a positive integer, got #{index}"
  end

  children = parent_el[:childNodes]

  # If index is greater than or equal to the number of children, append to the end
  if index >= children[:length].to_i # to_i is necessary because length is a JS::Number
    parent_el.append(el)
  else
    # Insert at the specified index position
    parent_el.insertBefore(el, children[index])
  end
end