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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d431abb68ddba76219f6dd4d845642c4263db2e
4
- data.tar.gz: d990ed3ab70fc60574a881af9d0cbef55d5885e7
3
+ metadata.gz: 8c530893c64f57d4267ae2edd101adfe456954c2
4
+ data.tar.gz: a603052bb1bb83292214fc0b1fbcf386655f5987
5
5
  SHA512:
6
- metadata.gz: fbc1e0e78c014293d361a40fed94158c2ad928b3679eebf4a994c43fe2ac9538a2593e6199218d080d666c5983cc194a76564b228e95f4dc5f5845a0a3fbcb76
7
- data.tar.gz: d35279b656c9f60a2af1e5cefc6a8c8a82aea228be36c1279f55b34379896b8291c88d1b8cdca532880a40adbd15381cfc222b097b253a68bc66ad4955861387
6
+ metadata.gz: f21e469c145f3995ae115615def139675882cda69096f40eff514f76921badd257b21de65ed5b17321f70e020e134c53b62167d5ee3beb875346e2a8b0c8c18a
7
+ data.tar.gz: b8ff637ba02cb67f73c00f755e4a945f064870cab108471f74463820420518cbdea171bb855e1ba624f4e2f6fcd8dca339587615a80fc3967b62c60e12a79a50
@@ -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
@@ -7,6 +7,7 @@ require "flok/project"
7
7
  require "flok/interactive"
8
8
  require "flok/user_compiler"
9
9
  require "flok/services_compiler"
10
+ require "flok/transition_compiler"
10
11
 
11
12
  module Flok
12
13
  end
@@ -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(&macro)
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
data/lib/flok/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Flok
2
- VERSION = "0.0.34"
2
+ VERSION = "0.0.35"
3
3
  end
@@ -0,0 +1,8 @@
1
+ transition :my_controller_tab_bar do
2
+ controller :my_controller
3
+ from :blah
4
+ to :blah2
5
+
6
+ path :tab_bar, './content.1'
7
+ path :home, './content.0'
8
+ end
@@ -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.34
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-05-25 00:00:00.000000000 Z
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