nitro 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +175 -0
- data/README +41 -7
- data/RELEASES +24 -0
- data/Rakefile +5 -7
- data/bin/new_app.rb +26 -4
- data/bin/new_form.rb +54 -0
- data/bin/proto/config.rb +3 -3
- data/bin/proto/root/index.xhtml +2 -34
- data/bin/proto/root/style.css +4 -70
- data/bin/proto/root/style.xsl +8 -39
- data/doc/tutorial.txt +5 -0
- data/examples/blog/app.rb +2 -1
- data/examples/blog/config.rb +7 -2
- data/examples/blog/root/style.xsl +1 -2
- data/examples/flash/README +34 -0
- data/examples/flash/app.rb +20 -0
- data/examples/flash/config.rb +38 -0
- data/examples/flash/lib/flash.rb +40 -0
- data/examples/flash/root/index.xhtml +25 -0
- data/examples/flash/root/show_inline_text.xhtml +12 -0
- data/examples/flash/tmp.swf +0 -0
- data/examples/og/README +7 -0
- data/examples/og/mock_example.rb +58 -0
- data/examples/og/run.rb +9 -5
- data/examples/tiny/root/include.xhtml +3 -0
- data/examples/tiny/root/index.xhtml +2 -1
- data/lib/glue/property.rb +166 -107
- data/lib/glue/property.rb.old +307 -0
- data/lib/nitro/builders/form.rb +26 -17
- data/lib/nitro/events.rb +1 -1
- data/lib/nitro/markup.rb +120 -0
- data/lib/nitro/server/cookie.rb +1 -1
- data/lib/nitro/server/dispatcher.rb +5 -6
- data/lib/nitro/server/filters.rb +1 -1
- data/lib/nitro/server/render.rb +33 -29
- data/lib/nitro/server/shaders.rb +32 -3
- data/lib/nitro/server/user.rb +1 -1
- data/lib/nitro/server/webrick.rb +9 -4
- data/lib/nitro/ui/popup.rb +1 -1
- data/lib/nitro/ui/select.rb +1 -1
- data/lib/nitro/ui/tabs.rb +1 -1
- data/lib/nitro/version.rb +2 -2
- data/lib/og.rb +17 -6
- data/lib/og/backend.rb +34 -4
- data/lib/og/backends/mysql.rb +3 -17
- data/lib/og/backends/psql.rb +5 -17
- data/lib/og/meta.rb +41 -26
- data/lib/og/mock.rb +223 -0
- data/lib/og/version.rb +2 -2
- data/lib/parts/content.rb +61 -0
- data/test/glue/{tc_properties.rb → tc_property.rb} +0 -1
- data/test/glue/tc_property_mixins.rb +62 -0
- data/test/og/tc_lifecycle.rb +107 -0
- data/test/tc_og.rb +31 -4
- data/vendor/README +6 -0
- data/vendor/binding_of_caller.rb +81 -0
- data/vendor/breakpoint.rb +526 -0
- data/vendor/breakpoint_client.rb +157 -0
- metadata +135 -95
@@ -0,0 +1,307 @@
|
|
1
|
+
# code:
|
2
|
+
# * George Moschovitis <gm@navel.gr>
|
3
|
+
# design:
|
4
|
+
# * Anastastios Koutoumanos <ak@navel.gr>
|
5
|
+
# * Elias Karakoulakis <ekarak@ktismata.com>
|
6
|
+
#
|
7
|
+
# (c) 2004 Navel, all rights reserved.
|
8
|
+
# $Id: property.rb 185 2004-12-10 13:29:09Z gmosx $
|
9
|
+
|
10
|
+
require "glue/array"
|
11
|
+
require "glue/hash"
|
12
|
+
|
13
|
+
module G
|
14
|
+
|
15
|
+
# = Property
|
16
|
+
#
|
17
|
+
# Ruby attributes are typeless and generally this is good. Some times
|
18
|
+
# we need extra metadata though, for example in relational mapping,
|
19
|
+
# or web form population.
|
20
|
+
#
|
21
|
+
# Only Fixnums, Strings, Floats, Times, Booleans are converted.
|
22
|
+
#
|
23
|
+
# The default = methods do not force the types. A special
|
24
|
+
# __force_set method should be used instead.
|
25
|
+
#
|
26
|
+
#--
|
27
|
+
# TODO:
|
28
|
+
# Inject only the really needd methods into Module.
|
29
|
+
# Perhaps a sync is needed in evals (!!!!)
|
30
|
+
#++
|
31
|
+
#
|
32
|
+
class Property
|
33
|
+
# the symbol of the property
|
34
|
+
attr_accessor :symbol
|
35
|
+
# the string representation of the symbol
|
36
|
+
attr_accessor :name
|
37
|
+
# the class of the property
|
38
|
+
attr_accessor :klass
|
39
|
+
# additional metadata (like sql declaratio, sql index, etc)
|
40
|
+
attr_accessor :meta
|
41
|
+
|
42
|
+
def initialize(symbol, klass, meta = {})
|
43
|
+
@symbol, @klass = symbol, klass
|
44
|
+
@meta = meta
|
45
|
+
@name = @symbol.to_s()
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(other)
|
49
|
+
return @symbol == other.symbol
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
return name
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end # module
|
58
|
+
|
59
|
+
class Module
|
60
|
+
|
61
|
+
# Define a property (== typed attribute)
|
62
|
+
# This works like Ruby's standard attr method, ie creates
|
63
|
+
# only one property.
|
64
|
+
#
|
65
|
+
# Use the prop_reader, prop_writer, prop_accessor methods
|
66
|
+
# for multiple properties.
|
67
|
+
#
|
68
|
+
# Examples:
|
69
|
+
# prop String, :name, :sql => "char(32), :sql_index => "name(32)"
|
70
|
+
# --> creates only writer.
|
71
|
+
# prop Fixnum, :oid, writer = true, :sql => "integer PRIMARY KEY"
|
72
|
+
# --> creates reader and writer.
|
73
|
+
#
|
74
|
+
def prop(*params)
|
75
|
+
meta = {}
|
76
|
+
klass = Object
|
77
|
+
|
78
|
+
for param in params
|
79
|
+
if param.is_a?(Class)
|
80
|
+
klass = param
|
81
|
+
elsif param.is_a?(Symbol)
|
82
|
+
symbol = param
|
83
|
+
elsif param.is_a?(TrueClass) or param.is_a?(TrueClass)
|
84
|
+
writer = param
|
85
|
+
elsif param.is_a?(Hash)
|
86
|
+
# the meta hash.
|
87
|
+
meta = param
|
88
|
+
else
|
89
|
+
raise "Error when defining property!"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
unless self.methods.include?(:__props)
|
94
|
+
eval %{
|
95
|
+
# Properties
|
96
|
+
# An array is used to enforce order.
|
97
|
+
def __props
|
98
|
+
@__props
|
99
|
+
end
|
100
|
+
|
101
|
+
def __props=(props)
|
102
|
+
@__props = props
|
103
|
+
end
|
104
|
+
|
105
|
+
def __meta
|
106
|
+
@__meta
|
107
|
+
end
|
108
|
+
|
109
|
+
def __meta=(meta)
|
110
|
+
@__meta = meta
|
111
|
+
end
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
@__props = G::SafeArray.new() unless @__props
|
116
|
+
|
117
|
+
property = G::Property.new(symbol, klass, meta)
|
118
|
+
|
119
|
+
reader = meta[:reader] || true
|
120
|
+
writer = writer || meta[:writer] || false
|
121
|
+
|
122
|
+
__add_prop(property, reader, writer)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Helper method. Accepts a collection of symbols and generates
|
126
|
+
# properties. Only generates reader.
|
127
|
+
#
|
128
|
+
# Example:
|
129
|
+
# prop_reader String, :name, :title, :body, :sql => "char(32)"
|
130
|
+
#
|
131
|
+
def prop_reader(*params)
|
132
|
+
meta = {}
|
133
|
+
klass = Object
|
134
|
+
symbols = []
|
135
|
+
|
136
|
+
for param in params
|
137
|
+
if param.is_a?(Class)
|
138
|
+
klass = param
|
139
|
+
elsif param.is_a?(Symbol)
|
140
|
+
symbols << param
|
141
|
+
elsif param.is_a?(Hash)
|
142
|
+
# the meta hash.
|
143
|
+
meta = param
|
144
|
+
else
|
145
|
+
raise "Error when defining property!"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
meta[:reader] = true
|
150
|
+
meta[:writer] = false
|
151
|
+
|
152
|
+
for symbol in symbols
|
153
|
+
prop(klass, symbol, meta)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Helper method. Accepts a collection of symbols and generates
|
158
|
+
# properties. Only generates writer.
|
159
|
+
#
|
160
|
+
# Example:
|
161
|
+
# prop_writer String, :name, :title, :body, :sql => "char(32)"
|
162
|
+
#
|
163
|
+
def prop_writer(*params)
|
164
|
+
meta = {}
|
165
|
+
klass = Object
|
166
|
+
symbols = []
|
167
|
+
|
168
|
+
for param in params
|
169
|
+
if param.is_a?(Class)
|
170
|
+
klass = param
|
171
|
+
elsif param.is_a?(Symbol)
|
172
|
+
symbols << param
|
173
|
+
elsif param.is_a?(Hash)
|
174
|
+
# the meta hash.
|
175
|
+
meta = param
|
176
|
+
else
|
177
|
+
raise "Error when defining property!"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
meta[:reader] = false
|
182
|
+
meta[:writer] = true
|
183
|
+
|
184
|
+
for symbol in symbols
|
185
|
+
prop(klass, symbol, meta)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Helper method. Accepts a collection of symbols and generates
|
190
|
+
# properties. Generates reader and writer.
|
191
|
+
#
|
192
|
+
# Example:
|
193
|
+
# prop_accessor String, :name, :title, :body, :sql => "char(32)"
|
194
|
+
#
|
195
|
+
def prop_accessor(*params)
|
196
|
+
meta = {}
|
197
|
+
klass = Object
|
198
|
+
symbols = []
|
199
|
+
|
200
|
+
for param in params
|
201
|
+
if param.is_a?(Class)
|
202
|
+
klass = param
|
203
|
+
elsif param.is_a?(Symbol)
|
204
|
+
symbols << param
|
205
|
+
elsif param.is_a?(Hash)
|
206
|
+
# the meta hash.
|
207
|
+
meta = param
|
208
|
+
else
|
209
|
+
raise "Error when defining property!"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
meta[:reader] = true
|
214
|
+
meta[:writer] = true
|
215
|
+
|
216
|
+
for symbol in symbols
|
217
|
+
prop(klass, symbol, meta)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# Add the property
|
222
|
+
#
|
223
|
+
def __add_prop(prop, reader = true, writer = true)
|
224
|
+
if idx = @__props.index(prop)
|
225
|
+
# override in case of duplicates. Keep the order of the props.
|
226
|
+
@__props[idx] = prop
|
227
|
+
else
|
228
|
+
@__props << prop
|
229
|
+
end
|
230
|
+
|
231
|
+
# Precompile the property read/write methods
|
232
|
+
|
233
|
+
s, klass = prop.symbol, prop.klass
|
234
|
+
|
235
|
+
if reader
|
236
|
+
module_eval %{
|
237
|
+
def #{s}
|
238
|
+
return @#{s}
|
239
|
+
end
|
240
|
+
}
|
241
|
+
end
|
242
|
+
|
243
|
+
# gmosx: __force_xxx reuses xxx= to allow for easier
|
244
|
+
# overrides.
|
245
|
+
if writer
|
246
|
+
module_eval %{
|
247
|
+
def #{s}=(val)
|
248
|
+
@#{s} = val
|
249
|
+
end
|
250
|
+
|
251
|
+
def __force_#{s}(val)
|
252
|
+
self.#{s}=(} + case klass.name
|
253
|
+
when Fixnum.name
|
254
|
+
"val.to_i()"
|
255
|
+
when String.name
|
256
|
+
"val.to_s()"
|
257
|
+
when Float.name
|
258
|
+
"val.to_f()"
|
259
|
+
when Time.name
|
260
|
+
"Time.parse(val.to_s())"
|
261
|
+
when TrueClass.name, FalseClass.name
|
262
|
+
"val.to_i() > 0"
|
263
|
+
else
|
264
|
+
"val"
|
265
|
+
end + %{)
|
266
|
+
end
|
267
|
+
}
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Attach metadata
|
272
|
+
#
|
273
|
+
def meta(key, val)
|
274
|
+
@__meta = G::SafeHash.new unless @__meta
|
275
|
+
|
276
|
+
@__meta[key] = [] unless @__meta[key]
|
277
|
+
|
278
|
+
# guard against duplicates, no need to keep order.
|
279
|
+
@__meta[key].delete_if { |v| val == v }
|
280
|
+
@__meta[key] << val
|
281
|
+
end
|
282
|
+
|
283
|
+
# This method is typically called before including other
|
284
|
+
# modules to preserve properties order.
|
285
|
+
#
|
286
|
+
def inherit_meta(mod = superclass)
|
287
|
+
# concat props.
|
288
|
+
if mod.__props
|
289
|
+
@__props = G::SafeArray.new unless @__props
|
290
|
+
|
291
|
+
mod.__props.each { |p|
|
292
|
+
__add_prop(p)
|
293
|
+
}
|
294
|
+
end
|
295
|
+
|
296
|
+
# concat metadata
|
297
|
+
if mod.__meta
|
298
|
+
mod.__meta.each { |k, val|
|
299
|
+
val.each { |v|
|
300
|
+
meta(k, v)
|
301
|
+
} if val
|
302
|
+
}
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
data/lib/nitro/builders/form.rb
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
#
|
4
4
|
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id: form.rb
|
5
|
+
# $Id: form.rb 200 2004-12-27 11:24:41Z gmosx $
|
6
|
+
|
7
|
+
require 'glue/hash'
|
8
|
+
require 'nitro/markup'
|
6
9
|
|
7
10
|
module N
|
8
11
|
|
@@ -10,7 +13,7 @@ module N
|
|
10
13
|
#
|
11
14
|
class FormBuilder
|
12
15
|
|
13
|
-
@@
|
16
|
+
@@cache = G::SafeHash.new
|
14
17
|
|
15
18
|
# Render a standard form for the given managed object.
|
16
19
|
# If show_all is false then apply field filtering.
|
@@ -34,34 +37,39 @@ class FormBuilder
|
|
34
37
|
if p.klass.ancestors.include?(Integer) or
|
35
38
|
p.klass.ancestors.include?(Float)
|
36
39
|
str << %{
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
<dt><label for="#{p.name}">#{p.name}</label></dt>
|
41
|
+
<dd>
|
42
|
+
<input type="text" name="#{p.name}" value="#{obj.send(p.symbol)}" />
|
43
|
+
</dd>
|
41
44
|
}
|
42
45
|
elsif p.klass.ancestors.include?(String)
|
43
46
|
str << %{
|
44
|
-
|
45
|
-
|
47
|
+
<dt><label for="#{p.name}">#{p.name}</label></dt>
|
48
|
+
<dd>
|
46
49
|
}
|
47
|
-
if
|
50
|
+
if p.meta[:markup]
|
51
|
+
val = N::Markup.compact(obj.send(p.symbol))
|
52
|
+
else
|
53
|
+
val = obj.send(p.symbol)
|
54
|
+
end
|
55
|
+
if :textarea == p.meta[:ui]
|
48
56
|
str << %{
|
49
|
-
|
57
|
+
<textarea name="#{p.name}">#{val}</textarea>
|
50
58
|
}
|
51
59
|
else
|
52
60
|
str << %{
|
53
|
-
|
61
|
+
<input type="text" name="#{p.name}" value="#{val}" />
|
54
62
|
}
|
55
63
|
end
|
56
64
|
str << %{
|
57
|
-
|
65
|
+
</dd>
|
58
66
|
}
|
59
67
|
elsif p.klass.ancestors.include?(TrueClass)
|
60
68
|
str << %{
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
69
|
+
<dt><label for="#{p.name}">#{p.name}</label></dt>
|
70
|
+
<dd>
|
71
|
+
<input type="checkbox" name="${p.name}" />
|
72
|
+
</dd>
|
65
73
|
}
|
66
74
|
=begin
|
67
75
|
elsif p.klass.ancestors.include?(Time)
|
@@ -74,7 +82,8 @@ class FormBuilder
|
|
74
82
|
end
|
75
83
|
end
|
76
84
|
|
77
|
-
str <<
|
85
|
+
str << %{
|
86
|
+
</dl>}
|
78
87
|
|
79
88
|
return str
|
80
89
|
end
|
data/lib/nitro/events.rb
CHANGED
data/lib/nitro/markup.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# code:
|
2
|
+
# * George Moschovitis <gm@navel.gr>
|
3
|
+
#
|
4
|
+
# (c) 2004 Navel, all rights reserved.
|
5
|
+
# $Id$
|
6
|
+
|
7
|
+
require 'glue/property'
|
8
|
+
|
9
|
+
module G
|
10
|
+
|
11
|
+
#--
|
12
|
+
# Override the default PropertyUtils implementation to
|
13
|
+
# add markup support.
|
14
|
+
#++
|
15
|
+
module PropertyUtils
|
16
|
+
# Override to add markup code.
|
17
|
+
#
|
18
|
+
def self.prop_setter(prop)
|
19
|
+
s = prop.symbol
|
20
|
+
if markup = prop.meta[:markup]
|
21
|
+
# if true, set to default Markup
|
22
|
+
markup = N::Markup if true == markup
|
23
|
+
|
24
|
+
return %{
|
25
|
+
def #{s}=(val)
|
26
|
+
@#{s} = #{markup}.expand(val)
|
27
|
+
end
|
28
|
+
|
29
|
+
def compact_#{s}
|
30
|
+
#{markup}.compact(@#{s})
|
31
|
+
end
|
32
|
+
}
|
33
|
+
else
|
34
|
+
return %{
|
35
|
+
def #{s}=(val)
|
36
|
+
@#{s} = val
|
37
|
+
end
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end # module
|
44
|
+
|
45
|
+
module N
|
46
|
+
|
47
|
+
# = Markup
|
48
|
+
#
|
49
|
+
# Generalised Markup transformations.
|
50
|
+
#
|
51
|
+
# The expand methods evaluate (expand) the markup
|
52
|
+
# code to produce the final content. The compact
|
53
|
+
# methods reverse this process to create the original
|
54
|
+
# markup code. Not all markup transformations are
|
55
|
+
# reversible.
|
56
|
+
#
|
57
|
+
# When this library is included, the default PropertyUtils
|
58
|
+
# implementation is overriden to add markup support.
|
59
|
+
#
|
60
|
+
# === Examples
|
61
|
+
#
|
62
|
+
# here comes the #{obj.body} # => prints the expanded version.
|
63
|
+
#
|
64
|
+
# obj.body = N::Markup.expand(@params['body'])
|
65
|
+
#
|
66
|
+
module Markup
|
67
|
+
def self.expand_html!(str)
|
68
|
+
return unless str
|
69
|
+
str.gsub!(/"/, '"')
|
70
|
+
str.gsub!(/'/, ''')
|
71
|
+
str.gsub!(/\r\n/, ' <br />')
|
72
|
+
return str
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.compact_html!(str)
|
76
|
+
return unless str
|
77
|
+
str.gsub!(/"/, '"')
|
78
|
+
str.gsub!(/'/, "'")
|
79
|
+
# gmosx: SOS! double quotes ARE needed for \r\n!!
|
80
|
+
str.gsub!(/\s<br \/>/, "\r\n")
|
81
|
+
return str
|
82
|
+
end
|
83
|
+
|
84
|
+
# Expand the markup code to produce the
|
85
|
+
# actual content.
|
86
|
+
#
|
87
|
+
def self.expand(str)
|
88
|
+
if str
|
89
|
+
xstr = str.dup
|
90
|
+
expand_html!(xstr)
|
91
|
+
expand_wiki!(xstr)
|
92
|
+
return xstr
|
93
|
+
else
|
94
|
+
return str
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Compact (reverse) the content to the origial markup
|
99
|
+
# code. Not all markup transformations are reversible.
|
100
|
+
#
|
101
|
+
def self.compact(str)
|
102
|
+
if str
|
103
|
+
xstr = str.dup
|
104
|
+
compact_html!(xstr)
|
105
|
+
compact_wiki!(xstr)
|
106
|
+
return xstr
|
107
|
+
else
|
108
|
+
return str
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Remove markup code from the input string.
|
113
|
+
# NOT IMPLEMENTED.
|
114
|
+
#
|
115
|
+
def self.clear(str)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end # module
|