nitro 0.24.0 → 0.25.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.
Files changed (67) hide show
  1. data/CHANGELOG +279 -0
  2. data/ProjectInfo +7 -7
  3. data/doc/AUTHORS +4 -2
  4. data/doc/RELEASES +96 -1
  5. data/lib/nitro.rb +5 -2
  6. data/lib/nitro/adapter/cgi.rb +1 -1
  7. data/lib/nitro/adapter/webrick.rb +7 -5
  8. data/lib/nitro/caching/output.rb +3 -2
  9. data/lib/nitro/cgi/utils.rb +8 -4
  10. data/lib/nitro/compiler.rb +9 -5
  11. data/lib/nitro/compiler/include.rb +42 -0
  12. data/lib/nitro/compiler/markup.rb +1 -1
  13. data/lib/nitro/compiler/morphing.rb +120 -50
  14. data/lib/nitro/compiler/squeeze.rb +2 -2
  15. data/lib/nitro/context.rb +9 -0
  16. data/lib/nitro/controller.rb +8 -4
  17. data/lib/nitro/dispatcher.rb +5 -5
  18. data/lib/nitro/dispatcher/nice.rb +16 -5
  19. data/lib/nitro/element.rb +30 -8
  20. data/lib/nitro/helper.rb +56 -0
  21. data/lib/nitro/{mixin → helper}/benchmark.rb +1 -1
  22. data/lib/nitro/{mixin → helper}/buffer.rb +1 -2
  23. data/lib/nitro/{mixin → helper}/debug.rb +1 -1
  24. data/lib/nitro/{mixin/helper.rb → helper/default.rb} +4 -4
  25. data/lib/nitro/{mixin → helper}/form.rb +3 -3
  26. data/lib/nitro/{mixin → helper}/javascript.rb +17 -1
  27. data/lib/nitro/{mixin → helper}/pager.rb +1 -1
  28. data/lib/nitro/{mixin → helper}/rss.rb +3 -3
  29. data/lib/nitro/{mixin → helper}/table.rb +1 -1
  30. data/lib/nitro/{mixin → helper}/xhtml.rb +2 -2
  31. data/lib/nitro/{mixin → helper}/xml.rb +1 -1
  32. data/lib/nitro/render.rb +16 -8
  33. data/lib/nitro/scaffold.rb +6 -6
  34. data/lib/nitro/server/runner.rb +12 -0
  35. data/lib/nitro/session/drbserver.rb +16 -1
  36. data/proto/public/js/builder.js +97 -0
  37. data/proto/public/js/controls.js +18 -5
  38. data/proto/public/js/dragdrop.js +8 -5
  39. data/proto/public/js/effects.js +185 -4
  40. data/proto/public/js/prototype.js +432 -178
  41. data/proto/public/js/scriptaculous.js +6 -2
  42. data/proto/public/js/slider.js +226 -0
  43. data/proto/public/js/unittest.js +363 -0
  44. data/proto/public/media/nitro.png +0 -0
  45. data/{script → proto/script}/scgi_ctl +0 -0
  46. data/{script → proto/script}/scgi_service +16 -8
  47. data/proto/src/skin.rb +24 -0
  48. data/{lib → src}/part/admin.rb +0 -0
  49. data/src/part/admin/controller.rb +47 -0
  50. data/{lib → src}/part/admin/skin.rb +0 -0
  51. data/src/part/admin/template/denied.xhtml +1 -0
  52. data/{lib → src}/part/admin/template/index.xhtml +0 -0
  53. data/test/nitro/{mixin → helper}/tc_pager.rb +2 -2
  54. data/test/nitro/{mixin → helper}/tc_rss.rb +3 -3
  55. data/test/nitro/{mixin → helper}/tc_table.rb +3 -3
  56. data/test/nitro/{mixin → helper}/tc_xhtml.rb +3 -3
  57. data/test/nitro/tc_caching.rb +4 -1
  58. data/test/nitro/tc_controller.rb +2 -2
  59. data/test/nitro/tc_element.rb +30 -0
  60. data/test/nitro/tc_helper.rb +36 -0
  61. data/test/nitro/tc_render.rb +1 -1
  62. metadata +70 -38
  63. data/lib/nitro/mixin/markup.rb +0 -122
  64. data/lib/part/admin/controller.rb +0 -28
  65. data/proto/README +0 -11
  66. data/proto/doc/README +0 -1
  67. data/proto/scgi.rb +0 -333
@@ -15,7 +15,7 @@ class CgiAdapter
15
15
 
16
16
  def self.start(server)
17
17
  cgi = CGI.new
18
- CgiUtils.process(server, cgi, cgi, cgi)
18
+ Cgi.process(server, cgi, cgi, cgi)
19
19
  =begin
20
20
  context = Context.new(server)
21
21
  context.headers = ENV
@@ -134,7 +134,8 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
134
134
 
135
135
  # gmosx: make compatible with fastcgi.
136
136
  context.headers['REQUEST_URI'].slice!(/http:\/\/(.*?)\//)
137
- context.headers['REQUEST_URI'] << '/'
137
+ # context.headers['REQUEST_URI'] << '/'
138
+ context.headers['REQUEST_URI'] = '/' + context.headers['REQUEST_URI']
138
139
 
139
140
  Cgi.parse_params(context)
140
141
  Cgi.parse_cookies(context)
@@ -161,9 +162,9 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
161
162
  # Try to rewrite the path to a filename.
162
163
 
163
164
  def rewrite(req)
164
- if req.path == '/'
165
+ if req.path_info == '/'
165
166
  req.instance_variable_set(:@path_info, '/index.html')
166
- elsif req.path =~ /^([^.]+)$/
167
+ elsif req.path_info =~ /^([^.]+)$/
167
168
  req.instance_variable_set(:@path_info, "#{$1}/index.html")
168
169
  end
169
170
  end
@@ -171,9 +172,9 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
171
172
  # Rewrite back to the original path.
172
173
 
173
174
  def unrewrite(req)
174
- if req.path == '/'
175
+ if req.path_info == '/index.html'
175
176
  req.instance_variable_set(:@path_info, '/')
176
- elsif req.path =~ /^([^.]+).html$/
177
+ elsif req.path_info =~ /^([^.]+)\/index.html$/
177
178
  req.instance_variable_set(:@path_info, $1)
178
179
  end
179
180
  end
@@ -183,3 +184,4 @@ end
183
184
 
184
185
  # * George Moschovitis <gm@navel.gr>
185
186
  # * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
187
+ # * Bryan Soto <bryan.a.soto@gmail.com>
@@ -44,7 +44,7 @@ module Caching
44
44
  def output_cache_path(path)
45
45
  filename = ((path.empty? || path == '/') ? 'index.html' : path.dup)
46
46
  # filename.gsub!(/\/$/, '')
47
- filename << 'index.html' unless (filename.split('/').last || filename).include? '.'
47
+ filename << '/index.html' unless (filename.split('/').last || filename).include? '.'
48
48
  return output_cache_root + '/' + filename
49
49
  end
50
50
 
@@ -66,9 +66,10 @@ module Caching
66
66
  # gmosx: is this the right thing to do?
67
67
  end
68
68
  end
69
+ alias_method :delete_output, :expire_output
69
70
 
70
71
  def caching_allowed?
71
- !@request.post?
72
+ not (@request.post? or @request.uri =~ /\?/)
72
73
  end
73
74
 
74
75
  end
@@ -5,25 +5,29 @@ module Nitro
5
5
  module Request
6
6
 
7
7
  # Some useful mini methods for browser testing.
8
+ # TODO: add testing for mac IE (an other platforms)
8
9
 
10
+ # Different servers hold user agent in differnet
11
+ # strings (unify this).
12
+
9
13
  def user_agent
10
14
  headers['HTTP_USER_AGENT'] || headers['USER-AGENT']
11
15
  end
12
16
 
13
17
  def from_gecko?
14
- headers['USER-AGENT'] =~ /Gecko/
18
+ user_agent =~ /Gecko/
15
19
  end
16
20
  alias_method :from_mozilla?, :from_gecko?
17
21
 
18
22
  def from_ie?
19
- headers['USER-AGENT'] =~ /MSIE/
23
+ user_agent =~ /MSIE/
20
24
  end
21
25
  alias_method :from_msie?, :from_ie?
22
26
 
23
27
  def from_opera?
24
- headers['USER-AGENT'] =~ /Opera/
28
+ user_agent =~ /Opera/
25
29
  end
26
30
 
27
31
  def from_khtml?
28
- headers['USER-AGENT'] =~ /KTHML/
32
+ user_agent =~ /KTHML/
29
33
  end
30
34
  alias_method :from_safari?, :from_khtml?
31
35
 
@@ -38,7 +38,7 @@ class Compiler
38
38
  # template_root/action/index.xhtml
39
39
 
40
40
  path = "#{template_root}/#{action.gsub(/__/, '/')}/#{Template.default}.#{ext}".squeeze('/')
41
-
41
+
42
42
  unless File.exist?(path)
43
43
  # No template found!
44
44
  return nil
@@ -105,7 +105,7 @@ class Compiler
105
105
 
106
106
  code = %{
107
107
  def #{action}_action
108
- @parent_action_name = @action_name
108
+ @parent_action_name = @action_name
109
109
  @action_name = '#{action}'
110
110
  }
111
111
 
@@ -131,17 +131,21 @@ class Compiler
131
131
  param_count = klass.instance_method(action.intern).arity
132
132
 
133
133
  if param_count != 0
134
+ if param_count > 0
135
+ code << "params = Array.new(#{param_count}, nil);"
136
+ else
137
+ code << "params = [];"
138
+ end
134
139
  code << %{
135
- params = []
136
140
  if context.query_string
137
141
  context.query_string.split(/[&;]/).each_with_index do |qs, i|
138
142
  }
139
143
  # Don't pass more parameters than the action's arity.
140
144
  if param_count > 0
141
- code << "break if i >= #{param_count};"
145
+ code << "break unless i < #{param_count};"
142
146
  end
143
147
  code << %{
144
- params << CGI.unescape(qs.split(/=/).last)
148
+ params[i] = CGI.unescape(qs.split(/=/).last)
145
149
  end
146
150
  end
147
151
  action_return_value = #{action}(*params)
@@ -0,0 +1,42 @@
1
+ module Nitro
2
+
3
+ # Performs static includes. Typically you should include this compiler
4
+ # as the first stage of the compile pipeline.
5
+ #
6
+ # This compiler is extremely helpful, typically you would want
7
+ # to use static includes in many many cases.
8
+
9
+ class StaticInclude
10
+ #--
11
+ # FIXME: use template root of the controller.
12
+ #++
13
+
14
+ def self.transform(text)
15
+ # Statically include sub-template files.
16
+ # The target file is included at compile time.
17
+ #
18
+ # gmosx: must be xformed before the <?r pi.
19
+ #
20
+ # Example:
21
+ # <?include href="root/myfile.sx" ?>
22
+
23
+ return text.gsub(/<\?include href=["|'](.*?)["|'](.*)\?>/) do |match|
24
+ unless File.exist?(filename = "#{Template.root}/#$1")
25
+ unless File.exist?(filename = "#{Template.root}/#$1.xinc")
26
+ unless File.exist?(filename = "#{Template.root}/#$1.xhtml")
27
+ raise "Cannot include '#{Template.root}/#$1'"
28
+ end
29
+ end
30
+ end
31
+ itext = File.read(filename)
32
+ itext.gsub!(/<\?xml.*\?>/, '')
33
+ itext.gsub!(/<\/?root(.*?)>/m, ' ');
34
+ itext
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ # * George Moschovitis <gm@navel.gr>
@@ -1,4 +1,4 @@
1
- require 'nitro/mixin/markup'
1
+ require 'glue/markup'
2
2
 
3
3
  module Nitro
4
4
 
@@ -1,66 +1,136 @@
1
- module Nitro::Compiler
1
+ require 'rexml/document'
2
+ require 'rexml/streamlistener'
2
3
 
3
- # A module that expand xhtml tags to ruby code
4
- # according to some tag attributes. (if, unless, each)
5
- #--
6
- # FIXME: nested tags are not handled correctly. We should
7
- # reimplement this using REXML or something.
8
- #++
4
+ module Nitro
9
5
 
10
- module Morphing
6
+ # A compiler that handles these attribute's tags:
7
+ #
8
+ # <tag if="x">..</tag>
9
+ # <tag unless="x">..</tag>
10
+ # <tag each="x">..</tag>
11
+ # <tag times="x">..</tag>
12
+ #
13
+ # by transforming them like that
14
+ #
15
+ # <div prop1="one" if="@mycond" prop2="two">@mycond is true</div>
16
+ #
17
+ # becomes
18
+ #
19
+ # <?r if @mycond ?>
20
+ # <div prop1="one" prop2="two">@mycond is true</div>
21
+ # <?r end ?>
22
+ #
23
+ #
24
+ # <li times="3">...</li>
25
+ #
26
+ # becomes
27
+ #
28
+ # <?r 3.times do ?>
29
+ # <li>...</li>
30
+ # <?r end ?>
31
+ #
32
+ #
33
+ # <li each="item in array">my item is #{item}</li>
34
+ #
35
+ # becomes
36
+ #
37
+ # <?r for item in array ?>
38
+ # <li>my item is #{item}</li>
39
+ # <?r end ?>
11
40
 
12
- def self.transform(input_text)
13
- text = input_text.dup
14
- # <tag if="x">..</tag>
15
- # <tag unless="x">..</tag>
16
- #
17
- # example:
18
- #
19
- # <div prop1="one" if="@mycond" prop2="two">@mycond is true</div>
20
- #
21
- # becomes
22
- #
23
- # <?r if @mycond ?>
24
- # <div prop1="one" prop2="two">@mycond is true</div>
25
- # <?r end ?>
41
+ class Morphing
26
42
 
27
- text.gsub!(/<(\w*?)([^>]*?)(if|unless)=["|'](.*?)["|'](.*?)>(.*?)<\/\1>/m) do |match|
28
- %{<?r #$3 #$4 ?>
29
- <#$1#$2#$5>#$6</#$1>
30
- <?r end ?>}
43
+ class Listener # :nodoc: all
44
+ include REXML::StreamListener
45
+
46
+ attr_reader :buffer
47
+
48
+ def initialize
49
+ super
50
+ @buffer = ''
51
+ @stack = []
52
+ @depth = 0
31
53
  end
32
-
33
- # <tag times="x">..</tag>
34
-
35
- text.gsub!(/<(\w*?)([^>]*?)times=["|'](.*?)["|'](.*?)>(.*?)<\/\1>/m) do |match|
36
- %{<?r #$3.times do ?>
37
- <#$1#$2#$4>#$5</#$1>
38
- <?r end ?>}
54
+
55
+ def tag_start(name, attributes)
56
+ if attr = attributes.detect { |k, v| %w{if unless for each times}.include?(k) }
57
+ temp_buffer =
58
+ if attr[0] == 'times'
59
+ "<?r #{attr[1]}.times do ?>"
60
+ elsif (attr[0] == 'for' or attr[0] == 'each') and attr[1] =~ / in /
61
+ "<?r for #{attr[1]} ?>"
62
+ elsif attr[0] == 'if' or attr[0] == 'unless'
63
+ "<?r #{attr[0]} #{attr[1]} ?>"
64
+ else
65
+ Logger.info "Morphing: #{attr[0]} attribute found but was not suitable for morphing" if $DBG
66
+ false
67
+ end
68
+ if temp_buffer
69
+ @buffer << temp_buffer
70
+ attributes.delete(attr[0])
71
+ @stack.push(@depth)
72
+ end
73
+ end
74
+
75
+ attrs = attributes.collect do | k, v |
76
+ %|#{k}="#{v}"|
77
+ end
78
+
79
+ attrs = attrs.empty? ? "" : " " + attrs.join(' ')
80
+ @depth += 1
81
+ @buffer << "<#{name}#{attrs}>"
39
82
  end
40
83
 
41
- # <tag each="x">..</tag>
42
- #
43
- # example:
44
- #
45
- # <li each="item in array">my item is #{item}</li>
46
- #
47
- # becomes
48
- #
49
- # <?r for item in array ?>
50
- # <li>my item is #{item}</li>
51
- # <?r end ?>
52
-
53
- text.gsub!(/<(\w*?)([^>]*?)each=["|'](.*?)["|'](.*?)>(.*?)<\/\1>/m) do |match|
54
- %{<?r for #$3 ?>
55
- <#$1#$2#$4>#$5</#$1>
56
- <?r end ?>}
84
+ def tag_end(name)
85
+ @depth -= 1
86
+ @buffer << "</#{name}>"
87
+ if @stack.last == @depth
88
+ @buffer << "\n<?r end ?>"
89
+ @stack.pop
90
+ end
57
91
  end
58
92
 
59
- text
93
+ def text(str)
94
+ @buffer << str
95
+ end
96
+
97
+ def instruction(name, attributes)
98
+ @buffer << "<?#{name}#{attributes}?>"
99
+ end
60
100
  end
101
+
102
+ def self.transform(source)
103
+ listener = Listener.new
104
+ REXML::Document.parse_stream(source, listener)
105
+ return listener.buffer
106
+ end
107
+
108
+ end
61
109
 
62
110
  end
63
111
 
112
+ if __FILE__ == $0
113
+ puts Nitro::Morphing.transform(<<EOF)
114
+ <body>
115
+ <child attr1="attr1" if="test" attr2="attr2">
116
+ <mytag>
117
+ this is texxt
118
+ <one if="@qsdf">
119
+ qqqqq
120
+ </one>
121
+ </mytag>
122
+ </child>
123
+ <child times="4">
124
+ <mytag>
125
+ qqqqq
126
+ </mytag>
127
+ <one if="@qsdf">
128
+ text
129
+ </one>
130
+ </child>
131
+ </body>
132
+ EOF
64
133
  end
65
134
 
66
135
  # * George Moschovitis <gm@navel.gr>
136
+ # * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
@@ -1,4 +1,4 @@
1
- module Nitro::Compiler
1
+ module Nitro
2
2
 
3
3
  # Compress the inline xhtml. Does not touch the ruby code.
4
4
 
@@ -6,7 +6,7 @@ class Squeeze
6
6
 
7
7
  # Compresses the inline xhtml. Does not touch the ruby code.
8
8
 
9
- def transform(text)
9
+ def self.transform(text)
10
10
  return text.gsub(/\@out \<\< \%\^(.*?)\^/m) do |match|
11
11
  c = $1.gsub(/^(\s*)/m, '').squeeze(" \t").tr("\n", '').tr("\t", ' ')
12
12
  "@out << %{#{c}}"
data/lib/nitro/context.rb CHANGED
@@ -80,6 +80,15 @@ class Context
80
80
  @session || @session = Session.lookup(self)
81
81
  end
82
82
 
83
+ # Lookup the controller for this request.
84
+ #--
85
+ # FIXME: improve this! BUGGY
86
+ #++
87
+
88
+ def controller
89
+ @dispatcher.controllers[@base || '/']
90
+ end
91
+
83
92
  # Populate an object from request parameters.
84
93
  # This is a truly dangerous method.
85
94
  #
@@ -1,14 +1,14 @@
1
1
  require 'mega/annotation'
2
2
 
3
3
  require 'glue/aspects'
4
- require 'glue/helper'
4
+ require 'glue/markup'
5
5
 
6
6
  require 'nitro'
7
7
  require 'nitro/render'
8
8
  require 'nitro/scaffold'
9
9
  require 'nitro/caching'
10
10
  require 'nitro/flash'
11
- require 'nitro/mixin/markup'
11
+ require 'nitro/helper'
12
12
 
13
13
  module Nitro
14
14
 
@@ -40,7 +40,7 @@ module Publishable
40
40
  include Render
41
41
  include Glue::Aspects
42
42
  include Flashing
43
- include Glue::Helpers
43
+ include Helpers
44
44
 
45
45
  # Override this method as needed. Unless overriden
46
46
  # this method is initialized by the Dispatcher to
@@ -136,7 +136,11 @@ class Controller
136
136
  include Publishable
137
137
  include Scaffolding
138
138
  include Caching
139
- include Markup
139
+ include Helpers
140
+ helper Markup
140
141
  end
141
142
 
142
143
  end
144
+
145
+ # * George Moschovitis <gm@navel.gr>
146
+