Class: Volt::Page

Inherits:
Object show all
Defined in:
lib/volt/page/page.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(volt_app) ⇒ Page

Returns a new instance of Page.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/volt/page/page.rb', line 7

def initialize(volt_app)
  @volt_app = volt_app
  # Run the code to setup the page
  @page          = PageRoot.new

  @url         = URL.new
  @params      = @url.params
  @url_tracker = UrlTracker.new(self)
  @templates   = {}

  @events = DocumentEvents.new

  if RUBY_PLATFORM == 'opal'
    if Volt.in_browser?
      # Setup escape binding for console
      `
        $(document).keyup(function(e) {
          if (e.keyCode == 27) {
            Opal.gvars.page.$launch_console();
          }
        });

        $(document).on('click', 'a', function(event) {
          return Opal.gvars.page.$link_clicked($(this).attr('href'), event);
        });
      `
    end
  end

  # Initialize tasks so we can get the reload message
  tasks if Volt.env.development?

  if Volt.in_browser?
    channel.on('reconnected') do
      @page._reconnected = true

      `setTimeout(function() {`
      @page._reconnected = false
      `}, 2000);`
    end
  end
end

Instance Attribute Details

#eventsObject (readonly)

Returns the value of attribute events.



5
6
7
# File 'lib/volt/page/page.rb', line 5

def events
  @events
end

#pageObject (readonly)

Returns the value of attribute page.



5
6
7
# File 'lib/volt/page/page.rb', line 5

def page
  @page
end

#paramsObject (readonly)

Returns the value of attribute params.



5
6
7
# File 'lib/volt/page/page.rb', line 5

def params
  @params
end

#routesObject (readonly)

Returns the value of attribute routes.



5
6
7
# File 'lib/volt/page/page.rb', line 5

def routes
  @routes
end

#template_loader=(value) ⇒ Object (writeonly)

On the server, we can delay loading the views until they are actually requeted. This sets up an instance variable to call to load.



129
130
131
# File 'lib/volt/page/page.rb', line 129

def template_loader=(value)
  @template_loader = value
end

#urlObject (readonly)

Returns the value of attribute url.



5
6
7
# File 'lib/volt/page/page.rb', line 5

def url
  @url
end

Instance Method Details

#add_routes(&block) ⇒ Object



141
142
143
144
145
# File 'lib/volt/page/page.rb', line 141

def add_routes(&block)
  @routes ||= Routes.new
  @routes.define(&block)
  @url.router = @routes
end

#add_template(name, template, bindings) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/volt/page/page.rb', line 115

def add_template(name, template, bindings)
  # First template gets priority.  The backend will load templates in order so
  # that local templates come in before gems (so they can be overridden).
  #
  # TODO: Currently this means we will send templates to the client that will
  # not get used because they are being overridden.  Need to detect that and
  # not send them.
  unless @templates[name]
    @templates[name] = { 'html' => template, 'bindings' => bindings }
  end
end

#binding_nameObject

We provide a binding_name, so we can bind events on the document



95
96
97
# File 'lib/volt/page/page.rb', line 95

def binding_name
  'page'
end

#channelObject



103
104
105
106
107
108
109
110
111
# File 'lib/volt/page/page.rb', line 103

def channel
  @channel ||= begin
    if Volt.client?
      Channel.new
    else
      ChannelStub.new
    end
  end
end

#cookiesObject



62
63
64
# File 'lib/volt/page/page.rb', line 62

def cookies
  @cookies ||= CookiesRoot.new({}, persistor: Persistors::Cookies)
end

#flashObject



50
51
52
# File 'lib/volt/page/page.rb', line 50

def flash
  @flash ||= FlashRoot.new({}, persistor: Persistors::Flash)
end

#launch_consoleObject



99
100
101
# File 'lib/volt/page/page.rb', line 99

def launch_console
  puts 'Launch Console'
end


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/volt/page/page.rb', line 70

def link_clicked(url = '', event = nil)
  # Skip when href == ''
  return false if url.blank?

  # Normalize url
  # Benchmark.bm(1) do
  if @url.parse(url)
    if event
      # Handled new url
      `event.stopPropagation();`
    end

    # Clear the flash
    flash.clear

    # return false to stop the event propigation
    return false
  end
  # end

  # Not stopping, process link normally
  true
end

#load_stored_pageObject

When the page is reloaded from the backend, we store the $page.page, so we can reload the page in the exact same state. Speeds up development.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/volt/page/page.rb', line 173

def load_stored_page
  if Volt.client?
    if `sessionStorage`
      page_obj_str = nil

      `page_obj_str = sessionStorage.getItem('___page');`
      `if (page_obj_str) {`
      `sessionStorage.removeItem('___page');`

      EJSON.parse(page_obj_str).each_pair do |key, value|
        page.send(:"_#{key}=", value)
      end
      `}`
    end
  end
rescue => e
  Volt.logger.error("Unable to restore: #{e.inspect}")
end

#local_storeObject



58
59
60
# File 'lib/volt/page/page.rb', line 58

def local_store
  @local_store ||= LocalStoreRoot.new({}, persistor: Persistors::LocalStore)
end

#startObject



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/volt/page/page.rb', line 147

def start
  # Setup to render template
  `$('body').html('<!-- $CONTENT --><!-- $/CONTENT -->');`

  load_stored_page

  # Do the initial url params parse
  @url_tracker.url_updated(true)

  main_controller = Main::MainController.new(@volt_app)

  # Setup main page template
  TemplateRenderer.new(@volt_app, DomTarget.new, main_controller, 'CONTENT', 'main/main/main/body')

  # Setup title reactive template
  @title_template = StringTemplateRenderer.new(@volt_app, main_controller, 'main/main/main/title')

  # Watch for changes to the title template
  proc do
    title = @title_template.html.gsub(/\n/, ' ')
    `document.title = title;`
  end.watch!
end

#storeObject



54
55
56
# File 'lib/volt/page/page.rb', line 54

def store
  @store ||= StoreRoot.new({}, persistor: Persistors::StoreFactory.new(tasks))
end

#tasksObject



66
67
68
# File 'lib/volt/page/page.rb', line 66

def tasks
  @tasks ||= Tasks.new(self)
end

#templatesObject



131
132
133
134
135
136
137
138
139
# File 'lib/volt/page/page.rb', line 131

def templates
  if @template_loader
    # Load the templates
    @template_loader.call
    @template_loader = nil
  end

  @templates
end