jabs 0.1.1 → 0.2.0

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
@@ -1,10 +1,20 @@
1
1
  require 'lib/jabs'
2
2
  require 'pathname'
3
+ require 'sinatra'
4
+ require 'haml'
5
+ require 'sass'
3
6
 
4
- puts Pathname.new(__FILE__).dirname.expand_path+'src'
5
- puts "OF"
7
+ class Example < Sinatra::Base
8
+ set :views, Jabs.root+'../examples/views'
9
+
10
+ %w{input_with_default drag_and_drop}.each do |part|
11
+ get "/#{part}" do
12
+ haml part.intern
13
+ end
14
+ end
15
+ end
16
+
17
+ use Jabs::Rack::Static, :urls => '/jabs', :root => Pathname.new(__FILE__).dirname.expand_path
18
+ Jabs::Rack.mount(self, '/jquery')
19
+ map("/examples") { run Example.new }
6
20
 
7
- use Jabs::Rack::Static, :urls => '/src', :root => Pathname.new(__FILE__).dirname.expand_path
8
- run lambda { |env|
9
- [200, {'Content-Type'=>'text/html'}, "JABS"]
10
- }
@@ -0,0 +1,23 @@
1
+ :ready
2
+ $#sortable
3
+ .sortable 'li'
4
+
5
+ def sortable parent_selector
6
+ :dragstart
7
+ event.target
8
+ .closest parent_selector
9
+ .clone
10
+ .css
11
+ position: 'absolute'
12
+ .appendTo document.body
13
+
14
+ :drag
15
+ event.dragProxy
16
+ .css
17
+ top: event.pageY
18
+ left: event.pageX
19
+
20
+ :dragend
21
+ event.dragProxy
22
+ .remove
23
+
@@ -3,7 +3,7 @@
3
3
  :blur
4
4
  if @value === ''
5
5
  @value = @default_value
6
-
6
+
7
7
  :focus
8
8
  if @value === @default_value
9
9
  @value = ''
@@ -0,0 +1,16 @@
1
+ %script{:src=> "/jabs/drag_and_drop.js.jabs"}
2
+ %style
3
+ :sass
4
+ ol, li
5
+ list-style: number
6
+ li
7
+ height: 20px
8
+ width: 300px
9
+ margin-bottom: 4px
10
+ background: black
11
+ color: white
12
+ %ol#sortable
13
+ %li One: Lorem ipsum dolor sit amet
14
+ %li Two: Lorem ipsum dolor sit amet.
15
+ %li Three: Lorem ipsum dolor sit amet.
16
+ %li Four: Lorem ipsum dolor sit amet.
@@ -0,0 +1,3 @@
1
+ %script{:src=> "/jabs/input_with_default.js.jabs"}
2
+ %input{:type=>'text', :default_value => "hello!"}/
3
+ %input{:type=>'text', :default_value => "hello again!"}/
@@ -0,0 +1,8 @@
1
+ <DOCTYPE html>
2
+ %html
3
+ %head
4
+ %title Jabs Example
5
+ %meta{"http-equiv"=>"content-type", "content"=>"text/html; charset=utf-8"}
6
+ %script{:src=> "/jquery/jquery.js"}
7
+ %body= yield
8
+
@@ -2,56 +2,19 @@ require 'fold'
2
2
  require 'rack'
3
3
  require 'johnson'
4
4
  require 'pathname'
5
- puts require Pathname.new(__FILE__).dirname.expand_path+'jabs/middleware'
6
-
7
- module Johnson
8
- module Nodes
9
- attr_accessor :value
10
- class FallThrough < Node
11
- def initialize(_row, _column, value)
12
- @value = value
13
- end
14
- end
15
- end
16
-
17
- module Visitors
18
- class EcmaVisitor
19
- def visit_SourceElements(o)
20
- newline = o.value.length > 0 ? "\n" : ' '
21
- (@depth == 0 ? '' : "{#{newline}") +
22
- indent {
23
- o.value.map { |x|
24
- code = x.accept(self)
25
- semi = case x
26
- when Nodes::FallThrough
27
- ""
28
- when Nodes::Function, Nodes::While, Nodes::If, Nodes::Try, Nodes::Switch, Nodes::Case, Nodes::Default, Nodes::For, Nodes::ForIn
29
- code =~ /\}\Z/ ? '' : ';'
30
- else
31
- ';'
32
- end
33
- "#{indent}#{code}#{semi}"
34
- }.join("\n")
35
- } +
36
- (@depth == 0 ? '' : "#{newline}}")
37
- end
38
-
39
- def visit_FallThrough(o)
40
- o.value
41
- end
42
- end
43
-
44
- class SexpVisitor
45
- def visit_FallThrough(o)
46
- [:fall_through, o.value]
47
- end
48
- end
49
- end
50
- end
51
5
 
52
6
  module Jabs
53
- include Johnson::Nodes
7
+ def self.root
8
+ @root ||= Pathname.new(__FILE__).dirname.expand_path
9
+ end
10
+
11
+ require root+'jabs/precompiler'
12
+ require root+'jabs/engine'
13
+ require root+'jabs/middleware'
54
14
 
15
+ require root+'johnson/ext'
16
+ include Johnson::Nodes
17
+
55
18
  def self.logger
56
19
  @logger ||= begin
57
20
  #TODO configurable logging
@@ -62,247 +25,5 @@ module Jabs
62
25
  logger
63
26
  end
64
27
  end
65
-
66
- class Precompiler < Fold::Precompiler
67
- class << self
68
- attr_accessor :spot_replacements
69
- end
70
-
71
- self.spot_replacements = []
72
-
73
- def self.spot_replace key, &block
74
- spot_replacements << block if block_given?
75
- end
76
-
77
- attr_reader :sexp, :current_sexp
78
-
79
- def initialize
80
- super
81
-
82
- @ready = false
83
- @current_sexp = []
84
- @full_sexp = [:source_elements, @current_sexp]
85
- end
86
-
87
- folds :Line, // do
88
- [:fall_through, (Precompiler.do_spot_replace(text, self) + children.map{|child| child.text}.join(""))]
89
- end
90
-
91
- folds :Selector, /^\$/ do
92
- call(function(nil, ["$this"], [:source_elements, render_children]), jquery([:string, text]))
93
- end
94
-
95
- folds :SubSelector, /^&/ do
96
- call(
97
- function(nil, ["$this"], [:source_elements, render_children]),
98
- call(access([:name, "$this"], [:name, "find"]), [:string, text])
99
- )
100
- end
101
-
102
- folds :Event, /^:/ do
103
- event_bind(text, [:name, "$this"], [:source_elements, [parse("var $this = jQuery(this)")] + render_children])
104
- end
105
-
106
- folds :Ready, /^:ready/ do
107
- jquery(function(nil, [], [:source_elements, [call(function(nil, ["$this"], [:source_elements, render_children]), jquery([:name, "window"]))]]))
108
- end
109
-
110
- folds :Function, /^fun / do
111
- parts = text.split(/ /)
112
- name, arg_names = parts.shift, parts.join('').gsub(' ', '').split(',')
113
- [:function, name, arg_names, [:source_elements, render_children]]
114
- end
115
-
116
- folds :Def, /^def / do
117
- parts = text.split(/ /)
118
- name, arg_names = parts.shift, parts.join('').gsub(' ', '').split(',')
119
- [:assign_expr,
120
- access(access([:name, "jQuery"], [:name, "fn"]), [:name, name]),
121
- [:function, nil, arg_names, [:source_elements, [parse("var $this = this")] + render_children]]]
122
- end
123
-
124
- if_meta = %q{
125
- index = parent.children.index(self)
126
- _next = parent.children.slice index + 1
127
-
128
- _else = if [Else, ElseIf].include? _next.class
129
- _next.render
130
- else
131
- nil
132
- end
133
- [:if, parse(Precompiler.do_spot_replace(text)),[:source_elements, render_children], _else]
134
- }
135
-
136
- folds :If, /^if / do
137
- eval if_meta
138
- end
139
-
140
- folds :Unless, /^unless / do
141
- [:if, [:not, [:parenthesis, parse(Precompiler.do_spot_replace(text))]], [:source_elements, render_children], nil]
142
- end
143
-
144
- folds :Else, /^else/ do
145
- [:source_elements, render_children]
146
- end
147
-
148
- folds :ElseIf, /^else if/ do
149
- eval if_meta
150
- end
151
-
152
- folds :DotAccessor, /^\./ do
153
- index = parent.children.index(self)
154
- _next = parent.children.slice index + 1
155
- _text = _next ? _next.text : ""
156
- if children.any?
157
- if (_text[/\}\)/])
158
- [:fall_through, ("$this."+Precompiler.do_spot_replace(text, self) + children.map{|child| child.text}.join(""))]
159
- else
160
- call(
161
- function(nil, ["$this"], [:source_elements, render_children]),
162
- parse(Precompiler.do_spot_replace(".#{text}", self))
163
- )
164
- end
165
- else
166
- parse Precompiler.do_spot_replace(".#{text}", self)
167
- end
168
- end
169
-
170
- spot_replace :DotAccessor do |expression, precompiler|
171
- expression.gsub /(^\.([\w]+)|- \.(.+))(.*)/ do |match|
172
- "$this#{Precompiler.compile_arguments expression, $1, match, $4}"
173
- end
174
- end
175
-
176
- spot_replace :AccessUpAndCall do |expression, precompiler|
177
- expression.gsub /\.\.(\..*)/ do |match|
178
- "$this.prevObject#{Precompiler.do_spot_replace($1)}"
179
- end
180
- end
181
-
182
- spot_replace :AccessUpUp do |expression, precompiler|
183
- expression.
184
- gsub(/ \.\.\/|^\.\.\//, "$this.prevObject/").
185
- gsub(/\/\.\./, ".prevObject")
186
- end
187
-
188
- spot_replace :AccessUp do |expression, precompiler|
189
- expression.gsub /\.\./ do
190
- "$this.prevObject"
191
- end
192
- end
193
-
194
- spot_replace :AttributeSetter do |expression, precompiler|
195
- expression.gsub /@([\w]+)[ ]*=[ ]*(.*)/ do |match|
196
- if $2[0] == ?=
197
- match
198
- else
199
- "$this.attr('#{$1}', #{Precompiler.do_spot_replace $2, precompiler})"
200
- end
201
- end
202
- end
203
28
 
204
- spot_replace :AttributeAccessor do |expression, precompiler|
205
- expression.gsub /@([\w]+)/ do
206
- "$this.attr('#{$1}')"
207
- end
208
- end
209
-
210
- spot_replace :DanglingThis do |expression, precompiler|
211
- expression.gsub /prevObject\$this/ do
212
- "prevObject"
213
- end
214
- end
215
-
216
- def self.do_spot_replace expression, precompiler=nil
217
- spot_replacements.each do |block|
218
- expression = block.call(expression, precompiler)
219
- end
220
- expression
221
- end
222
-
223
- def self.compile_arguments expression, call, real, args
224
- return real if expression[Regexp.new("^\\#{call}\\(")]
225
- arguments = []
226
- if args[/^\./]
227
- "#{call}()#{do_spot_replace(args).gsub("$this", "")}"
228
- else
229
- args.split(/\s|,/).each do |arg|
230
- arg.gsub!(/:(\w+)/) {%{"#{$1}"}}
231
- next if arg[/\s/]
232
- next if arg == ""
233
- arguments << arg
234
- end
235
- "#{call}(#{arguments.join(', ')})"
236
- end
237
- end
238
-
239
- def parse expression
240
- self.class.do_spot_replace expression, self
241
- Johnson::Parser.parse(expression).value.first
242
- end
243
-
244
- def source block=nil
245
- source = [:source_elements]
246
- source << [block] unless(block.nil? or block.empty?)
247
- source
248
- end
249
-
250
- def event_bind event, binds_to, function_sexp=nil
251
- call(access(binds_to, [:name, "live"]), [:string, event], function(nil, ["e"], function_sexp))
252
- end
253
-
254
- def call *args
255
- [:function_call, args]
256
- end
257
-
258
- def onready function_sexp=nil
259
- event_bind('ready', jquery([:name, "document"]), function_sexp)
260
- end
261
-
262
- def access left, right
263
- [:dot_accessor, right, left]
264
- end
265
-
266
- def function name=nil, args=[], function_sexp=nil
267
- [:function, name, args, function_sexp]
268
- end
269
-
270
- def jquery *jquery_arg
271
- [:function_call, [
272
- [:name, 'jQuery'],
273
- *jquery_arg
274
- ]]
275
- end
276
-
277
- def johnsonize(sexp)
278
- return sexp if sexp.is_a?(Johnson::Nodes::Node)
279
- return sexp if sexp.class.to_s == "String"
280
- return [] if sexp === []
281
- return nil if sexp === nil
282
- unless sexp.first.class.to_s == "Array"
283
- if sexp.first.class.to_s == "Symbol"
284
- klass = eval("Johnson::Nodes::#{sexp.shift.to_s.camelcase}")
285
- klass.new 0,0, *sexp.map{|n|johnsonize(n)}
286
- elsif sexp.is_a? Array
287
- sexp.map{|n|johnsonize(n)}
288
- else
289
- sexp
290
- end
291
- else
292
- sexp.map{|n|johnsonize(n)}
293
- end
294
- end
295
- end
296
-
297
- class Engine < Fold::Engine
298
-
299
- def render context=nil
300
- @p = precompiler_class.new
301
- root = Johnson::Nodes::SourceElements.new 0, 0
302
- @p.fold(lines).children.each{|c|root << @p.johnsonize(c.render)}
303
- root.to_ecma
304
- end
305
- end
306
29
  end
307
-
308
- puts Jabs::Engine.new($stdin.read).render if $0 == __FILE__
@@ -0,0 +1,18 @@
1
+ module Jabs
2
+ class Engine < Fold::Engine
3
+ def render context=nil
4
+ @p = precompiler_class.new
5
+ root = Johnson::Nodes::SourceElements.new 0, 0
6
+ main = Johnson::Nodes::SourceElements.new 0, 0
7
+ root << @p.johnsonize(@p.call([:function, nil, [], main]))
8
+
9
+ @p.fold(lines).children.each{|c|main << @p.johnsonize(c.render)}
10
+ root.to_ecma
11
+ rescue Fold::FoldFactory::IndentationError => e
12
+ require 'pp'
13
+ pp lines
14
+ puts "______------UP"
15
+ raise e
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,21 @@
1
1
  module Jabs
2
-
3
2
  module Rack
3
+
4
+ def self.mount(rack_builder, mount_pount)
5
+ rack_builder.map(mount_pount) do
6
+ run (lambda do |env|
7
+ source = %w{
8
+ jquery/jquery-1.3.2.js
9
+ jquery/jquery.event.drag-1.5.js
10
+ jquery/jquery.event.drop-1.2.js
11
+ jquery/jquery.focus_and_blur.js
12
+ }.map{|path| (Jabs.root+path).read }.join("\n")
13
+
14
+ [200, {'Content-Type'=> 'text/javascript'}, source]
15
+ end)
16
+ end
17
+ end
18
+
4
19
  class Static < ::Rack::Static
5
20
  def initialize(app, options={})
6
21
  super(app, options)
@@ -11,7 +26,6 @@ module Jabs
11
26
 
12
27
  class File < ::Rack::File
13
28
  def serving
14
- @path += ".jabs" unless @path[/\.jabs$/]
15
29
  status, headers, body = * super
16
30
  return [status, headers, body] unless status == 200
17
31
 
@@ -19,7 +33,7 @@ module Jabs
19
33
 
20
34
  headers['Content-Type'] = 'text/javascript'
21
35
  headers['Content-Length'] = jabs.size.to_s
22
-
36
+
23
37
  [status, headers, jabs]
24
38
  end
25
39
  end