nitro 0.20.0 → 0.21.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 (115) hide show
  1. data/CHANGELOG +752 -543
  2. data/INSTALL +38 -38
  3. data/README +264 -225
  4. data/Rakefile +48 -49
  5. data/bin/nitro +3 -3
  6. data/bin/nitrogen +6 -6
  7. data/doc/AUTHORS +10 -10
  8. data/doc/CHANGELOG.1 +1939 -1939
  9. data/doc/CHANGELOG.2 +954 -954
  10. data/doc/LICENSE +3 -3
  11. data/doc/MIGRATION +28 -0
  12. data/doc/RELEASES +814 -643
  13. data/doc/config.txt +5 -5
  14. data/install.rb +7 -17
  15. data/lib/nitro.rb +38 -9
  16. data/lib/nitro/adapter/cgi.rb +311 -312
  17. data/lib/nitro/adapter/fastcgi.rb +18 -25
  18. data/lib/nitro/adapter/webrick.rb +128 -137
  19. data/lib/nitro/adapter/wee.rb +51 -0
  20. data/lib/nitro/caching.rb +20 -20
  21. data/lib/nitro/caching/actions.rb +43 -43
  22. data/lib/nitro/caching/fragments.rb +46 -46
  23. data/lib/nitro/caching/invalidation.rb +11 -11
  24. data/lib/nitro/caching/output.rb +65 -65
  25. data/lib/nitro/caching/stores.rb +67 -67
  26. data/lib/nitro/compiler.rb +262 -0
  27. data/lib/nitro/compiler/elements.rb +0 -0
  28. data/lib/nitro/compiler/errors.rb +65 -0
  29. data/lib/nitro/compiler/localization.rb +25 -0
  30. data/lib/nitro/compiler/markup.rb +19 -0
  31. data/lib/nitro/compiler/shaders.rb +206 -0
  32. data/lib/nitro/compiler/squeeze.rb +20 -0
  33. data/lib/nitro/compiler/xslt.rb +61 -0
  34. data/lib/nitro/context.rb +87 -88
  35. data/lib/nitro/controller.rb +151 -158
  36. data/lib/nitro/cookie.rb +34 -34
  37. data/lib/nitro/dispatcher.rb +195 -186
  38. data/lib/nitro/element.rb +132 -126
  39. data/lib/nitro/element/java_script.rb +6 -6
  40. data/lib/nitro/flash.rb +66 -66
  41. data/lib/nitro/mail.rb +192 -192
  42. data/lib/nitro/mixin/buffer.rb +66 -0
  43. data/lib/nitro/mixin/debug.rb +16 -16
  44. data/lib/nitro/mixin/form.rb +88 -0
  45. data/lib/nitro/mixin/helper.rb +2 -2
  46. data/lib/nitro/mixin/javascript.rb +108 -108
  47. data/lib/nitro/mixin/markup.rb +144 -0
  48. data/lib/nitro/mixin/pager.rb +202 -202
  49. data/lib/nitro/mixin/rss.rb +67 -0
  50. data/lib/nitro/mixin/table.rb +63 -0
  51. data/lib/nitro/mixin/xhtml.rb +75 -0
  52. data/lib/nitro/mixin/xml.rb +124 -0
  53. data/lib/nitro/render.rb +183 -359
  54. data/lib/nitro/request.rb +140 -140
  55. data/lib/nitro/response.rb +27 -27
  56. data/lib/nitro/routing.rb +21 -21
  57. data/lib/nitro/scaffold.rb +124 -118
  58. data/lib/nitro/server.rb +117 -80
  59. data/lib/nitro/server/runner.rb +341 -0
  60. data/lib/nitro/service.rb +12 -12
  61. data/lib/nitro/service/xmlrpc.rb +22 -22
  62. data/lib/nitro/session.rb +122 -120
  63. data/lib/nitro/session/drb.rb +9 -9
  64. data/lib/nitro/session/drbserver.rb +34 -34
  65. data/lib/nitro/template.rb +171 -155
  66. data/lib/nitro/testing/assertions.rb +90 -90
  67. data/lib/nitro/testing/context.rb +16 -16
  68. data/lib/nitro/testing/testcase.rb +34 -34
  69. data/proto/conf/lhttpd.conf +9 -9
  70. data/proto/public/error.xhtml +75 -75
  71. data/proto/public/index.xhtml +18 -18
  72. data/proto/public/js/behaviour.js +65 -65
  73. data/proto/public/js/controls.js +1 -1
  74. data/proto/public/js/prototype.js +3 -3
  75. data/proto/public/settings.xhtml +61 -61
  76. data/proto/run.rb +1 -5
  77. data/test/nitro/adapter/raw_post1.bin +0 -0
  78. data/test/nitro/adapter/tc_cgi.rb +57 -57
  79. data/test/nitro/adapter/tc_webrick.rb +4 -4
  80. data/test/nitro/mixin/tc_pager.rb +25 -25
  81. data/test/nitro/mixin/tc_rss.rb +24 -0
  82. data/test/nitro/mixin/tc_table.rb +31 -0
  83. data/test/nitro/mixin/tc_xhtml.rb +13 -0
  84. data/test/nitro/tc_caching.rb +10 -10
  85. data/test/nitro/tc_context.rb +8 -8
  86. data/test/nitro/tc_controller.rb +48 -48
  87. data/test/nitro/tc_cookie.rb +6 -6
  88. data/test/nitro/tc_dispatcher.rb +64 -64
  89. data/test/nitro/tc_element.rb +27 -27
  90. data/test/nitro/tc_flash.rb +31 -31
  91. data/test/nitro/tc_mail.rb +63 -63
  92. data/test/nitro/tc_server.rb +26 -26
  93. data/test/nitro/tc_session.rb +9 -9
  94. data/test/nitro/tc_template.rb +19 -19
  95. data/test/public/blog/list.xhtml +1 -1
  96. metadata +31 -37
  97. data/lib/nitro/buffering.rb +0 -45
  98. data/lib/nitro/builder/form.rb +0 -104
  99. data/lib/nitro/builder/rss.rb +0 -104
  100. data/lib/nitro/builder/table.rb +0 -80
  101. data/lib/nitro/builder/xhtml.rb +0 -132
  102. data/lib/nitro/builder/xml.rb +0 -131
  103. data/lib/nitro/conf.rb +0 -36
  104. data/lib/nitro/environment.rb +0 -21
  105. data/lib/nitro/errors.rb +0 -69
  106. data/lib/nitro/localization.rb +0 -153
  107. data/lib/nitro/markup.rb +0 -147
  108. data/lib/nitro/output.rb +0 -24
  109. data/lib/nitro/runner.rb +0 -348
  110. data/lib/nitro/shaders.rb +0 -206
  111. data/test/nitro/builder/tc_rss.rb +0 -23
  112. data/test/nitro/builder/tc_table.rb +0 -30
  113. data/test/nitro/builder/tc_xhtml.rb +0 -39
  114. data/test/nitro/builder/tc_xml.rb +0 -56
  115. data/test/nitro/tc_localization.rb +0 -49
@@ -0,0 +1,66 @@
1
+ require 'glue/attribute'
2
+
3
+ module Nitro
4
+
5
+ # The output buffering mixin. Provides php-style output
6
+ # buffering functionality.
7
+ #
8
+ # === Examples
9
+ #
10
+ # <?r buf = capture do ?>
11
+ # ...
12
+ # <?r end ?>
13
+ #
14
+ #--
15
+ # TODO: use better names but keep the ob_xxx php style methods
16
+ # as aliases.
17
+ #++
18
+
19
+ module BufferMixin
20
+
21
+ private
22
+
23
+ # Output buffers stack, used for php-style nested output
24
+ # buffering.
25
+
26
+ attr :out_buffers
27
+
28
+ # Start (push) a new output buffer.
29
+
30
+ def open_buffer
31
+ @out_buffers ||= []
32
+ @out_buffers.push(@out)
33
+ @out = ''
34
+ end
35
+ alias_method :ob_start, :open_buffer
36
+
37
+ # End (pop) the current output buffer.
38
+
39
+ def close_buffer
40
+ buf = @out
41
+ @out = @out_buffers.pop
42
+ return buf
43
+ end
44
+ alias_method :ob_end, :close_buffer
45
+
46
+ # End (pop) the current output buffer and write to the parent.
47
+
48
+ def close_and_write_buffer
49
+ nested_buffer = @out
50
+ @out = @out_buffers.pop
51
+ @out << nested_buffer
52
+ end
53
+ alias_method :ob_write_end, :close_and_write_buffer
54
+
55
+ def capture
56
+ open_buffer
57
+ yield
58
+ return close_buffer
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ # * George Moschovitis <gm@navel.gr>
66
+
@@ -6,22 +6,22 @@ module DebugMixin
6
6
 
7
7
  private
8
8
 
9
- # Returns a <pre>-tag set with the +object+ dumped by YAML.
10
- # Very readable way to inspect an object.
11
- #--
12
- # TODO: make safe html.
13
- #++
14
-
15
- def debug(object)
16
- begin
17
- Marshal::dump(object)
18
- "<pre class='debug_dump'>#{object.to_yaml.gsub(" ", "&nbsp; ")}</pre>"
19
- rescue Object
20
- # Object couldn't be dumped, perhaps because of singleton
21
- # methods, this is the fallback.
22
- "<code class='debug_dump'>#{object.inspect}</code>"
23
- end
24
- end
9
+ # Returns a <pre>-tag set with the +object+ dumped by YAML.
10
+ # Very readable way to inspect an object.
11
+ #--
12
+ # TODO: make safe html.
13
+ #++
14
+
15
+ def debug(object)
16
+ begin
17
+ Marshal::dump(object)
18
+ "<pre class='debug_dump'>#{object.to_yaml.gsub(" ", "&nbsp; ")}</pre>"
19
+ rescue Object
20
+ # Object couldn't be dumped, perhaps because of singleton
21
+ # methods, this is the fallback.
22
+ "<code class='debug_dump'>#{object.inspect}</code>"
23
+ end
24
+ end
25
25
 
26
26
  end
27
27
 
@@ -0,0 +1,88 @@
1
+ require 'glue/hash'
2
+
3
+ module Nitro
4
+
5
+ # A collection of useful helpers for creating and manipulating
6
+ # Forms.
7
+
8
+ module FormMixin
9
+
10
+ # Render a standard form for the given Entity (ie an
11
+ # object with attribute metadata).
12
+ # If show_all is false then apply field filtering.
13
+ #
14
+ # Example:
15
+ #
16
+ # <p>
17
+ # <form name="test">
18
+ # #{form_for entry}
19
+ # </form>
20
+ # </p>
21
+ #--
22
+ # TODO: get info, for example localization mode from session,
23
+ # if this module is mixed in a Render.
24
+ #++
25
+
26
+ def form_for(obj, lc = nil, show_all = false)
27
+ str = '<dl>'
28
+
29
+ for p in obj.class.properties
30
+ unless show_all
31
+ next if :oid == p.symbol
32
+ end
33
+
34
+ if p.klass.ancestors.include?(Integer) or
35
+ p.klass.ancestors.include?(Float)
36
+ str << %{
37
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
38
+ <dd>
39
+ <input type="text" id="#{p.symbol}" name="#{p.symbol}" value="#{obj.send(p.symbol)}" />
40
+ </dd>
41
+ }
42
+ elsif p.klass.ancestors.include?(String)
43
+ str << %{
44
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
45
+ <dd>
46
+ }
47
+ val = obj.send(p.symbol)
48
+ if :textarea == p.meta[:ui]
49
+ str << %{
50
+ <textarea id="#{p.symbol}" name="#{p.symbol}">#{val}</textarea>
51
+ }
52
+ else
53
+ str << %{
54
+ <input type="text" id="#{p.symbol}" name="#{p.symbol}" value="#{val}" />
55
+ }
56
+ end
57
+ str << %{
58
+ </dd>
59
+ }
60
+ elsif p.klass.ancestors.include?(TrueClass)
61
+ str << %{
62
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
63
+ <dd>
64
+ <input type="checkbox" id="#{p.symbol}" name="#{p.symbol}" />
65
+ </dd>
66
+ }
67
+ elsif p.klass.ancestors.include?(Time)
68
+ str << %{
69
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
70
+ <dd>
71
+ <input type="text" id="#{p.symbol}" name="#{p.symbol}" value="#{obj.send(p.symbol)}" />
72
+ </dd>
73
+ }
74
+ end
75
+ end
76
+
77
+ str << %{
78
+ </dl>}
79
+
80
+ self << str
81
+ end
82
+ alias_method :build_form, :form_for
83
+
84
+ end
85
+
86
+ end
87
+
88
+ # * George Moschovitis
@@ -7,8 +7,8 @@ module Nitro
7
7
  # be shared accross all Controllers.
8
8
 
9
9
  module Helper
10
- include DebugMixin
11
- # This is an open module, extend in your application.
10
+ include DebugMixin
11
+ # This is an open module, extend in your application.
12
12
  end
13
13
 
14
14
  end
@@ -13,123 +13,123 @@ module JavascriptMixin
13
13
 
14
14
  private
15
15
 
16
- unless const_defined? :DEFAULT_JAVASCRIPT_FILES
17
- DEFAULT_JAVASCRIPT_FILES = [
18
- 'js/behaviour.js',
19
- 'js/prototype.js',
20
- 'js/effects.js',
21
- 'js/dragdrop.js',
22
- 'js/controls.js'
23
- ]
24
- end
16
+ unless const_defined? :DEFAULT_JAVASCRIPT_FILES
17
+ DEFAULT_JAVASCRIPT_FILES = [
18
+ 'js/behaviour.js',
19
+ 'js/prototype.js',
20
+ 'js/effects.js',
21
+ 'js/dragdrop.js',
22
+ 'js/controls.js'
23
+ ]
24
+ end
25
25
 
26
- # :section: behaviour.js
27
-
28
- def behaviour(id, js)
29
- @_behaviours ||= []
30
- @_behaviours << [id, js]
31
- end
32
-
33
- # :section: prototype.js
26
+ # :section: behaviour.js
27
+
28
+ def behaviour(id, js)
29
+ @_behaviours ||= []
30
+ @_behaviours << [id, js]
31
+ end
32
+
33
+ # :section: prototype.js
34
34
 
35
- def live_request(id, options = {})
36
- if href = options.delete(:href)
37
- behaviour "##{id}", %{
38
- el.onclick = function() {
39
- new Ajax.Request('#{href}', #{hash_to_js(options)});
40
- return false;
41
- }
42
- }
43
- else
44
- behaviour "##{id}", %{
45
- el.onclick = function() {
46
- new Ajax.Request(el.href, #{hash_to_js(options)});
47
- return false;
48
- }
49
- }
50
- end
51
- end
52
- alias_method :live, :live_request
53
- alias_method :async, :live_request
54
-
55
- # :section: script.aculo.us dragdrop.js
56
-
57
- # Make the element dragable.
58
-
59
- def draggable(id, options = {})
60
- @_javascript ||= ''
61
- @_javascript << "\nnew Draggable('#{id}', #{hash_to_js(options)});"
62
- end
63
-
64
- # :section: script.aculo.us controls.js
65
-
66
- # Add autocomplete functionality to a text field.
67
-
68
- def auto_complete(id, options = {})
69
- update = options[:update] || "#{id}_auto_complete"
70
- url = options[:url] || "#{id}_auto_complete"
71
- @_javascript ||= ''
72
- @_javascript << "\nnew Ajax.Autocompleter('#{id}', '#{update}', '#{url}');"
73
-
74
- # Turn off the browser's autocomplete functionality to avoid
75
- # interference.
76
-
77
- behaviour "##{id}", %{
78
- el.autocomplete = 'off';
79
- }
80
- end
81
-
82
- # :section: general javascript helpers.
83
-
84
- # Include external javascript file.
85
-
86
- def include_script(files = DEFAULT_JAVASCRIPT_FILES)
87
- code = ''
88
-
89
- for file in [files].flatten
90
- code << %|<script src="#{file}" type="text/javascript">//</script>|
91
- end
92
-
93
- return code
94
- end
95
-
96
- # Escape carrier returns and single and double quotes for JavaScript segments.
35
+ def live_request(id, options = {})
36
+ if href = options.delete(:href)
37
+ behaviour "##{id}", %{
38
+ el.onclick = function() {
39
+ new Ajax.Request('#{href}', #{hash_to_js(options)});
40
+ return false;
41
+ }
42
+ }
43
+ else
44
+ behaviour "##{id}", %{
45
+ el.onclick = function() {
46
+ new Ajax.Request(el.href, #{hash_to_js(options)});
47
+ return false;
48
+ }
49
+ }
50
+ end
51
+ end
52
+ alias_method :live, :live_request
53
+ alias_method :async, :live_request
54
+
55
+ # :section: script.aculo.us dragdrop.js
56
+
57
+ # Make the element dragable.
58
+
59
+ def draggable(id, options = {})
60
+ @_javascript ||= ''
61
+ @_javascript << "\nnew Draggable('#{id}', #{hash_to_js(options)});"
62
+ end
63
+
64
+ # :section: script.aculo.us controls.js
65
+
66
+ # Add autocomplete functionality to a text field.
67
+
68
+ def auto_complete(id, options = {})
69
+ update = options[:update] || "#{id}_auto_complete"
70
+ url = options[:url] || "#{id}_auto_complete"
71
+ @_javascript ||= ''
72
+ @_javascript << "\nnew Ajax.Autocompleter('#{id}', '#{update}', '#{url}');"
73
+
74
+ # Turn off the browser's autocomplete functionality to avoid
75
+ # interference.
76
+
77
+ behaviour "##{id}", %{
78
+ el.autocomplete = 'off';
79
+ }
80
+ end
81
+
82
+ # :section: general javascript helpers.
83
+
84
+ # Include external javascript file.
85
+
86
+ def include_script(files = DEFAULT_JAVASCRIPT_FILES)
87
+ code = ''
88
+
89
+ for file in [files].flatten
90
+ code << %|<script src="#{file}" type="text/javascript">//</script>|
91
+ end
92
+
93
+ return code
94
+ end
95
+
96
+ # Escape carrier returns and single and double quotes for JavaScript segments.
97
97
 
98
98
  def escape_javascript(js)
99
- (js || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
99
+ (js || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
100
100
  end
101
101
 
102
- # Converts a Ruby hash to a Javascript hash.
103
-
104
- def hash_to_js(options)
102
+ # Converts a Ruby hash to a Javascript hash.
103
+
104
+ def hash_to_js(options)
105
105
  '{' + options.map {|k, v| "#{k}:#{v}"}.join(', ') + '}'
106
106
  end
107
107
 
108
- # Emits the aggregated helper javascript.
109
- #--
110
- # FIXME: refactor this!
111
- #++
112
-
113
- def helper_script
114
- code = %|<script type="text/javascript">\n|
115
- unless @_behaviours.empty?
116
- code << %|var _behaviours = {\n|
117
- compo = []
118
- for id, js in @_behaviours
119
- compo << %|'#{id}': function(el) { #{js} \n }|
120
- end
121
- code << compo.join(',')
122
- code << %|
123
- }
124
- Behaviour.register(_behaviours);
125
- |
126
- end
127
- code << %|
128
- #@_javascript
129
- </script>
130
- |
131
- end
132
-
108
+ # Emits the aggregated helper javascript.
109
+ #--
110
+ # FIXME: refactor this!
111
+ #++
112
+
113
+ def helper_script
114
+ code = %|<script type="text/javascript">\n|
115
+ unless @_behaviours.empty?
116
+ code << %|var _behaviours = {\n|
117
+ compo = []
118
+ for id, js in @_behaviours
119
+ compo << %|'#{id}': function(el) { #{js} \n }|
120
+ end
121
+ code << compo.join(',')
122
+ code << %|
123
+ }
124
+ Behaviour.register(_behaviours);
125
+ |
126
+ end
127
+ code << %|
128
+ #@_javascript
129
+ </script>
130
+ |
131
+ end
132
+
133
133
  end
134
134
 
135
135
  end
@@ -0,0 +1,144 @@
1
+ require 'singleton'
2
+ require 'redcloth'
3
+
4
+ require 'glue/property'
5
+ require 'glue/sanitize'
6
+
7
+ module Nitro
8
+
9
+ #--
10
+ # Override the default PropertyUtils implementation to
11
+ # add markup support.
12
+ #++
13
+ =begin
14
+ module PropertyUtils
15
+ # Override to add markup code.
16
+ #
17
+ def self.prop_setter(prop)
18
+ s = prop.symbol
19
+ if markup = prop.meta[:markup]
20
+ # if true, set to default Markup
21
+ markup = Nitro::Markup if true == markup
22
+
23
+ code = %{
24
+ def #{s}=(val)
25
+ }
26
+
27
+ if Property.type_checking
28
+ code << %{
29
+ unless String == val.class
30
+ raise "Invalid type, expected '#{prop.klass}', is '\#\{val.class\}'."
31
+ end
32
+ }
33
+ end
34
+
35
+ code << %{
36
+ @#{s} = #{markup}.expand(val)
37
+ end
38
+
39
+ def compact_#{s}
40
+ #{markup}.compact(@#{s})
41
+ end
42
+ }
43
+
44
+ return code
45
+ else
46
+ return %{
47
+ def #{s}=(val)
48
+ @#{s} = val
49
+ end
50
+ }
51
+ end
52
+ end
53
+ end
54
+ =end
55
+
56
+ # Generalised Markup transformations.
57
+ #
58
+ # The expand methods evaluate (expand) the markup
59
+ # code to produce the final content. The compact
60
+ # methods reverse this process to create the original
61
+ # markup code. Not all markup transformations are
62
+ # reversible.
63
+ #
64
+ # When this library is included, the default PropertyUtils
65
+ # implementation is overriden to add markup support.
66
+ #
67
+ # === Examples
68
+ #
69
+ # Define your custom markup methods like this:
70
+ #
71
+ # module Markup
72
+ # def markup_simple
73
+ # ...
74
+ # end
75
+ # def markup_special
76
+ # ...
77
+ # end
78
+ #
79
+ # # maps the {{..}} macro
80
+ # alias_method :sanitize, :markup_simple
81
+ # # maps the {|..|} macro
82
+ # alias_method :markup, :markup_special
83
+ # end
84
+ #
85
+ # here comes the #{obj.body} # => prints the expanded version.
86
+ #
87
+ # obj.body = markup(@params['body'])
88
+
89
+ module Markup
90
+ private
91
+
92
+ # The default markup method. You should override this method
93
+ # in your application to call your custom markup
94
+ # methods.
95
+
96
+ def expand(str)
97
+ if str
98
+ xstr = str.dup
99
+ xstr.gsub!(/</, '&lt;')
100
+ xstr.gsub!(/>/, '&gt;')
101
+ return String.sanitize(xstr)
102
+ end
103
+ return nil
104
+ end
105
+ alias_method :sanitize, :expand
106
+
107
+ # ...
108
+
109
+ def expand_redcloth(str)
110
+ if str
111
+ return RedCloth.new(expand(str)).to_html
112
+ end
113
+ return nil
114
+ end
115
+ alias_method :markup, :expand_redcloth
116
+
117
+ # Compact (reverse) the content to the origial markup
118
+ # code. Not all markup transformations are reversible.
119
+ # You should override this method in your application
120
+ # to call your custom markup methods.
121
+ #
122
+ # NOT IMPLEMENTED.
123
+
124
+ def compact(str, meth = nil)
125
+ end
126
+
127
+ # Remove markup code from the input string.
128
+ #
129
+ # NOT IMPLEMENTED.
130
+
131
+ def clear(str)
132
+ end
133
+ end
134
+
135
+ # An abstract Markup class.
136
+
137
+ class Markuper
138
+ include Singleton
139
+ include Markup
140
+ end
141
+
142
+ end
143
+
144
+ # * George Moschovitis <gm@navel.gr>