flok 0.0.34 → 0.0.35

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