Class: Live::Element

Inherits:
Object
  • Object
show all
Defined in:
lib/live/element.rb

Overview

Represents a single dynamic content area on the page.

Direct Known Subclasses

View

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id = self.class.unique_id, data = {}) ⇒ Element

Initialize the element with the specified id and data.



42
43
44
45
46
47
48
# File 'lib/live/element.rb', line 42

def initialize(id = self.class.unique_id, data = {})
  data[:class] ||= self.class.name
  
  @id = id
  @data = data
  @page = nil
end

Instance Attribute Details

#dataObject (readonly)

The data associated with the element.



54
55
56
# File 'lib/live/element.rb', line 54

def data
  @data
end

#idObject (readonly)

The unique id within the bound page.



51
52
53
# File 'lib/live/element.rb', line 51

def id
  @id
end

#pageObject (readonly)

Returns the value of attribute page.



57
58
59
# File 'lib/live/element.rb', line 57

def page
  @page
end

Class Method Details

.child(parent, id = self.unique_id, **data) ⇒ Object

Mount an element within a parent element.



28
29
30
31
32
# File 'lib/live/element.rb', line 28

def self.child(parent, id = self.unique_id, **data)
  full_id = parent.id + ":" + id
  
  self.new(full_id, data)
end

.mount(parent, id, data = {}) ⇒ Object



34
35
36
# File 'lib/live/element.rb', line 34

def self.mount(parent, id, data = {})
  self.child(parent, id, **data)
end

.root(id = self.unique_id, **data) ⇒ Object

Create a new root element with a convenient syntax for specifying the id and data.



23
24
25
# File 'lib/live/element.rb', line 23

def self.root(id = self.unique_id, **data)
  self.new(id, data)
end

.unique_idObject



15
16
17
# File 'lib/live/element.rb', line 15

def self.unique_id
  SecureRandom.uuid
end

Instance Method Details

#append(selector, fragment = nil, **options, &block) ⇒ Object

Append to the content of the client-side element by appending the specified element.



135
136
137
138
139
# File 'lib/live/element.rb', line 135

def append(selector, fragment = nil, **options, &block)
  fragment ||= XRB::Builder.fragment(&block)
  
  rpc(:append, selector, fragment.to_s, options)
end

#append_markup(output) ⇒ Object



157
158
159
# File 'lib/live/element.rb', line 157

def append_markup(output)
  build_markup(::XRB::Builder.new(output))
end

#bind(page) ⇒ Object

Bind this tag to a dynamically updating page.



79
80
81
# File 'lib/live/element.rb', line 79

def bind(page)
  @page = page
end

#build_markup(builder) ⇒ Object



161
162
163
# File 'lib/live/element.rb', line 161

def build_markup(builder)
  render(builder)
end

#closeObject



83
84
85
# File 'lib/live/element.rb', line 83

def close
  @page = nil
end

#dispatch_event(selector, type, **options) ⇒ Object



147
148
149
# File 'lib/live/element.rb', line 147

def dispatch_event(selector, type, **options)
  rpc(:dispatch_event, selector, event, options)
end

#forward_event(detail = nil) ⇒ Object

Generate a JavaScript string which forwards the specified event to the server.



61
62
63
64
65
66
67
# File 'lib/live/element.rb', line 61

def forward_event(detail = nil)
  if detail
    "live.forwardEvent(#{JSON.dump(@id)}, event, #{JSON.dump(detail)})"
  else
    "live.forwardEvent(#{JSON.dump(@id)}, event)"
  end
end

#forward_form_event(detail = nil) ⇒ Object



69
70
71
72
73
74
75
# File 'lib/live/element.rb', line 69

def forward_form_event(detail = nil)
  if detail
    "live.forwardFormEvent(#{JSON.dump(@id)}, event, #{JSON.dump(detail)})"
  else
    "live.forwardFormEvent(#{JSON.dump(@id)}, event)"
  end
end

#handle(event) ⇒ Object

Handle a client event, typically as triggered by #forward.



89
90
# File 'lib/live/element.rb', line 89

def handle(event)
end

#prepend(selector, fragment = nil, **options, &block) ⇒ Object

Prepend to the content of the client-side element by appending the specified element.



126
127
128
129
130
# File 'lib/live/element.rb', line 126

def prepend(selector, fragment = nil, **options, &block)
  fragment ||= XRB::Builder.fragment(&block)
  
  rpc(:prepend, selector, fragment.to_s, options)
end

#remove(selector, **options) ⇒ Object

Remove the specified element from the client-side element.



143
144
145
# File 'lib/live/element.rb', line 143

def remove(selector, **options)
  rpc(:remove, selector, options)
end

#render(builder) ⇒ Object

Render the element.



153
154
155
# File 'lib/live/element.rb', line 153

def render(builder)
  builder.text(self.class.name)
end

#replace(selector, fragment = nil, **options, &block) ⇒ Object

Replace the content of the client-side element by rendering this view.



117
118
119
120
121
# File 'lib/live/element.rb', line 117

def replace(selector, fragment = nil, **options, &block)
  fragment ||= XRB::Builder.fragment(&block)
  
  rpc(:replace, selector, fragment.to_s, options)
end

#rpc(*arguments) ⇒ Object

Enqueue a remote procedure call to the currently bound page.



95
96
97
98
99
100
101
102
103
# File 'lib/live/element.rb', line 95

def rpc(*arguments)
  if @page
    # This update might not be sent right away. Therefore, mutable arguments may be serialized to JSON at a later time (or never). This could be a race condition:
    @page.enqueue(arguments)
  else
    # This is a programming error, as it probably means the element is still part of the logic of the server side (e.g. async loop), but it is not bound to a page, so there is nothing to update/access/rpc.
    raise PageError, "Element is not bound to a page, make sure to implement #close!"
  end
end

#script(code, **options) ⇒ Object



105
106
107
# File 'lib/live/element.rb', line 105

def script(code, **options)
  rpc(:script, @id, code, options)
end

#The page this elemenet is bound to.=(pagethiselemenetisboundto. = (value)) ⇒ Object



57
# File 'lib/live/element.rb', line 57

attr :page

#to_htmlObject



166
167
168
# File 'lib/live/element.rb', line 166

def to_html
  XRB::Builder.fragment(&self.method(:build_markup))
end

#to_sObject

Convenience method for rendering the view as a string.



172
173
174
# File 'lib/live/element.rb', line 172

def to_s
  to_html.to_s
end

#update!(**options) ⇒ Object

Update the content of the client-side element by rendering this view.



110
111
112
# File 'lib/live/element.rb', line 110

def update!(**options)
  rpc(:update, @id, self.to_html, options)
end