Class: Sandals::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/sandals/application.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title:, &definition) ⇒ Application

Returns a new instance of Application.

Raises:

  • (ArgumentError)


7
8
9
10
11
12
13
14
15
16
# File 'lib/sandals/application.rb', line 7

def initialize(title:, &definition)
  @title = title
  @definition = definition
  @refresh_interval = nil
  @styles = {}
  @view_definition = nil
  @snapshots = SnapshotHistory.new
  instance_eval(&definition)
  raise ArgumentError, "Sandals.app requires a view block" unless @view_definition
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *arguments, **options, &block) ⇒ Object (private)



109
110
111
112
113
114
115
# File 'lib/sandals/application.rb', line 109

def method_missing(name, *arguments, **options, &block)
  if @current_view&.respond_to?(name)
    @current_view.public_send(name, *arguments, **options, &block)
  else
    super
  end
end

Instance Attribute Details

#refresh_intervalObject (readonly)

Returns the value of attribute refresh_interval.



5
6
7
# File 'lib/sandals/application.rb', line 5

def refresh_interval
  @refresh_interval
end

#stylesObject (readonly)

Returns the value of attribute styles.



5
6
7
# File 'lib/sandals/application.rb', line 5

def styles
  @styles
end

Instance Method Details

#dispatch(revision:, events:, oldest_pending_revision: revision) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sandals/application.rb', line 70

def dispatch(revision:, events:, oldest_pending_revision: revision)
  if oldest_pending_revision > revision
    raise ArgumentError,
      "oldest pending revision cannot be newer than event revision"
  end

  snapshot = @snapshots.fetch(revision)

  EventDispatcher.new(snapshot.controls).dispatch(events)

  next_snapshot = publish_view
  @snapshots.discard_before(oldest_pending_revision)
  [next_snapshot.revision, HTMLRenderer.new.render_fragment(next_snapshot.view)]
end

#new_sessionObject



18
19
20
# File 'lib/sandals/application.rb', line 18

def new_session
  self.class.new(title: @title, &@definition)
end

#refresh(every:) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/sandals/application.rb', line 27

def refresh(every:)
  interval = Float(every, exception: false)
  unless interval&.finite? && interval >= 1
    raise ArgumentError, "refresh interval must be at least one second"
  end

  @refresh_interval = interval
end

#render(development_reload: false) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/sandals/application.rb', line 60

def render(development_reload: false)
  snapshot = publish_view
  HTMLRenderer.new.render(
    self,
    snapshot.view,
    revision: snapshot.revision,
    development_reload:
  )
end

#render_viewObject



52
53
54
55
56
57
58
# File 'lib/sandals/application.rb', line 52

def render_view
  @current_view = View.new(styles:)
  instance_eval(&view)
  @current_view
ensure
  @current_view = nil
end

#select(label, **options, &action) ⇒ Object



42
43
44
# File 'lib/sandals/application.rb', line 42

def select(label, **options, &action)
  @current_view.select(label, **options, &action)
end

#style(element, **properties) ⇒ Object



36
37
38
39
40
# File 'lib/sandals/application.rb', line 36

def style(element, **properties)
  element = Style.validate_element!(element)
  normalized = Style.normalize(element, properties)
  @styles[element] = (@styles.fetch(element, {})).merge(normalized).freeze
end

#title(*arguments, **options) ⇒ Object



46
47
48
49
50
# File 'lib/sandals/application.rb', line 46

def title(*arguments, **options)
  return @title if arguments.empty? && options.empty?

  @current_view.title(*arguments, **options)
end

#view(&block) ⇒ Object



22
23
24
25
# File 'lib/sandals/application.rb', line 22

def view(&block)
  @view_definition = block if block
  @view_definition
end