nitro 0.26.0 → 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +312 -0
- data/INSTALL +3 -1
- data/ProjectInfo +6 -9
- data/README +32 -5
- data/Rakefile +5 -1
- data/bin/nitrogen +3 -60
- data/doc/MIGRATION +24 -0
- data/doc/RELEASES +141 -0
- data/doc/lhttpd.txt +3 -0
- data/lib/glue/magick.rb +38 -0
- data/lib/glue/thumbnails.rb +3 -0
- data/lib/glue/webfile.rb +137 -0
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/acgi.rb +235 -0
- data/lib/nitro/adapter/cgi.rb +16 -17
- data/lib/nitro/adapter/scgi.rb +4 -4
- data/lib/nitro/adapter/webrick.rb +9 -2
- data/lib/nitro/cgi.rb +49 -49
- data/lib/nitro/cgi/response.rb +4 -0
- data/lib/nitro/cgi/stream.rb +7 -7
- data/lib/nitro/cgi/utils.rb +2 -1
- data/lib/nitro/compiler.rb +47 -4
- data/lib/nitro/compiler/elements.rb +40 -20
- data/lib/nitro/compiler/layout.rb +21 -0
- data/lib/nitro/compiler/localization.rb +3 -1
- data/lib/nitro/compiler/markup.rb +2 -0
- data/lib/nitro/compiler/morphing.rb +16 -4
- data/lib/nitro/compiler/script.rb +109 -0
- data/lib/nitro/context.rb +10 -10
- data/lib/nitro/dispatcher.rb +4 -2
- data/lib/nitro/element.rb +107 -26
- data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
- data/lib/nitro/flash.rb +4 -1
- data/lib/nitro/helper.rb +15 -0
- data/lib/nitro/helper/benchmark.rb +8 -2
- data/lib/nitro/helper/form.rb +3 -3
- data/lib/nitro/helper/form/controls.rb +131 -29
- data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
- data/lib/nitro/helper/javascript.rb +69 -59
- data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
- data/lib/nitro/helper/javascript/morphing.rb +163 -0
- data/lib/nitro/helper/javascript/prototype.rb +96 -0
- data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
- data/lib/nitro/helper/layout.rb +42 -0
- data/lib/nitro/helper/table.rb +190 -27
- data/lib/nitro/{adapter → helper}/wee.rb +9 -3
- data/lib/nitro/render.rb +23 -17
- data/lib/nitro/scaffolding.rb +19 -2
- data/lib/nitro/server.rb +4 -8
- data/lib/nitro/server/runner.rb +28 -6
- data/lib/nitro/session.rb +7 -7
- data/lib/nitro_and_og.rb +2 -0
- data/proto/public/Makefile.acgi +40 -0
- data/proto/public/acgi.c +138 -0
- data/proto/public/js/builder.js +7 -3
- data/proto/public/js/controls.js +32 -12
- data/proto/public/js/dragdrop.js +4 -3
- data/proto/public/js/effects.js +111 -62
- data/proto/public/js/scriptaculous.js +10 -13
- data/proto/public/js/slider.js +88 -31
- data/proto/public/scaffold/new.xhtml +2 -2
- data/setup.rb +1585 -0
- data/src/part/admin.rb +6 -0
- data/src/part/admin/controller.rb +3 -3
- data/src/part/admin/skin.rb +1 -8
- data/test/nitro/adapter/tc_webrick.rb +2 -0
- data/test/nitro/tc_controller_aspect.rb +1 -1
- data/test/nitro/tc_element.rb +5 -6
- data/test/nitro/tc_table.rb +66 -0
- metadata +277 -271
- data/doc/architecture.txt +0 -2
- data/doc/bugs.txt +0 -15
- data/doc/tutorial.txt +0 -26
- data/install.rb +0 -37
- data/lib/nitro/compiler/script_generator.rb +0 -14
- data/lib/nitro/compiler/shaders.rb +0 -206
- data/lib/nitro/helper/prototype.rb +0 -49
- data/lib/nitro/scaffold/relations.rb +0 -54
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'nano/string/camelize'
|
2
|
+
|
3
|
+
require 'nitro/element'
|
4
|
+
|
5
|
+
module Nitro
|
6
|
+
|
7
|
+
# This helper uses Nitro's powerfull Elements mechanism to
|
8
|
+
# implement a simple Rails style Layout helper. Perhaps this
|
9
|
+
# may be useful for people coming over from Rails.
|
10
|
+
#
|
11
|
+
# WARNING: This is not enabled by default. You have to insert
|
12
|
+
# the LayoutCompiler before the ElementsCompiler for layout to
|
13
|
+
# work.
|
14
|
+
|
15
|
+
module LayoutHelper
|
16
|
+
|
17
|
+
def self.included(base)
|
18
|
+
base.module_eval do
|
19
|
+
# Enclose all templates of this controller with the
|
20
|
+
# given element.
|
21
|
+
|
22
|
+
def self.layout(name = nil)
|
23
|
+
klass = name.to_s.camelize
|
24
|
+
|
25
|
+
unless klass
|
26
|
+
if defined? 'Nitro::Element::Layout'
|
27
|
+
klass = Nitro::Element::Layout
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if klass
|
32
|
+
ann self, :layout => klass
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/helper/table.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'glue/uri'
|
2
|
+
require 'glue/configuration'
|
3
|
+
|
1
4
|
module Nitro
|
2
5
|
|
3
6
|
# The TableBuilder is a helper class that automates the creation
|
@@ -14,11 +17,37 @@ module Nitro
|
|
14
17
|
# <div class="custom-table-class">
|
15
18
|
# #{table :values => users, :headers => header}
|
16
19
|
# </div>
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# === Extended Example
|
23
|
+
#
|
24
|
+
# <?r
|
25
|
+
# users = User.all.map { |u| [u.name, u.first_name, u.last_name, u.email] }
|
26
|
+
# headers = ['Username', 'First name', 'Last name', 'Email']
|
27
|
+
# order_opts = { :right => true, # right align the order controls
|
28
|
+
# :values => [nil, 'first_name', 'last_name'], # column names from DB
|
29
|
+
# :asc_pic => "/images/asc.png",
|
30
|
+
# :desc_pic => "/images/desc.png" }
|
31
|
+
# ?>
|
32
|
+
#
|
33
|
+
# <div class="custom-table-class">
|
34
|
+
# #{table :values => users, :headers => header,
|
35
|
+
# :order => order_opts, :alternating_rows => true }
|
36
|
+
# </div>
|
37
|
+
#
|
17
38
|
#--
|
18
|
-
# TODO:
|
39
|
+
# TODO: legend, verbose... ?
|
19
40
|
#++
|
20
41
|
|
21
42
|
module TableHelper
|
43
|
+
|
44
|
+
# The order by key.
|
45
|
+
|
46
|
+
setting :order_by_key, :default => '_order_by', :doc => 'The order key'
|
47
|
+
|
48
|
+
# The order by key.
|
49
|
+
|
50
|
+
setting :order_direction_key, :default => '_order_direction', :doc => 'The order direction key'
|
22
51
|
|
23
52
|
# [+options+]
|
24
53
|
# A hash of options.
|
@@ -26,55 +55,189 @@ module TableHelper
|
|
26
55
|
# :id = id of the component.
|
27
56
|
# :headers = an array of the header values
|
28
57
|
# :values = an array of arrays.
|
29
|
-
|
58
|
+
# :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
|
59
|
+
# :alternating_rows = alternating rows, use css to color row_even / row_odd
|
60
|
+
# :footers = an array of tfooter values
|
61
|
+
|
30
62
|
def table(options)
|
31
|
-
c = options
|
32
|
-
|
33
63
|
str = '<table'
|
34
|
-
str << %| id="#{
|
64
|
+
str << %| id="#{options[:id]}"| if options[:id]
|
35
65
|
str << '>'
|
36
|
-
|
66
|
+
|
37
67
|
str << table_rows(options)
|
38
68
|
|
39
69
|
str << '</table>'
|
40
70
|
end
|
41
71
|
alias_method :build_table, :table
|
42
|
-
|
72
|
+
|
43
73
|
# [+options+]
|
44
74
|
# A hash of options.
|
45
75
|
#
|
46
76
|
# :id = id of the component.
|
47
77
|
# :headers = an array of the header values
|
48
78
|
# :values = an array of arrays.
|
49
|
-
|
79
|
+
# :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
|
80
|
+
# :alternating_rows = alternating rows, use css to color row_even / row_odd
|
81
|
+
# :footers = an array of tfooter values
|
82
|
+
|
50
83
|
def table_rows(options)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
84
|
+
# also accept :items, :rows
|
85
|
+
options[:values] = options[:values] || options[:items] || options[:rows]
|
86
|
+
|
87
|
+
str = ''
|
88
|
+
str << table_header(options)
|
89
|
+
str << table_footer(options) if options[:footers]
|
90
|
+
|
91
|
+
items = options[:values]
|
92
|
+
|
93
|
+
row_state = 'odd' if options[:alternating_rows]
|
94
|
+
|
95
|
+
# when items is an array of arrays of arrays (meaning, several
|
96
|
+
# arrays deviding the table into several table parts (tbodys))
|
97
|
+
|
98
|
+
if create_tbody?(options)
|
99
|
+
for body in items
|
100
|
+
str << '<tbody>'
|
101
|
+
|
102
|
+
for row in body
|
103
|
+
str << '<tr'
|
104
|
+
|
105
|
+
if options[:alternating_rows]
|
106
|
+
str << %| class="row_#{row_state}"|
|
107
|
+
row_state = (row_state == "odd" ? "even" : "odd")
|
108
|
+
end
|
109
|
+
|
110
|
+
str << '>'
|
111
|
+
|
112
|
+
for value in row
|
113
|
+
str << %|<td>#{value}</td>|
|
114
|
+
end
|
115
|
+
|
116
|
+
str << '</tr>'
|
117
|
+
end
|
118
|
+
|
119
|
+
str << '</tbody>'
|
120
|
+
end
|
121
|
+
else
|
122
|
+
for row in items
|
123
|
+
str << '<tr'
|
124
|
+
|
125
|
+
if options[:alternating_rows]
|
126
|
+
str << %| class="row_#{row_state}"|
|
127
|
+
row_state = (row_state == "odd" ? "even" : "odd")
|
128
|
+
end
|
129
|
+
|
130
|
+
str << '>'
|
131
|
+
|
132
|
+
for value in row
|
133
|
+
str << %|<td>#{value}</td>|
|
134
|
+
end
|
135
|
+
|
136
|
+
str << '</tr>'
|
137
|
+
end
|
57
138
|
end
|
58
|
-
|
59
|
-
str
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
139
|
+
|
140
|
+
return str
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
# [+options+]
|
146
|
+
# A hash of options.
|
147
|
+
#
|
148
|
+
# :id = id of the component.
|
149
|
+
# :headers = an array of the header values
|
150
|
+
# :values = an array of arrays.
|
151
|
+
# :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
|
152
|
+
# :alternating_rows = alternating rows, use css to color row_even / row_odd
|
153
|
+
# :footers = an array of tfooter values
|
154
|
+
|
155
|
+
def table_header(options)
|
156
|
+
str = ''
|
157
|
+
str << '<thead>' if create_tbody?(options) || options[:footers]
|
158
|
+
str << '<tr>'
|
159
|
+
|
160
|
+
options[:headers].each_with_index do |header, index|
|
161
|
+
if (options[:order] && options[:order][:values] &&
|
162
|
+
options[:order][:values][index])
|
163
|
+
order_by = options[:order][:values][index]
|
164
|
+
|
165
|
+
asc_val = if options[:order][:asc_pic]
|
166
|
+
%|<img src="#{options[:order][:asc_pic]}" alt="asc" />|
|
167
|
+
else
|
168
|
+
'^'
|
169
|
+
end
|
170
|
+
desc_val = if options[:order][:desc_pic]
|
171
|
+
%|<img src="#{options[:order][:desc_pic]}" alt="desc" />|
|
172
|
+
else
|
173
|
+
'v'
|
174
|
+
end
|
175
|
+
|
176
|
+
order_asc = "<a href='#{target_uri(order_by, 'ASC')}'>#{asc_val}</a>"
|
177
|
+
order_desc = "<a href='#{target_uri(order_by, 'DESC')}'>#{desc_val}</a>"
|
178
|
+
|
179
|
+
str << '<th><table width="100%" cellspacing="0" cellpadding="0"><tr>'
|
180
|
+
|
181
|
+
if options[:order][:left] || !options[:order][:right]
|
182
|
+
str << "<th>#{order_asc}<br />#{order_desc}</th>"
|
183
|
+
end
|
184
|
+
|
185
|
+
str << %|<th>#{header}</th>|
|
186
|
+
|
187
|
+
if options[:order][:right]
|
188
|
+
str << "<th>#{order_asc}<br />#{order_desc}</th>"
|
189
|
+
end
|
190
|
+
|
191
|
+
str << '</tr></table></th>'
|
192
|
+
else
|
193
|
+
str << %|<th>#{header}</th>|
|
68
194
|
end
|
69
|
-
|
70
|
-
str << "</tr>"
|
71
195
|
end
|
72
|
-
|
196
|
+
|
197
|
+
str << '</tr>'
|
198
|
+
str << '</thead>' if create_tbody?(options) || options[:footers]
|
199
|
+
|
73
200
|
return str
|
74
201
|
end
|
202
|
+
|
203
|
+
# [+options+]
|
204
|
+
# A hash of options.
|
205
|
+
#
|
206
|
+
# :id = id of the component.
|
207
|
+
# :headers = an array of the header values
|
208
|
+
# :values = an array of arrays.
|
209
|
+
# :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
|
210
|
+
# :alternating_rows = alternating rows, use css to color row_even / row_odd
|
211
|
+
# :footers = an array of tfooter values
|
212
|
+
|
213
|
+
def table_footer(options)
|
214
|
+
str = '<tfoot><tr>'
|
215
|
+
|
216
|
+
for footer in options[:footers]
|
217
|
+
str << %|<td>#{footer}</td>|
|
218
|
+
end
|
219
|
+
|
220
|
+
str << '</tr></tfoot>'
|
221
|
+
|
222
|
+
return str
|
223
|
+
end
|
224
|
+
|
225
|
+
# Generate the target URI.
|
226
|
+
|
227
|
+
def target_uri(order_by, direction)
|
228
|
+
params = { TableHelper.order_by_key => order_by,
|
229
|
+
TableHelper.order_direction_key => direction }
|
230
|
+
|
231
|
+
return UriUtils.update_query_string(request.uri.to_s, params)
|
232
|
+
end
|
233
|
+
|
234
|
+
def create_tbody?(options)
|
235
|
+
options[:values][0][0].respond_to?(:to_ary)
|
236
|
+
end
|
75
237
|
|
76
238
|
end
|
77
239
|
|
78
240
|
end
|
79
241
|
|
80
242
|
# * George Moschovitis <gm@navel.gr>
|
243
|
+
# * Kashia Buch <kashia@vfemail.net>
|
@@ -5,7 +5,10 @@ require 'wee/adaptors/nitro'
|
|
5
5
|
|
6
6
|
module Nitro
|
7
7
|
|
8
|
-
|
8
|
+
# Include this mixin to the standard Controller to have easy
|
9
|
+
# access to Wee Components.
|
10
|
+
|
11
|
+
module WeeHelper
|
9
12
|
include Wee::Nitro::ControllerMixin
|
10
13
|
|
11
14
|
# Returns the output of the component.
|
@@ -38,11 +41,14 @@ module WeeMixin
|
|
38
41
|
end
|
39
42
|
end
|
40
43
|
|
41
|
-
|
44
|
+
#--
|
45
|
+
# Add Wee-related helper methods to the default Nitro
|
46
|
+
# controller.
|
47
|
+
#++
|
42
48
|
|
43
49
|
class Controller
|
44
50
|
include Wee::Nitro::ControllerMixin
|
45
|
-
include
|
51
|
+
include WeeHelper
|
46
52
|
end
|
47
53
|
|
48
54
|
end
|
data/lib/nitro/render.rb
CHANGED
@@ -27,7 +27,9 @@ class ActionExit < Exception; end
|
|
27
27
|
|
28
28
|
class RenderExit < Exception; end
|
29
29
|
|
30
|
-
# The output buffer.
|
30
|
+
# The output buffer. The output of a contoller action is
|
31
|
+
# accumulated in this buffer before sending this to the client
|
32
|
+
# as a HTTP Response.
|
31
33
|
#--
|
32
34
|
# TODO: Implement a FAST string (maybe in C)
|
33
35
|
#++
|
@@ -125,18 +127,19 @@ module Render
|
|
125
127
|
klass.new(@context, base).send(action)
|
126
128
|
end
|
127
129
|
|
128
|
-
rescue
|
130
|
+
rescue NoActionError => e1
|
131
|
+
log_error(e1, path, false)
|
132
|
+
print '(error)'
|
129
133
|
|
130
|
-
|
131
|
-
# For example called by redirects.
|
132
|
-
|
133
|
-
rescue Exception, StandardError => e
|
134
|
-
log_error(e, path)
|
134
|
+
rescue RenderExit, ActionExit => e2
|
135
135
|
|
136
|
-
#
|
137
|
-
# error not the full page.
|
136
|
+
# Just stop rendering. For example called by redirects.
|
138
137
|
|
139
|
-
|
138
|
+
rescue Exception, StandardError => e3
|
139
|
+
# More fault tolerant, only flags the erroneous box with
|
140
|
+
# error not the full page.
|
141
|
+
log_error(e3, path)
|
142
|
+
print '(error)'
|
140
143
|
end
|
141
144
|
|
142
145
|
private
|
@@ -191,15 +194,18 @@ private
|
|
191
194
|
|
192
195
|
# Log a rendering error.
|
193
196
|
|
194
|
-
def log_error(error, path)
|
195
|
-
@rendering_errors ||= []
|
196
|
-
@rendering_errors << [error, path]
|
197
|
+
def log_error(error, path, full = true)
|
198
|
+
(@rendering_errors ||= []) << [error, path]
|
197
199
|
|
198
|
-
|
199
|
-
|
200
|
+
if full
|
201
|
+
# gmosx: Hmm perhaps this should not be logged
|
202
|
+
# to avoid DOS attacks.
|
200
203
|
|
201
|
-
|
202
|
-
|
204
|
+
Logger.error "Error while handling '#{path}'."
|
205
|
+
Logger.error pp_exception(error)
|
206
|
+
else
|
207
|
+
Logger.error error.to_s
|
208
|
+
end
|
203
209
|
end
|
204
210
|
|
205
211
|
# Convenience method to lookup the session.
|
data/lib/nitro/scaffolding.rb
CHANGED
@@ -4,6 +4,11 @@ require 'nitro/helper/pager'
|
|
4
4
|
|
5
5
|
module Nitro
|
6
6
|
|
7
|
+
# Scaffolding is a feature of Nitro that automatically generates
|
8
|
+
# maintenance methods for you. It is typically used in the
|
9
|
+
# early stages of development or by the auto administration
|
10
|
+
# part.
|
11
|
+
#
|
7
12
|
# This module is applied to controllers to provide
|
8
13
|
# automatically generated CRUD methods.
|
9
14
|
#--
|
@@ -60,6 +65,10 @@ module Scaffolding
|
|
60
65
|
klass.to_s.demodulize.underscore.downcase
|
61
66
|
end
|
62
67
|
|
68
|
+
#--
|
69
|
+
# A helper that defines a class method.
|
70
|
+
#++
|
71
|
+
|
63
72
|
def define_class_method(meth, code)
|
64
73
|
unless @klass.instance_methods.include?(meth.to_s)
|
65
74
|
@klass.module_eval %{
|
@@ -69,10 +78,18 @@ module Scaffolding
|
|
69
78
|
}
|
70
79
|
end
|
71
80
|
end
|
72
|
-
|
81
|
+
|
82
|
+
#--
|
83
|
+
# A helper that defines a controller action.
|
84
|
+
#++
|
85
|
+
|
73
86
|
def define_controller_action(definition, code, template = nil)
|
74
87
|
sym, args = definition.to_s.split(/\(|\)/)
|
75
88
|
|
89
|
+
# Access Namespace::Klass.action as namespace/klass/action.
|
90
|
+
|
91
|
+
sym.gsub!(/::/, '__')
|
92
|
+
|
76
93
|
if sym == 'index'
|
77
94
|
action = "#{@base__}index"
|
78
95
|
else
|
@@ -167,7 +184,7 @@ module Scaffolding
|
|
167
184
|
# FIXME: investigate save, improve.
|
168
185
|
|
169
186
|
define_controller_action 'save', %{
|
170
|
-
if oid = request
|
187
|
+
if oid = request.fetch('#@oid', nil)
|
171
188
|
oid = oid.to_s # fix StringIO (post).
|
172
189
|
obj = request.fill(@klass[oid], :assign_relations => true, :force_boolean => true, :preprocess => true)
|
173
190
|
else
|