flok 0.0.34 → 0.0.35
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/kern/controller.js +5 -0
- data/docs/mod/intercept.md +26 -0
- data/lib/flok.rb +1 -0
- data/lib/flok/transition_compiler.rb +292 -0
- data/lib/flok/transition_compiler_templates/ttable.js.erb +0 -0
- data/lib/flok/version.rb +1 -1
- data/spec/etc/transition_compiler/trans0.rb +8 -0
- data/spec/etc/transition_complier_spec.rb +32 -0
- data/spec/kern/controller_spec.rb +21 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c530893c64f57d4267ae2edd101adfe456954c2
|
4
|
+
data.tar.gz: a603052bb1bb83292214fc0b1fbcf386655f5987
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f21e469c145f3995ae115615def139675882cda69096f40eff514f76921badd257b21de65ed5b17321f70e020e134c53b62167d5ee3beb875346e2a8b0c8c18a
|
7
|
+
data.tar.gz: b8ff637ba02cb67f73c00f755e4a945f064870cab108471f74463820420518cbdea171bb855e1ba624f4e2f6fcd8dca339587615a80fc3967b62c60e12a79a50
|
data/app/kern/controller.js
CHANGED
@@ -20,6 +20,11 @@ function _embed(vc_name, sp, context, event_gw) {
|
|
20
20
|
var cte = ctable[vc_name];
|
21
21
|
|
22
22
|
//Find the root view name
|
23
|
+
<% if @debug %>
|
24
|
+
if (cte === undefined) {
|
25
|
+
throw "Tried to embed a flok controller named: '" + vc_name + "' but you have not created that controller yet, add controller :" + vc_name + "do ...";
|
26
|
+
}
|
27
|
+
<% end %>
|
23
28
|
var vname = cte.root_view;
|
24
29
|
|
25
30
|
//Get spot names
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#Intercept
|
2
|
+
The intercept module supports the animation system by allowing you to hijack an action change for a particular view controller.
|
3
|
+
|
4
|
+
Typical Example:
|
5
|
+
```js
|
6
|
+
intercept("my_controller", "start_action", "to_action", function($sel) {
|
7
|
+
$sel.find("#content").css("left", "40%");
|
8
|
+
$sel.find("#tab-bar").css("left", "0%");
|
9
|
+
|
10
|
+
cd("../*/")
|
11
|
+
});
|
12
|
+
```
|
13
|
+
|
14
|
+
The actual code used to define an interceptor function is dependent on the platform.
|
15
|
+
|
16
|
+
An interceptor is defined like as follows:
|
17
|
+
```
|
18
|
+
transition "blah" do
|
19
|
+
#Define the context
|
20
|
+
controller "blah"
|
21
|
+
when "a" => "b"
|
22
|
+
|
23
|
+
path :home, "../../0"
|
24
|
+
path :about, "./1"
|
25
|
+
end
|
26
|
+
```
|
data/lib/flok.rb
CHANGED
@@ -0,0 +1,292 @@
|
|
1
|
+
#Compile a controller ruby file into a javascript string
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
module Flok
|
5
|
+
module TransitionCompiler
|
6
|
+
#Compile a ruby file containing flok controller definitions (from the transition)
|
7
|
+
def self.compile rb_src
|
8
|
+
#Execute code in this context, the context will hold all the information
|
9
|
+
#that is used to then generate code
|
10
|
+
context = TransitionCompilerContext.new
|
11
|
+
context.instance_eval(rb_src, __FILE__, __LINE__)
|
12
|
+
|
13
|
+
@src = ""
|
14
|
+
ctable_erb = File.read File.join(File.dirname(__FILE__), "./transition_compiler_templates/ttable.js.erb")
|
15
|
+
ctable_renderer = ERB.new(ctable_erb)
|
16
|
+
@src << ctable_renderer.result(context.get_binding)
|
17
|
+
|
18
|
+
#puts @src
|
19
|
+
|
20
|
+
return @src
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
#Compiler executes all rb code inside this context
|
26
|
+
module Flok
|
27
|
+
class TransitionCompilerContext
|
28
|
+
attr_accessor :controllers, :actions, :ons
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
@controllers = []
|
32
|
+
@actions = []
|
33
|
+
@ons = []
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_binding
|
37
|
+
return binding
|
38
|
+
end
|
39
|
+
|
40
|
+
def transition name, &block
|
41
|
+
end
|
42
|
+
|
43
|
+
def action controller, name, &block
|
44
|
+
@actions << TransitionCompilerAction.new(controller, name, self, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def on controller_name, action_name, name, &block
|
48
|
+
end
|
49
|
+
|
50
|
+
def actions_for_controller controller_name
|
51
|
+
return @actions.select{|e| e.controller.name == controller_name}
|
52
|
+
end
|
53
|
+
|
54
|
+
def spots_for_controller controller_name
|
55
|
+
return @controllers.detect{|e| e.name == controller_name}.spots
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#Event handler inside an action
|
60
|
+
class TransitionCompilerOn
|
61
|
+
attr_accessor :controller_name, :action_name, :name
|
62
|
+
end
|
63
|
+
|
64
|
+
class TransitionCompilerAction
|
65
|
+
attr_accessor :controller, :name, :on_entry_src, :ons
|
66
|
+
|
67
|
+
def initialize controller, name, ctx, &block
|
68
|
+
@controller = controller
|
69
|
+
@name = name
|
70
|
+
@ctx = ctx
|
71
|
+
@ons = [] #Event handlers
|
72
|
+
|
73
|
+
self.instance_eval(&block)
|
74
|
+
end
|
75
|
+
|
76
|
+
def on_entry js_src
|
77
|
+
#returns a string
|
78
|
+
@on_entry_src = macro(js_src)
|
79
|
+
end
|
80
|
+
|
81
|
+
def on name, js_src
|
82
|
+
@ons << {:name => name, :src => macro(js_src)}
|
83
|
+
end
|
84
|
+
|
85
|
+
def macro js_src
|
86
|
+
lines = js_src.split("\n").map do |line|
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
return lines.join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
def macro text
|
94
|
+
out = StringIO.new
|
95
|
+
|
96
|
+
text.split("\n").each do |l|
|
97
|
+
#EMBED(vc_name, spot_name, context) macro
|
98
|
+
if l =~ /Embed/
|
99
|
+
l.strip!
|
100
|
+
l.gsub!(/Embed\(/, "")
|
101
|
+
l.gsub! /\)$/, ""
|
102
|
+
l.gsub! /\);$/, ""
|
103
|
+
o = l.split(",").map{|e| e.strip}
|
104
|
+
|
105
|
+
vc_name = o.shift.gsub(/"/, "")
|
106
|
+
spot_name = o.shift.gsub(/"/, "")
|
107
|
+
context = o.shift
|
108
|
+
|
109
|
+
#Get the spot
|
110
|
+
spot_index = @controller.spots.index(spot_name)
|
111
|
+
raise "controller #{@controller.name.inspect} attempted to embed #{spot_name.inspect} inside #{@name.inspect}, but #{spot_name.inspect} was not defined in 'spots' (#{@controller.spots.inspect})" unless spot_index
|
112
|
+
|
113
|
+
#Calculate spot index as an offset from the base address using the index of the spot in the spots
|
114
|
+
#address offset
|
115
|
+
res = %{
|
116
|
+
|
117
|
+
var ptr = _embed("#{vc_name}", __base__+#{spot_index}+1, #{context}, __base__);
|
118
|
+
__info__.embeds[#{spot_index-1}].push(ptr);
|
119
|
+
}
|
120
|
+
out.puts res
|
121
|
+
#Send(event_name, info)
|
122
|
+
elsif l =~ /Send/
|
123
|
+
l.strip!
|
124
|
+
l.gsub!(/Send\(/, "")
|
125
|
+
l.gsub! /\)$/, ""
|
126
|
+
l.gsub! /\);$/, ""
|
127
|
+
o = l.split(",").map{|e| e.strip}
|
128
|
+
|
129
|
+
event_name = o.shift.gsub(/"/, "")
|
130
|
+
info = o.shift
|
131
|
+
|
132
|
+
out << %{
|
133
|
+
main_q.push([3, "if_event", __base__, "#{event_name}", #{info}])
|
134
|
+
}
|
135
|
+
#Raise(event_name, info)
|
136
|
+
elsif l =~ /Raise/
|
137
|
+
l.strip!
|
138
|
+
l.gsub!(/Raise\(/, "")
|
139
|
+
l.gsub! /\)$/, ""
|
140
|
+
l.gsub! /\);$/, ""
|
141
|
+
o = l.split(",").map{|e| e.strip}
|
142
|
+
|
143
|
+
event_name = o.shift
|
144
|
+
info = o.shift
|
145
|
+
|
146
|
+
out << %{
|
147
|
+
int_event(__info__.event_gw, #{event_name}, #{info});
|
148
|
+
}
|
149
|
+
#Lower(spot_name, event_name, info)
|
150
|
+
elsif l =~ /Lower/
|
151
|
+
l.strip!
|
152
|
+
l.gsub!(/Lower\(/, "")
|
153
|
+
l.gsub! /\)$/, ""
|
154
|
+
l.gsub! /\);$/, ""
|
155
|
+
o = l.split(",").map{|e| e.strip}
|
156
|
+
|
157
|
+
spot_name = o.shift.gsub(/"/, "")
|
158
|
+
event_name = o.shift
|
159
|
+
info = o.shift
|
160
|
+
|
161
|
+
#Get the spot
|
162
|
+
spot_index = @controller.spots.index(spot_name)
|
163
|
+
raise "controller #{@controller.name.inspect} attempted to lower message to #{spot_name.inspect} inside #{@name.inspect}, but #{spot_name.inspect} was not defined in 'spots' (#{@controller.spots.inspect})" unless spot_index
|
164
|
+
|
165
|
+
#Forward an event to the appropriate spot
|
166
|
+
out << %{
|
167
|
+
|
168
|
+
var vcs = __info__.embeds[#{spot_index-1}];
|
169
|
+
for (var i = 0; i < vcs.length; ++i) {
|
170
|
+
int_event(vcs[i], #{event_name}, #{info});
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
#GOTO(action_name)
|
175
|
+
elsif l =~ /Goto/
|
176
|
+
l.strip!
|
177
|
+
l.gsub!(/Goto\(/, "")
|
178
|
+
l.gsub! /\)$/, ""
|
179
|
+
l.gsub! /\);$/, ""
|
180
|
+
o = l.split(",").map{|e| e.strip}
|
181
|
+
|
182
|
+
action_name = o.shift.gsub(/"/, "")
|
183
|
+
|
184
|
+
#Switch the actions, reset embeds, and call on_entry
|
185
|
+
res = %{
|
186
|
+
var old_action = __info__.action;
|
187
|
+
__info__.action = "#{action_name}";
|
188
|
+
|
189
|
+
//Remove all views
|
190
|
+
var embeds = __info__.embeds;
|
191
|
+
for (var i = 0; i < __info__.embeds.length; ++i) {
|
192
|
+
for (var j = 0; j < __info__.embeds[i].length; ++j) {
|
193
|
+
//Free +1 because that will be the 'main' view
|
194
|
+
main_q.push([1, "if_free_view", embeds[i][j]+1]);
|
195
|
+
|
196
|
+
<% if @debug %>
|
197
|
+
var vp = embeds[i][j]+1;
|
198
|
+
//First locate spot this view belongs to in reverse hash
|
199
|
+
var spot = debug_ui_view_to_spot[vp];
|
200
|
+
|
201
|
+
//Find it's index in the spot
|
202
|
+
var idx = debug_ui_spot_to_views[spot].indexOf(vp);
|
203
|
+
|
204
|
+
//Remove it from the spot => [view]
|
205
|
+
debug_ui_spot_to_views[spot].splice(idx, 1);
|
206
|
+
|
207
|
+
//Remove it from the reverse hash
|
208
|
+
delete debug_ui_view_to_spot[vp];
|
209
|
+
<% end %>
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
//Prep embeds array, embeds[0] refers to the spot bp+2 (bp is vc, bp+1 is main)
|
214
|
+
__info__.embeds = [];
|
215
|
+
for (var i = 1; i < #{@controller.spots.count}; ++i) {
|
216
|
+
__info__.embeds.push([]);
|
217
|
+
}
|
218
|
+
|
219
|
+
//Call on_entry for the new action via the singleton on_entry
|
220
|
+
//located in ctable
|
221
|
+
__info__.cte.actions[__info__.action].on_entry(__base__)
|
222
|
+
|
223
|
+
//Send off event for action change
|
224
|
+
main_q.push([3, "if_event", __base__, "action", {
|
225
|
+
from: old_action,
|
226
|
+
to: "#{action_name}"
|
227
|
+
}]);
|
228
|
+
}
|
229
|
+
out.puts res
|
230
|
+
#Request(service_name, payload, event_name_cb)
|
231
|
+
elsif l =~ /Request/
|
232
|
+
l.strip!
|
233
|
+
l.gsub!(/Request\(/, "")
|
234
|
+
l.gsub! /\)$/, ""
|
235
|
+
l.gsub! /\);$/, ""
|
236
|
+
o = l.split(",").map{|e| e.strip}
|
237
|
+
|
238
|
+
name = o.shift.gsub(/"/, "")
|
239
|
+
info = o.shift.gsub(/"/, "")
|
240
|
+
event_name = o.shift
|
241
|
+
|
242
|
+
out << %{
|
243
|
+
service_#{name}_req(#{info}, __base__, #{event_name});
|
244
|
+
}
|
245
|
+
else
|
246
|
+
out.puts l
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
return out.string
|
251
|
+
end
|
252
|
+
|
253
|
+
#You can def things in controller and use them as macros inside actions
|
254
|
+
#But these defs. live in the TransitionCompilerController instance and we need
|
255
|
+
#to delegate these calls to the controller that are not available in the action
|
256
|
+
def method_missing method, *args, &block
|
257
|
+
if macro = @controller.macros[method]
|
258
|
+
#Call the macro in our context
|
259
|
+
self.instance_eval(¯o)
|
260
|
+
else
|
261
|
+
raise "No macro found named: #{method}"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class TransitionCompilerController
|
267
|
+
attr_accessor :name, :spots, :macros
|
268
|
+
def initialize name, ctx, &block
|
269
|
+
@name = name
|
270
|
+
@ctx = ctx
|
271
|
+
@spots = ['main']
|
272
|
+
@macros = {}
|
273
|
+
|
274
|
+
self.instance_eval(&block)
|
275
|
+
end
|
276
|
+
|
277
|
+
#Create an action macro
|
278
|
+
def macro name, &block
|
279
|
+
@macros[name] = block
|
280
|
+
end
|
281
|
+
|
282
|
+
#Names of spots
|
283
|
+
def spots *spots
|
284
|
+
@spots += spots
|
285
|
+
end
|
286
|
+
|
287
|
+
#Pass through action
|
288
|
+
def action name, &block
|
289
|
+
@ctx.action self, name, &block
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
File without changes
|
data/lib/flok/version.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
#Load all the test files in ./user_compiler/*.js
|
2
|
+
|
3
|
+
Dir.chdir File.join File.dirname(__FILE__), '../../'
|
4
|
+
require './lib/flok'
|
5
|
+
|
6
|
+
#Testing the compilation of controller/action user files into javascript counterparts
|
7
|
+
RSpec.describe "Transition compiler" do
|
8
|
+
#Return a v8 instance of a compiled js file
|
9
|
+
def compile fn
|
10
|
+
compiler = Flok::TransitionCompiler
|
11
|
+
js_src(fn)
|
12
|
+
js_res = compiler.compile(js_src(fn))
|
13
|
+
ctx = V8::Context.new
|
14
|
+
ctx.eval js_res
|
15
|
+
ctx
|
16
|
+
end
|
17
|
+
|
18
|
+
#Get the source for a file in ./user_compiler/*.rb
|
19
|
+
def js_src fn
|
20
|
+
Dir.chdir File.join(File.dirname(__FILE__), "transition_compiler") do
|
21
|
+
return File.read(fn+'.rb')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Can load the ruby module" do
|
26
|
+
compiler = Flok::TransitionCompiler
|
27
|
+
end
|
28
|
+
|
29
|
+
it "Can compile a controller" do
|
30
|
+
ctx = compile "trans0"
|
31
|
+
end
|
32
|
+
end
|
@@ -9,7 +9,7 @@ require './spec/lib/rspec_extensions.rb'
|
|
9
9
|
RSpec.describe "kern:controller_spec" do
|
10
10
|
include_context "kern"
|
11
11
|
|
12
|
-
#Can initialize a controller via embed and have the correct if_dispatch messages
|
12
|
+
#Can initialize a controller via embed and have the correct if_dispatch messages
|
13
13
|
it "Can initiate a controller via _embed" do
|
14
14
|
#Compile the controller
|
15
15
|
ctx = flok_new_user File.read('./spec/kern/assets/controller0.rb')
|
@@ -54,6 +54,26 @@ RSpec.describe "kern:controller_spec" do
|
|
54
54
|
@driver.mexpect("if_event", [base, "action", {"from" => nil, "to" => "my_action"}])
|
55
55
|
end
|
56
56
|
|
57
|
+
it "Does raise a sensible error if a controller does not exist" do
|
58
|
+
#Compile the controller
|
59
|
+
ctx = flok_new_user File.read('./spec/kern/assets/controller0.rb')
|
60
|
+
|
61
|
+
did_error = false
|
62
|
+
#Run the embed function
|
63
|
+
begin
|
64
|
+
secret = SecureRandom.hex
|
65
|
+
ctx.eval %{
|
66
|
+
//Call embed on main root view, should fail
|
67
|
+
base = _embed("my_non_existant_controller", 0, {secret: "#{secret}"}, null);
|
68
|
+
}
|
69
|
+
rescue V8::Error => e
|
70
|
+
expect(e.message).to include("my_non_existant_controller")
|
71
|
+
did_error = true
|
72
|
+
end
|
73
|
+
|
74
|
+
expect(did_error).to eq(true)
|
75
|
+
end
|
76
|
+
|
57
77
|
#Can initialize a controller via embed and the sub-controller has the correct info
|
58
78
|
it "Can initiate a controller via _embed" do
|
59
79
|
#Compile the controller
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flok
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.35
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- seo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: execjs
|
@@ -323,6 +323,7 @@ files:
|
|
323
323
|
- docs/mod/debug.md
|
324
324
|
- docs/mod/debug/dump_ui.md
|
325
325
|
- docs/mod/event.md
|
326
|
+
- docs/mod/intercept.md
|
326
327
|
- docs/mod/net.md
|
327
328
|
- docs/mod/persist.md
|
328
329
|
- docs/mod/sockio.md
|
@@ -348,6 +349,8 @@ files:
|
|
348
349
|
- lib/flok/project_template/app/controllers/controller.rb
|
349
350
|
- lib/flok/service_compiler_templates/services.js.erb
|
350
351
|
- lib/flok/services_compiler.rb
|
352
|
+
- lib/flok/transition_compiler.rb
|
353
|
+
- lib/flok/transition_compiler_templates/ttable.js.erb
|
351
354
|
- lib/flok/user_compiler.rb
|
352
355
|
- lib/flok/user_compiler_templates/ctable.js.erb
|
353
356
|
- lib/flok/utilities.rb
|
@@ -366,6 +369,8 @@ files:
|
|
366
369
|
- spec/etc/macro_spec.rb
|
367
370
|
- spec/etc/service_compiler/service0.rb
|
368
371
|
- spec/etc/services_compiler_spec.rb
|
372
|
+
- spec/etc/transition_compiler/trans0.rb
|
373
|
+
- spec/etc/transition_complier_spec.rb
|
369
374
|
- spec/etc/user_compiler/controller0.rb
|
370
375
|
- spec/etc/user_compiler_spec.rb
|
371
376
|
- spec/iface/driver/assets/debug_socket_server.js
|
@@ -1159,6 +1164,8 @@ test_files:
|
|
1159
1164
|
- spec/etc/macro_spec.rb
|
1160
1165
|
- spec/etc/service_compiler/service0.rb
|
1161
1166
|
- spec/etc/services_compiler_spec.rb
|
1167
|
+
- spec/etc/transition_compiler/trans0.rb
|
1168
|
+
- spec/etc/transition_complier_spec.rb
|
1162
1169
|
- spec/etc/user_compiler/controller0.rb
|
1163
1170
|
- spec/etc/user_compiler_spec.rb
|
1164
1171
|
- spec/iface/driver/assets/debug_socket_server.js
|