inesita 0.5.1 → 0.6.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +2 -0
- data/inesita.gemspec +1 -1
- data/lib/inesita/cli/template/Gemfile.tt +1 -0
- data/lib/inesita/cli/template/app/application.js.rb.tt +17 -7
- data/opal/inesita.rb +4 -7
- data/opal/inesita/browser.rb +0 -26
- data/opal/inesita/component.rb +8 -42
- data/opal/inesita/component/cache.rb +12 -0
- data/opal/inesita/component/class_methods.rb +19 -0
- data/opal/inesita/component/render.rb +26 -0
- data/opal/inesita/component/virtual_dom.rb +26 -0
- data/opal/inesita/injection.rb +35 -1
- data/spec/opal/application_spec.rb +2 -27
- data/spec/opal/injecion_spec.rb +2 -1
- data/spec/opal/spec_helper.rb +0 -1
- metadata +8 -15
- data/lib/inesita/cli/template/app/layout.rb.tt +0 -10
- data/opal/inesita/application.rb +0 -52
- data/opal/inesita/component_helpers.rb +0 -20
- data/opal/inesita/component_virtual_dom_extension.rb +0 -19
- data/opal/inesita/injection_methods.rb +0 -7
- data/opal/inesita/layout.rb +0 -9
- data/opal/inesita/router.rb +0 -106
- data/opal/inesita/routes.rb +0 -79
- data/opal/inesita/store.rb +0 -15
- data/spec/opal/router_spec.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7412161a77addc91ce85fcccbacd0a39b19178e
|
4
|
+
data.tar.gz: 7232fb211110ecfd8484a305b7f484da8c1e9e35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c067ebc1c05e247cdb1d6606881e5c9d7a928c172887e1bd6921d51e49396439228e32ed9dd8317bb23652bd0aee4873558f79b11be13d63f1003990d100837
|
7
|
+
data.tar.gz: b28611e8b6feaa466b8fa74e7b7b466595033f9e381bf595252581454ceda36c135799a7d61dd87141fd56a706b6c31df44c158007790e4ec92a3532b1b07f1c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## [Unreleased]
|
2
|
+
|
3
|
+
### Removed
|
4
|
+
- `router` - moved to separate gem
|
5
|
+
|
6
|
+
|
1
7
|
## [0.5.1] - 2016.10.29
|
2
8
|
|
3
9
|
### Fixes
|
@@ -16,6 +22,7 @@
|
|
16
22
|
### Removed
|
17
23
|
- `init` callback, use `initialize` instead
|
18
24
|
|
25
|
+
|
19
26
|
## [0.4.4] - 2016.10.04
|
20
27
|
|
21
28
|
### Added
|
@@ -39,6 +46,7 @@
|
|
39
46
|
### Fixed
|
40
47
|
- prefix bug in opal 0.10
|
41
48
|
|
49
|
+
|
42
50
|
## [0.4.0] - 2016.05.02
|
43
51
|
|
44
52
|
### Added
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Inesita is a web frontend framework for fast building browser application using Ruby. It uses Virtual DOM for page render.
|
4
4
|
|
5
|
+
![Inesita](https://raw.githubusercontent.com/inesita-rb/inesita/master/lib/inesita/cli/template/static/inesita-rb.png)
|
6
|
+
|
5
7
|
## Description
|
6
8
|
|
7
9
|
More detailed description [here](https://inesita-rb.github.io).
|
data/inesita.gemspec
CHANGED
@@ -4,17 +4,27 @@ require 'inesita'
|
|
4
4
|
# require main parts of application
|
5
5
|
require 'router'
|
6
6
|
require 'store'
|
7
|
-
require 'layout'
|
8
7
|
|
9
8
|
# require all components
|
10
9
|
require_tree './components'
|
11
10
|
|
12
11
|
# when document is ready render application to <body>
|
12
|
+
|
13
|
+
class Application
|
14
|
+
include Inesita::Component
|
15
|
+
|
16
|
+
inject Router
|
17
|
+
inject Store
|
18
|
+
|
19
|
+
def render
|
20
|
+
div class: 'container' do
|
21
|
+
component NavBar
|
22
|
+
component router
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
13
28
|
Inesita::Browser.ready? do
|
14
|
-
|
15
|
-
Inesita::Application.new(
|
16
|
-
router: Router,
|
17
|
-
store: Store,
|
18
|
-
layout: Layout
|
19
|
-
).mount_to(Inesita::Browser.body)
|
29
|
+
Application.mount_to(Inesita::Browser.body)
|
20
30
|
end
|
data/opal/inesita.rb
CHANGED
@@ -6,12 +6,9 @@ require 'virtual_dom'
|
|
6
6
|
|
7
7
|
require 'inesita/browser'
|
8
8
|
require 'inesita/error'
|
9
|
-
require 'inesita/component_virtual_dom_extension'
|
10
|
-
require 'inesita/component_helpers'
|
11
9
|
require 'inesita/injection'
|
10
|
+
require 'inesita/component/class_methods'
|
11
|
+
require 'inesita/component/virtual_dom'
|
12
|
+
require 'inesita/component/render'
|
13
|
+
require 'inesita/component/cache'
|
12
14
|
require 'inesita/component'
|
13
|
-
require 'inesita/routes'
|
14
|
-
require 'inesita/router'
|
15
|
-
require 'inesita/store'
|
16
|
-
require 'inesita/application'
|
17
|
-
require 'inesita/layout'
|
data/opal/inesita/browser.rb
CHANGED
@@ -4,8 +4,6 @@ module Inesita
|
|
4
4
|
|
5
5
|
Window = JS.global
|
6
6
|
Document = Window.JS[:document]
|
7
|
-
Location = Document.JS[:location]
|
8
|
-
History = Window.JS[:history]
|
9
7
|
AddEventListener = Window.JS[:addEventListener]
|
10
8
|
|
11
9
|
if Native(Window.JS[:requestAnimationFrame])
|
@@ -18,30 +16,6 @@ module Inesita
|
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
21
|
-
def path
|
22
|
-
Location.JS[:pathname]
|
23
|
-
end
|
24
|
-
|
25
|
-
def query
|
26
|
-
Location.JS[:search]
|
27
|
-
end
|
28
|
-
|
29
|
-
def decode_uri_component(value)
|
30
|
-
JS.decodeURIComponent(value)
|
31
|
-
end
|
32
|
-
|
33
|
-
def push_state(path)
|
34
|
-
History.JS.pushState({}, nil, path)
|
35
|
-
end
|
36
|
-
|
37
|
-
def onpopstate(&block)
|
38
|
-
Window.JS[:onpopstate] = block
|
39
|
-
end
|
40
|
-
|
41
|
-
def hashchange(&block)
|
42
|
-
AddEventListener.call(:hashchange, block)
|
43
|
-
end
|
44
|
-
|
45
19
|
def ready?(&block)
|
46
20
|
AddEventListener.call('load', block)
|
47
21
|
end
|
data/opal/inesita/component.rb
CHANGED
@@ -1,60 +1,26 @@
|
|
1
1
|
module Inesita
|
2
2
|
module Component
|
3
3
|
include VirtualDOM::DOM
|
4
|
-
include
|
5
|
-
include
|
4
|
+
include VirtualDom
|
5
|
+
include Render
|
6
|
+
include Cache
|
6
7
|
include Injection
|
7
8
|
|
8
|
-
def
|
9
|
-
|
9
|
+
def self.included(base)
|
10
|
+
base.extend Inesita::Component::ClassMethods
|
10
11
|
end
|
11
12
|
|
12
13
|
def mount_to(element)
|
13
14
|
raise Error, "Can't mount #{self.class}, target element not found!" unless element
|
14
|
-
|
15
|
+
@root_component = self
|
16
|
+
init_injections
|
17
|
+
inject
|
15
18
|
@virtual_dom = render_virtual_dom
|
16
19
|
@root_node = VirtualDOM.create(@virtual_dom)
|
17
20
|
Browser.append_child(element, @root_node)
|
18
21
|
self
|
19
22
|
end
|
20
23
|
|
21
|
-
def render_if_root
|
22
|
-
return unless @virtual_dom && @root_node
|
23
|
-
new_virtual_dom = render_virtual_dom
|
24
|
-
diff = VirtualDOM.diff(@virtual_dom, new_virtual_dom)
|
25
|
-
VirtualDOM.patch(@root_node, diff)
|
26
|
-
@virtual_dom = new_virtual_dom
|
27
|
-
end
|
28
|
-
|
29
|
-
def before_render; end;
|
30
|
-
|
31
|
-
def render_virtual_dom
|
32
|
-
before_render
|
33
|
-
@cache_component_counter = 0
|
34
|
-
@__virtual_nodes__ = []
|
35
|
-
render
|
36
|
-
if @__virtual_nodes__.one?
|
37
|
-
@__virtual_nodes__.first
|
38
|
-
else
|
39
|
-
VirtualDOM::VirtualNode.new('div', {}, @__virtual_nodes__).to_n
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def cache_component(component, &block)
|
44
|
-
@cache_component ||= {}
|
45
|
-
@cache_component_counter ||= 0
|
46
|
-
@cache_component_counter += 1
|
47
|
-
@cache_component["#{component}-#{@cache_component_counter}"] || @cache_component["#{component}-#{@cache_component_counter}"] = block.call
|
48
|
-
end
|
49
|
-
|
50
|
-
def hook(mthd)
|
51
|
-
VirtualDOM::Hook.method(method(mthd))
|
52
|
-
end
|
53
|
-
|
54
|
-
def unhook(mthd)
|
55
|
-
VirtualDOM::UnHook.method(method(mthd))
|
56
|
-
end
|
57
|
-
|
58
24
|
attr_reader :props
|
59
25
|
def with_props(props)
|
60
26
|
@props = props
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Inesita
|
2
|
+
module Component
|
3
|
+
module Cache
|
4
|
+
def cache_component(component, &block)
|
5
|
+
@cache_component ||= {}
|
6
|
+
@cache_component_counter ||= 0
|
7
|
+
@cache_component_counter += 1
|
8
|
+
@cache_component["#{component}-#{@cache_component_counter}"] || @cache_component["#{component}-#{@cache_component_counter}"] = block.call
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Inesita
|
2
|
+
module Component
|
3
|
+
module ClassMethods
|
4
|
+
def mount_to(element)
|
5
|
+
new.mount_to(element)
|
6
|
+
end
|
7
|
+
|
8
|
+
def inject(clazz, opts = {})
|
9
|
+
method_name = opts[:as] || clazz.to_s.downcase
|
10
|
+
@injections ||= {}
|
11
|
+
@injections[method_name] = clazz
|
12
|
+
end
|
13
|
+
|
14
|
+
def injections
|
15
|
+
@injections || {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Inesita
|
2
|
+
module Component
|
3
|
+
module Render
|
4
|
+
def render
|
5
|
+
raise Error, "Implement #render in #{self.class} component"
|
6
|
+
end
|
7
|
+
|
8
|
+
def render_if_root
|
9
|
+
return unless @virtual_dom && @root_node
|
10
|
+
new_virtual_dom = render_virtual_dom
|
11
|
+
diff = VirtualDOM.diff(@virtual_dom, new_virtual_dom)
|
12
|
+
VirtualDOM.patch(@root_node, diff)
|
13
|
+
@virtual_dom = new_virtual_dom
|
14
|
+
end
|
15
|
+
|
16
|
+
def before_render; end;
|
17
|
+
|
18
|
+
def render_virtual_dom
|
19
|
+
before_render
|
20
|
+
@cache_component_counter = 0
|
21
|
+
@__virtual_nodes__ = []
|
22
|
+
render.to_vnode
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Inesita
|
2
|
+
module Component
|
3
|
+
module VirtualDom
|
4
|
+
def component(comp, opts = {})
|
5
|
+
raise Error, "Component is nil in #{self.class} class" if comp.nil?
|
6
|
+
@__virtual_nodes__ ||= []
|
7
|
+
@__virtual_nodes__ << cache_component(comp) do
|
8
|
+
comp = (comp.is_a?(Class) ? comp.new : comp)
|
9
|
+
.with_root_component(@root_component)
|
10
|
+
.inject
|
11
|
+
comp.init
|
12
|
+
comp
|
13
|
+
end.with_props(opts[:props] || {}).render_virtual_dom
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def hook(mthd)
|
18
|
+
VirtualDOM::Hook.method(method(mthd))
|
19
|
+
end
|
20
|
+
|
21
|
+
def unhook(mthd)
|
22
|
+
VirtualDOM::UnHook.method(method(mthd))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/opal/inesita/injection.rb
CHANGED
@@ -1,8 +1,42 @@
|
|
1
1
|
module Inesita
|
2
2
|
module Injection
|
3
|
+
def init; end
|
4
|
+
|
5
|
+
def with_root_component(component)
|
6
|
+
@root_component = component
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def inject
|
11
|
+
@root_component.injections.each do |name, instance|
|
12
|
+
define_singleton_method(name) do
|
13
|
+
instance
|
14
|
+
end
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :injections
|
20
|
+
def init_injections
|
21
|
+
@injections ||= {}
|
22
|
+
self.class.injections.each do |name, clazz|
|
23
|
+
if clazz.included_modules.include?(Inesita::Injection)
|
24
|
+
@injections[name] = clazz
|
25
|
+
.new
|
26
|
+
.with_root_component(@root_component)
|
27
|
+
.inject
|
28
|
+
else
|
29
|
+
raise Error, "Invalid #{clazz} class, should mixin Inesita::Injection"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
@injections.each do |key, instance|
|
33
|
+
instance.init
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
3
37
|
def render!
|
4
38
|
Browser.animation_frame do
|
5
|
-
root_component.render_if_root
|
39
|
+
@root_component.render_if_root
|
6
40
|
end
|
7
41
|
end
|
8
42
|
end
|
@@ -4,30 +4,9 @@ describe Inesita::Application do
|
|
4
4
|
let(:application) { Inesita::Application }
|
5
5
|
let(:layout) { Class.new { include Inesita::Layout } }
|
6
6
|
let(:injection) { Class.new { include Inesita::Injection } }
|
7
|
-
let(:router) do
|
8
|
-
Class.new do
|
9
|
-
include Inesita::Router
|
10
|
-
|
11
|
-
class TestComponent
|
12
|
-
include Inesita::Component
|
13
|
-
end
|
14
|
-
|
15
|
-
def routes
|
16
|
-
route '/', to: TestComponent
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
7
|
|
21
8
|
it 'should respond to #render' do
|
22
|
-
expect(application.new(
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should fail with wrong :router class' do
|
26
|
-
expect { application.new(router: Class) }.to raise_error Inesita::Error
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should not fail with :router class' do
|
30
|
-
expect { application.new(router: router) }.not_to raise_error
|
9
|
+
expect(application.new(layout: layout)).to respond_to(:render)
|
31
10
|
end
|
32
11
|
|
33
12
|
it 'should fail with wrong :layout class' do
|
@@ -38,11 +17,7 @@ describe Inesita::Application do
|
|
38
17
|
expect { application.new(layout: layout) }.not_to raise_error
|
39
18
|
end
|
40
19
|
|
41
|
-
it 'should not fail with :layout class' do
|
42
|
-
expect { application.new(router: router) }.not_to raise_error
|
43
|
-
end
|
44
|
-
|
45
20
|
it 'should not fail with any class for injection' do
|
46
|
-
expect { application.new(test: injection) }.not_to raise_error
|
21
|
+
expect { application.new(layout: layout, test: injection) }.not_to raise_error
|
47
22
|
end
|
48
23
|
end
|
data/spec/opal/injecion_spec.rb
CHANGED
@@ -3,6 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Inesita::Injection do
|
4
4
|
let(:application) { Inesita::Application }
|
5
5
|
let(:injection) { Class.new { include Inesita::Injection } }
|
6
|
+
let(:layout) { Class.new { include Inesita::Layout } }
|
6
7
|
|
7
8
|
it 'should respond to #render!' do
|
8
9
|
expect(injection.new).to respond_to(:render!)
|
@@ -13,6 +14,6 @@ describe Inesita::Injection do
|
|
13
14
|
end
|
14
15
|
|
15
16
|
it 'should respond to injection name method' do
|
16
|
-
expect(application.new(test: injection)).to respond_to(:test)
|
17
|
+
expect(application.new(layout: layout, test: injection)).to respond_to(:test)
|
17
18
|
end
|
18
19
|
end
|
data/spec/opal/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inesita
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michał Kalbarczyk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opal
|
@@ -199,7 +199,6 @@ files:
|
|
199
199
|
- lib/inesita/cli/template/app/components/home.rb.tt
|
200
200
|
- lib/inesita/cli/template/app/components/navbar.rb.tt
|
201
201
|
- lib/inesita/cli/template/app/index.html.slim.tt
|
202
|
-
- lib/inesita/cli/template/app/layout.rb.tt
|
203
202
|
- lib/inesita/cli/template/app/router.rb.tt
|
204
203
|
- lib/inesita/cli/template/app/store.rb.tt
|
205
204
|
- lib/inesita/cli/template/app/stylesheet.css.sass.tt
|
@@ -210,25 +209,20 @@ files:
|
|
210
209
|
- lib/inesita/minify.rb
|
211
210
|
- lib/inesita/server.rb
|
212
211
|
- opal/inesita.rb
|
213
|
-
- opal/inesita/application.rb
|
214
212
|
- opal/inesita/browser.rb
|
215
213
|
- opal/inesita/component.rb
|
216
|
-
- opal/inesita/
|
217
|
-
- opal/inesita/
|
214
|
+
- opal/inesita/component/cache.rb
|
215
|
+
- opal/inesita/component/class_methods.rb
|
216
|
+
- opal/inesita/component/render.rb
|
217
|
+
- opal/inesita/component/virtual_dom.rb
|
218
218
|
- opal/inesita/error.rb
|
219
219
|
- opal/inesita/injection.rb
|
220
|
-
- opal/inesita/injection_methods.rb
|
221
|
-
- opal/inesita/layout.rb
|
222
|
-
- opal/inesita/router.rb
|
223
|
-
- opal/inesita/routes.rb
|
224
|
-
- opal/inesita/store.rb
|
225
220
|
- spec/lib/nil_spec.rb
|
226
221
|
- spec/lib/spec_helper.rb
|
227
222
|
- spec/opal/application_spec.rb
|
228
223
|
- spec/opal/component_spec.rb
|
229
224
|
- spec/opal/injecion_spec.rb
|
230
225
|
- spec/opal/layout_spec.rb
|
231
|
-
- spec/opal/router_spec.rb
|
232
226
|
- spec/opal/spec_helper.rb
|
233
227
|
homepage: http://github.com/inesita-rb/inesita
|
234
228
|
licenses:
|
@@ -245,9 +239,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
245
239
|
version: '0'
|
246
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
241
|
requirements:
|
248
|
-
- - "
|
242
|
+
- - ">"
|
249
243
|
- !ruby/object:Gem::Version
|
250
|
-
version:
|
244
|
+
version: 1.3.1
|
251
245
|
requirements: []
|
252
246
|
rubyforge_project:
|
253
247
|
rubygems_version: 2.5.1
|
@@ -261,5 +255,4 @@ test_files:
|
|
261
255
|
- spec/opal/component_spec.rb
|
262
256
|
- spec/opal/injecion_spec.rb
|
263
257
|
- spec/opal/layout_spec.rb
|
264
|
-
- spec/opal/router_spec.rb
|
265
258
|
- spec/opal/spec_helper.rb
|
data/opal/inesita/application.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
module Inesita
|
2
|
-
class Application
|
3
|
-
include Inesita::Component
|
4
|
-
|
5
|
-
def initialize(options = {})
|
6
|
-
setup_router(options.delete(:router))
|
7
|
-
setup_layout(options.delete(:layout))
|
8
|
-
setup_root
|
9
|
-
setup_injections(options)
|
10
|
-
end
|
11
|
-
|
12
|
-
def render
|
13
|
-
component @root
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def setup_router(router)
|
19
|
-
if router
|
20
|
-
raise Error, "Invalid #{router} class, should mixin Inesita::Router" unless router.include?(Inesita::Router)
|
21
|
-
@router = inject(:router, router.new)
|
22
|
-
else
|
23
|
-
@router = Class.new { define_method(:method_missing) { raise 'Router missing' } }.new
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def setup_layout(layout)
|
28
|
-
if layout
|
29
|
-
raise Error, "Invalid #{layout} class, should mixin Inesita::Layout" unless layout.include?(Inesita::Layout)
|
30
|
-
@layout = inject(:layout, layout.new)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def setup_root
|
35
|
-
if @layout
|
36
|
-
@root = @layout
|
37
|
-
elsif @router
|
38
|
-
@root = @router
|
39
|
-
else
|
40
|
-
raise Error, 'Router or Layout not found!'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def setup_injections(injections)
|
45
|
-
return unless injections
|
46
|
-
return unless injections.is_a?(Hash)
|
47
|
-
injections.each do |key, value|
|
48
|
-
inject(key, value.new)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Inesita
|
2
|
-
module ComponentHelpers
|
3
|
-
def inject(name, what)
|
4
|
-
Injection.class_eval do
|
5
|
-
define_method(name) do
|
6
|
-
what
|
7
|
-
end
|
8
|
-
end
|
9
|
-
what
|
10
|
-
end
|
11
|
-
|
12
|
-
def class_names(hash)
|
13
|
-
class_names = []
|
14
|
-
hash.each do |key, value|
|
15
|
-
class_names << key if value
|
16
|
-
end
|
17
|
-
class_names.join(' ')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module Inesita
|
2
|
-
module ComponentVirtualDomExtension
|
3
|
-
def self.included(base)
|
4
|
-
base.alias_method :__a, :a
|
5
|
-
base.define_method(:a) do |params, &block|
|
6
|
-
params = { onclick: -> { router.go_to(params[:href]) } }.merge(params) if params[:href] && respond_to?(:router)
|
7
|
-
__a(params, &block)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def component(comp, opts = {})
|
12
|
-
raise Error, "Component is nil in #{self.class} class" if comp.nil?
|
13
|
-
@__virtual_nodes__ ||= []
|
14
|
-
@__virtual_nodes__ << cache_component(comp) do
|
15
|
-
comp.is_a?(Class) ? comp.new : comp
|
16
|
-
end.with_props(opts[:props] || {}).render_virtual_dom
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/opal/inesita/layout.rb
DELETED
data/opal/inesita/router.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
module Inesita
|
2
|
-
module Router
|
3
|
-
include Inesita::Component
|
4
|
-
|
5
|
-
attr_reader :params
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@routes = Routes.new
|
9
|
-
raise Error, 'Add #routes method to router!' unless respond_to?(:routes)
|
10
|
-
routes
|
11
|
-
raise Error, 'Add #route to your #routes method!' if @routes.routes.empty?
|
12
|
-
find_route
|
13
|
-
parse_url_params
|
14
|
-
add_listeners
|
15
|
-
end
|
16
|
-
|
17
|
-
def add_listeners
|
18
|
-
Browser.onpopstate { find_route; parse_url_params; render! }
|
19
|
-
Browser.hashchange { find_route; parse_url_params; render! }
|
20
|
-
end
|
21
|
-
|
22
|
-
def route(*params, &block)
|
23
|
-
@routes.route(*params, &block)
|
24
|
-
end
|
25
|
-
|
26
|
-
def find_route
|
27
|
-
@routes.routes.each do |route|
|
28
|
-
next unless path.match(route[:regex])
|
29
|
-
return go_to(url_for(route[:redirect_to])) if route[:redirect_to]
|
30
|
-
return @route = route
|
31
|
-
end
|
32
|
-
raise Error, "Can't find route for url"
|
33
|
-
end
|
34
|
-
|
35
|
-
def find_component(route)
|
36
|
-
call_on_enter_callback(route)
|
37
|
-
@component_props = route[:component_props]
|
38
|
-
route[:component]
|
39
|
-
end
|
40
|
-
|
41
|
-
def render
|
42
|
-
component find_component(@route), props: @component_props if @route
|
43
|
-
end
|
44
|
-
|
45
|
-
def call_on_enter_callback(route)
|
46
|
-
return unless route[:on_enter]
|
47
|
-
if route[:on_enter].respond_to?(:call)
|
48
|
-
route[:on_enter].call
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def go_to(path)
|
53
|
-
Browser.push_state(path)
|
54
|
-
find_route
|
55
|
-
parse_url_params
|
56
|
-
render!
|
57
|
-
false
|
58
|
-
end
|
59
|
-
|
60
|
-
def parse_url_params
|
61
|
-
@params = compotent_url_params
|
62
|
-
query[1..-1].split('&').each do |param|
|
63
|
-
key, value = param.split('=')
|
64
|
-
@params[Browser.decode_uri_component(key)] = Browser.decode_uri_component(value)
|
65
|
-
end unless query.empty?
|
66
|
-
end
|
67
|
-
|
68
|
-
def compotent_url_params
|
69
|
-
Hash[@route[:params].zip(path.match(@route[:regex])[1..-1])]
|
70
|
-
end
|
71
|
-
|
72
|
-
def url_for(name, params = nil)
|
73
|
-
route = @routes.routes.find do |r|
|
74
|
-
case name
|
75
|
-
when String
|
76
|
-
r[:name] == name || r[:path] == name
|
77
|
-
when Object
|
78
|
-
r[:component] == name
|
79
|
-
else
|
80
|
-
false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
route ? url_with_params(route, params) : raise(Error, "Route '#{name}' not found.")
|
84
|
-
end
|
85
|
-
|
86
|
-
def query
|
87
|
-
Browser.query
|
88
|
-
end
|
89
|
-
|
90
|
-
def path
|
91
|
-
Browser.path
|
92
|
-
end
|
93
|
-
|
94
|
-
def current_url?(name)
|
95
|
-
path == url_for(name, params)
|
96
|
-
end
|
97
|
-
|
98
|
-
def url_with_params(route, params)
|
99
|
-
path = route[:path]
|
100
|
-
params.each do |key, value|
|
101
|
-
path = path.gsub(":#{key}", "#{value}")
|
102
|
-
end if params
|
103
|
-
path
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
data/opal/inesita/routes.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
module Inesita
|
2
|
-
class Routes
|
3
|
-
attr_reader :routes
|
4
|
-
|
5
|
-
def initialize(parent = nil)
|
6
|
-
@parent = parent
|
7
|
-
@routes = []
|
8
|
-
end
|
9
|
-
|
10
|
-
def route(*params, &block)
|
11
|
-
path = params.first.gsub(/^\//, '')
|
12
|
-
path = @parent ? "#{@parent}/#{path}" : "/#{path}"
|
13
|
-
|
14
|
-
add_subroutes(path, &block) if block_given?
|
15
|
-
|
16
|
-
if params.last[:redirect_to]
|
17
|
-
add_redirect(path, params.last[:redirect_to])
|
18
|
-
else
|
19
|
-
add_route(params.last[:as], path, params.last[:to], params.last[:props], params.last[:on_enter])
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def validate_component(component)
|
24
|
-
raise Error, 'Component not exists' unless component
|
25
|
-
raise Error, "Invalid #{component} class, should mixin Inesita::Component" unless component.include?(Inesita::Component)
|
26
|
-
end
|
27
|
-
|
28
|
-
def add_redirect(path, redirect_to)
|
29
|
-
@routes << {
|
30
|
-
path: path,
|
31
|
-
redirect_to: redirect_to
|
32
|
-
}.merge(build_params_and_regex(path))
|
33
|
-
end
|
34
|
-
|
35
|
-
def add_route(name, path, component, component_props, on_enter)
|
36
|
-
validate_component(component)
|
37
|
-
@routes << {
|
38
|
-
path: path,
|
39
|
-
component: component,
|
40
|
-
component_props: component_props,
|
41
|
-
on_enter: on_enter,
|
42
|
-
name: name || component.to_s.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
43
|
-
}.merge(build_params_and_regex(path))
|
44
|
-
end
|
45
|
-
|
46
|
-
def add_subroutes(path, &block)
|
47
|
-
subroutes = Routes.new(path)
|
48
|
-
subroutes.instance_exec(&block)
|
49
|
-
@routes += subroutes.routes
|
50
|
-
end
|
51
|
-
|
52
|
-
def build_params_and_regex(path)
|
53
|
-
regex = ['^']
|
54
|
-
params = []
|
55
|
-
parts = path.split('/')
|
56
|
-
regex << '\/' if parts.empty?
|
57
|
-
parts.each do |part|
|
58
|
-
next if part.empty?
|
59
|
-
regex << '\/'
|
60
|
-
case part[0]
|
61
|
-
when ':'
|
62
|
-
params << part[1..-1]
|
63
|
-
regex << '([^\/]+)'
|
64
|
-
when '*'
|
65
|
-
params << part[1..-1]
|
66
|
-
regex << '(.*)'
|
67
|
-
break
|
68
|
-
else
|
69
|
-
regex << part
|
70
|
-
end
|
71
|
-
end
|
72
|
-
regex << '$'
|
73
|
-
{
|
74
|
-
regex: Regexp.new(regex.join),
|
75
|
-
params: params
|
76
|
-
}
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/opal/inesita/store.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module Inesita
|
2
|
-
# TODO: Remove it.
|
3
|
-
module Store
|
4
|
-
def self.included(base)
|
5
|
-
$console.warn('"include Inesita::Store" is deprecated. Use "include Inesita::Injection" insted.')
|
6
|
-
self.include Injection
|
7
|
-
end
|
8
|
-
|
9
|
-
def render!
|
10
|
-
Browser.animation_frame do
|
11
|
-
root_component.render_if_root
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/spec/opal/router_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Inesita::Router do
|
4
|
-
let(:wrong_router) { Class.new { include Inesita::Router } }
|
5
|
-
let(:empty_router) { Class.new { include Inesita::Router; def routes; end } }
|
6
|
-
let(:router) do
|
7
|
-
Class.new do
|
8
|
-
include Inesita::Router
|
9
|
-
|
10
|
-
class TestComponent
|
11
|
-
include Inesita::Component
|
12
|
-
end
|
13
|
-
|
14
|
-
class OtherTestComponent
|
15
|
-
include Inesita::Component
|
16
|
-
end
|
17
|
-
|
18
|
-
def routes
|
19
|
-
route '/', to: TestComponent
|
20
|
-
route '/other', to: OtherTestComponent
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should fail without routes' do
|
26
|
-
expect { wrong_router.new }.to raise_error Inesita::Error
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should fail with empty routes' do
|
30
|
-
expect { empty_router.new }.to raise_error Inesita::Error
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should not fail with routes' do
|
34
|
-
expect { router.new }.not_to raise_error
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#url_for' do
|
38
|
-
it 'should return url for component name' do
|
39
|
-
expect(router.new.url_for(:test_component)).to eq '/'
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should return url for component name' do
|
43
|
-
expect(router.new.url_for(:other_test_component)).to eq '/other'
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should fail when no route for component' do
|
47
|
-
expect { router.new.url_for(:nothing) }.to raise_error Inesita::Error
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe '#current_url?' do
|
52
|
-
it 'should return true for current url' do
|
53
|
-
expect(router.new.current_url?(:test_component)).to eq true
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'should return false for current url' do
|
57
|
-
expect(router.new.current_url?(:other_test_component)).to eq false
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|