nitro 0.6.0 → 0.7.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.
- 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
|