inesita 0.5.1 → 0.6.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+

|
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
|