nitro 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG +312 -0
  2. data/INSTALL +3 -1
  3. data/ProjectInfo +6 -9
  4. data/README +32 -5
  5. data/Rakefile +5 -1
  6. data/bin/nitrogen +3 -60
  7. data/doc/MIGRATION +24 -0
  8. data/doc/RELEASES +141 -0
  9. data/doc/lhttpd.txt +3 -0
  10. data/lib/glue/magick.rb +38 -0
  11. data/lib/glue/thumbnails.rb +3 -0
  12. data/lib/glue/webfile.rb +137 -0
  13. data/lib/nitro.rb +1 -1
  14. data/lib/nitro/adapter/acgi.rb +235 -0
  15. data/lib/nitro/adapter/cgi.rb +16 -17
  16. data/lib/nitro/adapter/scgi.rb +4 -4
  17. data/lib/nitro/adapter/webrick.rb +9 -2
  18. data/lib/nitro/cgi.rb +49 -49
  19. data/lib/nitro/cgi/response.rb +4 -0
  20. data/lib/nitro/cgi/stream.rb +7 -7
  21. data/lib/nitro/cgi/utils.rb +2 -1
  22. data/lib/nitro/compiler.rb +47 -4
  23. data/lib/nitro/compiler/elements.rb +40 -20
  24. data/lib/nitro/compiler/layout.rb +21 -0
  25. data/lib/nitro/compiler/localization.rb +3 -1
  26. data/lib/nitro/compiler/markup.rb +2 -0
  27. data/lib/nitro/compiler/morphing.rb +16 -4
  28. data/lib/nitro/compiler/script.rb +109 -0
  29. data/lib/nitro/context.rb +10 -10
  30. data/lib/nitro/dispatcher.rb +4 -2
  31. data/lib/nitro/element.rb +107 -26
  32. data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
  33. data/lib/nitro/flash.rb +4 -1
  34. data/lib/nitro/helper.rb +15 -0
  35. data/lib/nitro/helper/benchmark.rb +8 -2
  36. data/lib/nitro/helper/form.rb +3 -3
  37. data/lib/nitro/helper/form/controls.rb +131 -29
  38. data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
  39. data/lib/nitro/helper/javascript.rb +69 -59
  40. data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
  41. data/lib/nitro/helper/javascript/morphing.rb +163 -0
  42. data/lib/nitro/helper/javascript/prototype.rb +96 -0
  43. data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
  44. data/lib/nitro/helper/layout.rb +42 -0
  45. data/lib/nitro/helper/table.rb +190 -27
  46. data/lib/nitro/{adapter → helper}/wee.rb +9 -3
  47. data/lib/nitro/render.rb +23 -17
  48. data/lib/nitro/scaffolding.rb +19 -2
  49. data/lib/nitro/server.rb +4 -8
  50. data/lib/nitro/server/runner.rb +28 -6
  51. data/lib/nitro/session.rb +7 -7
  52. data/lib/nitro_and_og.rb +2 -0
  53. data/proto/public/Makefile.acgi +40 -0
  54. data/proto/public/acgi.c +138 -0
  55. data/proto/public/js/builder.js +7 -3
  56. data/proto/public/js/controls.js +32 -12
  57. data/proto/public/js/dragdrop.js +4 -3
  58. data/proto/public/js/effects.js +111 -62
  59. data/proto/public/js/scriptaculous.js +10 -13
  60. data/proto/public/js/slider.js +88 -31
  61. data/proto/public/scaffold/new.xhtml +2 -2
  62. data/setup.rb +1585 -0
  63. data/src/part/admin.rb +6 -0
  64. data/src/part/admin/controller.rb +3 -3
  65. data/src/part/admin/skin.rb +1 -8
  66. data/test/nitro/adapter/tc_webrick.rb +2 -0
  67. data/test/nitro/tc_controller_aspect.rb +1 -1
  68. data/test/nitro/tc_element.rb +5 -6
  69. data/test/nitro/tc_table.rb +66 -0
  70. metadata +277 -271
  71. data/doc/architecture.txt +0 -2
  72. data/doc/bugs.txt +0 -15
  73. data/doc/tutorial.txt +0 -26
  74. data/install.rb +0 -37
  75. data/lib/nitro/compiler/script_generator.rb +0 -14
  76. data/lib/nitro/compiler/shaders.rb +0 -206
  77. data/lib/nitro/helper/prototype.rb +0 -49
  78. data/lib/nitro/scaffold/relations.rb +0 -54
@@ -16,10 +16,14 @@ module Response
16
16
 
17
17
  attr_accessor :response_cookies
18
18
 
19
+ # Return the content type for this response.
20
+
19
21
  def content_type
20
22
  @response_headers['Content-Type']
21
23
  end
22
24
 
25
+ # Set the content type for this response.
26
+
23
27
  def content_type=(ctype)
24
28
  @response_headers['Content-Type'] = ctype
25
29
  end
@@ -4,14 +4,12 @@ module Nitro
4
4
 
5
5
  module Render
6
6
 
7
- # Enable streaming mode for the current
8
- # HTTP Response.
9
- # You can optionally provide an existing IO
10
- # object for streaming.
7
+ # Enable streaming mode for the current HTTP Response.
8
+ # You can optionally provide an existing IO object for
9
+ # streaming.
11
10
  #--
12
- # This code is considered a hack fix.
13
- # But it still is useful so for the moment
14
- # it stays in the distribution.
11
+ # This code is considered a hack fix. But it still is useful
12
+ # so for the moment it stays in the distribution.
15
13
  #++
16
14
 
17
15
  def stream(io = nil)
@@ -41,3 +39,5 @@ module Render
41
39
  end
42
40
 
43
41
  end
42
+
43
+ # * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
@@ -29,7 +29,8 @@ module Request
29
29
  end
30
30
 
31
31
  def from_khtml?
32
- user_agent =~ /KTHML/
32
+ puts "agent = #{user_agent}"
33
+ user_agent =~ /KHTML/
33
34
  end
34
35
  alias_method :from_safari?, :from_khtml?
35
36
 
@@ -6,14 +6,17 @@ require 'nitro/compiler/elements'
6
6
  require 'nitro/compiler/errors'
7
7
  require 'nitro/compiler/markup'
8
8
  require 'nitro/compiler/morphing'
9
+ require 'nitro/compiler/script'
9
10
  require 'nitro/compiler/include'
10
11
  require 'nitro/compiler/cleanup'
12
+ require 'nitro/compiler/layout'
11
13
 
12
14
  module Nitro
13
15
 
14
16
  # The Compiler transforms published methods (actions) and
15
17
  # assorted template files (views) into specialized code that
16
- # responds to a URI.
18
+ # responds to a URI. The generated action methods are injects
19
+ # in the Controller that handles the URI.
17
20
 
18
21
  class Compiler
19
22
  unless const_defined? :PROTO_TEMPLATE_ROOT
@@ -23,7 +26,14 @@ class Compiler
23
26
  # The controller for this compiler.
24
27
 
25
28
  attr_accessor :controller
29
+
30
+ # The compiler stages (compilers) can create multiple variables
31
+ # or accumulation bufffers to communicate with each other.
32
+ # Typically javascript and css acc-buffers are used. This is
33
+ # the shared memory used by the compilers.
26
34
 
35
+ attr_accessor :shared
36
+
27
37
  # Set to true to force reloading of code and templates for
28
38
  # each request. Extremely useful during development. Must be
29
39
  # turned off in production servers to avoid the severe
@@ -33,6 +43,7 @@ class Compiler
33
43
 
34
44
  def initialize(controller = nil)
35
45
  @controller = controller
46
+ @shared = {}
36
47
  end
37
48
 
38
49
  # Action names with double underscores (__) are converted
@@ -92,9 +103,11 @@ class Compiler
92
103
 
93
104
  def transform_template(template)
94
105
  template = StaticInclude.transform(template)
95
- template = Morphing.transform(template)
96
- template = Elements.transform(template)
106
+ template = Morphing.transform(template, self)
107
+ # template = LayoutCompiler.transform(template, self)
108
+ template = Elements.transform(template, self)
97
109
  template = Markup.transform(template)
110
+ template = ScriptCompiler.transform(template, self)
98
111
  template = Cleanup.transform(template)
99
112
  template = Template.transform(template)
100
113
  end
@@ -121,10 +134,40 @@ class Compiler
121
134
  end
122
135
  end
123
136
 
124
- # Compiles an action.
137
+ # Compiles an action. The generated action combines the
138
+ # action supplied by the programmer and an optional template
139
+ # in an optimized method to handle the input URI.
125
140
  #
126
141
  # Passes the action name and the parent action name in the
127
142
  # @action_name and @parent_action_name respectively.
143
+ #
144
+ # === Example
145
+ #
146
+ # def my_method
147
+ # template_root/my_method.xhtml
148
+ #
149
+ # are combined in:
150
+ #
151
+ # def my_method_action
152
+ #
153
+ # This generated method is called by the dispatcher.
154
+ #
155
+ # === Template root overloading
156
+ #
157
+ # Nitro provides a nice method of template_root overloading
158
+ # that allows you to use OOP principles with templates.
159
+ # Lets say you have the following controller inheritance.
160
+ #
161
+ # SpecificController < BaseController < Nitro::Controller
162
+ #
163
+ # When the compiler tries to find a template for the
164
+ # SpecificController, it first looks into SC's template root.
165
+ # If no suitable template is found, it looks into
166
+ # BaseController's template_root etc. The final template_root
167
+ # is always the Nitro proto dir (the prototype application).
168
+ # This way you can reuse Controllers and templates and only
169
+ # overriding the templates as required by placing a template
170
+ # with the same name in the more specific template root.
128
171
  #--
129
172
  # TODO: cleanup this method.
130
173
  #++
@@ -9,7 +9,7 @@ module Nitro
9
9
  # A compiler that handles the processing of Elements
10
10
 
11
11
  class Elements # :nodoc: all
12
-
12
+
13
13
  class Listener # :nodoc: all
14
14
  include REXML::StreamListener
15
15
 
@@ -28,21 +28,36 @@ class Elements # :nodoc: all
28
28
  def tag_start(name, attributes)
29
29
  # check if the name starts with the element prefix, or
30
30
  # is capitalized.
31
+
31
32
  if name =~ PREFIX_RE or name =~ CAPITALIZED_RE
32
33
  name = name.split(':')[1].camelize if name =~ PREFIX_RE
33
-
34
- obj = Object.const_get(name).new
35
-
36
- attributes.each do | k, v |
37
- obj.instance_variable_set("@#{k}", v)
38
- end
39
-
40
- @stack.push [obj, @buffer, @parent]
41
-
42
- @buffer = obj._text
43
- @parent.add_child(obj) if @parent
44
-
45
- @parent = obj
34
+
35
+ # First try to use Nitro::Element::xxx then ::xxx
36
+
37
+ if klass = Nitro::Element.const_get(name) || Object.const_get(name)
38
+ unless klass.ancestors.include? Nitro::Element
39
+ if Element.auto_extend
40
+ klass.send(:include, Nitro::ElementMixin)
41
+ else
42
+ Logger.error "Invalid element class '#{name}', does not extend Nitro::Element"
43
+ end
44
+ end
45
+ else
46
+ Logger.error "The class of this element tag '#{name}' does not exist"
47
+ end
48
+
49
+ if klass and obj = klass.new
50
+ attributes.each do | k, v |
51
+ obj.instance_variable_set("@#{k}", v)
52
+ end
53
+
54
+ @stack.push [obj, @buffer, @parent]
55
+
56
+ @buffer = obj._text
57
+ @parent.add_child(obj) if @parent
58
+
59
+ @parent = obj
60
+ end
46
61
  else # This is a static element.
47
62
  attrs = []
48
63
 
@@ -88,19 +103,23 @@ class Elements # :nodoc: all
88
103
  self.new.parse(source)
89
104
  end
90
105
 
91
- def transform(source)
92
- self.new.transform(source)
106
+ def transform(source, compiler)
107
+ self.new.transform(source, compiler)
93
108
  end
94
109
  end
95
110
 
96
111
  # Expand the elemens found in source.
112
+ #--
113
+ # gmosx, FIXME: optimize this, how?
114
+ # gmosx, FIXME: this is a hack fix, improve.
115
+ # TODO:farms why is cleanup called this many times?!?!? ... waste of gsubs
116
+ #++
97
117
 
98
- def transform(source)
118
+ def transform(source, compiler)
99
119
  listener = Listener.new
120
+
100
121
  REXML::Document.parse_stream(source, listener)
101
- # gmosx, FIXME: optimize this, how?
102
- # gmosx, FIXME: this is a hack fix, improve.
103
- # TODO:farms why is cleanup called this many times?!?!? ... waste of gsubs
122
+
104
123
  return listener.buffer
105
124
  end
106
125
  end
@@ -109,6 +128,7 @@ end
109
128
 
110
129
  unless const_defined? :ElementProcessor
111
130
  ElementProcessor = Elements
131
+ ElementCompiler = Elements
112
132
  end
113
133
 
114
134
  end
@@ -0,0 +1,21 @@
1
+ module Nitro
2
+
3
+ # A compiler that handles Rails style simplistic layouts.
4
+ # Perhaps this will be useful for some people that are comming
5
+ # from Rails.
6
+
7
+ class LayoutCompiler # :nodoc: all
8
+
9
+ def self.transform(source, compiler)
10
+ if layout = compiler.controller.ann.self[:layout]
11
+ return "<#{layout}>#{source}</#{layout}>"
12
+ else
13
+ return source
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ # * George Moschovitis <gm@navel.gr>
@@ -1,6 +1,6 @@
1
1
  require 'glue/localization'
2
2
 
3
- module Glue
3
+ module Nitro
4
4
 
5
5
  class Localization
6
6
 
@@ -23,3 +23,5 @@ class Localization
23
23
  end
24
24
 
25
25
  end
26
+
27
+ # * George Moschovitis <gm@navel.gr>
@@ -19,3 +19,5 @@ module Markup
19
19
  end
20
20
 
21
21
  end
22
+
23
+ # * George Moschovitis <gm@navel.gr>
@@ -12,14 +12,19 @@ module Nitro
12
12
 
13
13
  # The base morpher class. Morphers are triggered
14
14
  # by a special 'key' attribute in the xml stream and
15
- # transform the owner element.
15
+ # transform the owner element.
16
+ #
17
+ # key = attribute 'key'
18
+ # name = element name
19
+ # attributes = alement attributes
16
20
 
17
21
  class Morpher
18
- def initialize(key, name, attributes)
22
+ def initialize(key, name, attributes, compiler = nil)
19
23
  @key = key
20
24
  @name = name
21
25
  @attributes = attributes
22
26
  @value = @attributes[@key]
27
+ @compiler = compiler
23
28
  end
24
29
 
25
30
  def before_start(buffer); end
@@ -148,6 +153,12 @@ class Morphing
148
153
  class Listener # :nodoc: all
149
154
  include REXML::StreamListener
150
155
 
156
+ # The compiler that calls this compiling stage. Useful
157
+ # for advanced morphing effects and inter-stage
158
+ # communication.
159
+
160
+ attr_accessor :compiler
161
+
151
162
  attr_accessor :buffer
152
163
 
153
164
  def initialize
@@ -167,7 +178,7 @@ class Morphing
167
178
 
168
179
  Morphing.morphers.each do |key, morpher_class|
169
180
  if attributes.has_key? key
170
- morphers << morpher_class.new(key, name, attributes)
181
+ morphers << morpher_class.new(key, name, attributes, compiler)
171
182
  end
172
183
  end
173
184
 
@@ -214,8 +225,9 @@ class Morphing
214
225
  "</#{name}>"
215
226
  end
216
227
 
217
- def self.transform(source)
228
+ def self.transform(source, compiler = nil)
218
229
  listener = Listener.new
230
+ listener.compiler = compiler
219
231
  REXML::Document.parse_stream(source, listener)
220
232
  return listener.buffer
221
233
  end
@@ -0,0 +1,109 @@
1
+ require 'nano/kernel/constant'
2
+
3
+ require 'nitro/helper/javascript'
4
+
5
+ module Nitro
6
+
7
+ # Generates client-side javascript code.
8
+
9
+ module ScriptCompiler
10
+ extend JavascriptHelper
11
+
12
+ def self.transform(text, compiler)
13
+ begin
14
+ client = constant("#{compiler.controller}::Client")
15
+ rescue Object
16
+ client = nil
17
+ end
18
+
19
+ if client
20
+ client.send :include, Nitro::ScriptGenerator
21
+ client = client.new
22
+
23
+ functions = {}
24
+
25
+ text.scan(/__nc_(.*)\(\)/) do |match|
26
+ functions[match.first] = true
27
+ end
28
+
29
+ script = ''
30
+
31
+ for fun in functions.keys
32
+ begin
33
+ client.buffer = ''
34
+ ret = client.send(fun.to_sym)
35
+
36
+ # the function code is accumulated in the client
37
+ # buffer.
38
+
39
+ function_code = client.buffer
40
+
41
+ # if the client action returs a String append it to
42
+ # the function code.
43
+
44
+ function_code << ret if ret.is_a?(String)
45
+
46
+ script << %{
47
+ function __nc_#{fun}() {
48
+ #{function_code}
49
+ }
50
+ }
51
+ rescue => ex
52
+ Logger.debug ex.inspect if $DBG
53
+ end
54
+ end
55
+
56
+ # Inject css in the head tag.
57
+
58
+ if css_buffer = compiler.shared[:css_buffer]
59
+ text.sub!(/<\/head>/) do |match|
60
+ %{
61
+ <style>
62
+ #{css_buffer}
63
+ </style>
64
+ </head>
65
+ }
66
+ end
67
+ end
68
+
69
+ # Inject required javascript files in the head tag.
70
+
71
+ if required_files = compiler.shared[:js_required_files]
72
+ text.sub!(/<\/head>/) do |match|
73
+ %{
74
+ #{include_script *required_files.keys}
75
+ </head>
76
+ }
77
+ end
78
+ end
79
+
80
+ # Inject javascript just before the end of the
81
+ # template.
82
+ #--
83
+ # gmosx: injection happens at the end, so that the DOM
84
+ # tree is created. Dunno if this is valid xhtml though.
85
+ #++
86
+
87
+ js_buffer = compiler.shared[:js_buffer]
88
+
89
+ if script or js_buffer
90
+ text.sub!(/<\/html>/) do |match|
91
+ %{
92
+ <script type="text/javascript">
93
+ #{script}
94
+ #{js_buffer}
95
+ </script>
96
+ </html>
97
+ }
98
+ end
99
+ end
100
+ end
101
+
102
+ return text
103
+ end
104
+
105
+ end
106
+
107
+ end
108
+
109
+ # * George Moschovitis <gm@navel.gr>