nitro 0.25.0 → 0.26.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 +531 -1
- data/ProjectInfo +29 -5
- data/README +1 -1
- data/doc/AUTHORS +12 -6
- data/doc/RELEASES +114 -0
- data/lib/glue/sweeper.rb +71 -0
- data/lib/nitro.rb +19 -12
- data/lib/nitro/adapter/cgi.rb +4 -0
- data/lib/nitro/adapter/webrick.rb +4 -2
- data/lib/nitro/caching.rb +1 -0
- data/lib/nitro/caching/fragments.rb +7 -1
- data/lib/nitro/caching/output.rb +6 -1
- data/lib/nitro/caching/stores.rb +13 -1
- data/lib/nitro/cgi.rb +9 -1
- data/lib/nitro/cgi/request.rb +11 -3
- data/lib/nitro/cgi/utils.rb +24 -2
- data/lib/nitro/compiler.rb +89 -63
- data/lib/nitro/compiler/cleanup.rb +16 -0
- data/lib/nitro/compiler/elements.rb +117 -0
- data/lib/nitro/compiler/markup.rb +3 -1
- data/lib/nitro/compiler/morphing.rb +203 -73
- data/lib/nitro/compiler/script_generator.rb +14 -0
- data/lib/nitro/compiler/shaders.rb +1 -1
- data/lib/nitro/context.rb +5 -6
- data/lib/nitro/controller.rb +43 -21
- data/lib/nitro/dispatcher.rb +86 -37
- data/lib/nitro/element.rb +3 -105
- data/lib/nitro/helper/benchmark.rb +3 -0
- data/lib/nitro/helper/dojo.rb +0 -0
- data/lib/nitro/helper/form.rb +85 -255
- data/lib/nitro/helper/form/controls.rb +274 -0
- data/lib/nitro/helper/javascript.rb +86 -6
- data/lib/nitro/helper/pager.rb +5 -0
- data/lib/nitro/helper/prototype.rb +49 -0
- data/lib/nitro/helper/scriptaculous.rb +0 -0
- data/lib/nitro/helper/xhtml.rb +11 -8
- data/lib/nitro/helper/xml.rb +1 -1
- data/lib/nitro/routing.rb +8 -1
- data/lib/nitro/scaffolding.rb +344 -0
- data/lib/nitro/server.rb +5 -1
- data/lib/nitro/server/runner.rb +19 -15
- data/lib/nitro/session.rb +32 -56
- data/lib/nitro/session/drbserver.rb +1 -1
- data/lib/nitro/session/file.rb +34 -15
- data/lib/nitro/session/memory.rb +13 -4
- data/lib/nitro/session/og.rb +56 -0
- data/proto/public/js/controls.js +30 -1
- data/proto/public/js/dragdrop.js +211 -146
- data/proto/public/js/effects.js +261 -399
- data/proto/public/js/prototype.js +131 -72
- data/proto/public/scaffold/edit.xhtml +10 -3
- data/proto/public/scaffold/form.xhtml +1 -7
- data/proto/public/scaffold/index.xhtml +20 -0
- data/proto/public/scaffold/list.xhtml +15 -8
- data/proto/public/scaffold/new.xhtml +10 -3
- data/proto/public/scaffold/search.xhtml +28 -0
- data/proto/public/scaffold/view.xhtml +8 -0
- data/proto/run.rb +93 -1
- data/src/part/admin.rb +4 -2
- data/src/part/admin/controller.rb +62 -28
- data/src/part/admin/skin.rb +8 -8
- data/src/part/admin/system.css +135 -0
- data/src/part/admin/template/index.xhtml +8 -12
- data/test/nitro/caching/tc_stores.rb +17 -0
- data/test/nitro/tc_caching.rb +1 -4
- data/test/nitro/tc_dispatcher.rb +22 -10
- data/test/nitro/tc_element.rb +1 -1
- data/test/nitro/tc_session.rb +23 -11
- data/test/public/blog/another/very_litle/index.xhtml +1 -0
- metadata +29 -15
- data/lib/nitro/dispatcher/general.rb +0 -62
- data/lib/nitro/dispatcher/nice.rb +0 -57
- data/lib/nitro/scaffold.rb +0 -171
- data/proto/public/index.xhtml +0 -83
- data/proto/public/js/scaffold.js +0 -74
- data/proto/public/settings.xhtml +0 -66
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
require 'nitro/helper/xhtml'
|
|
2
|
+
|
|
3
|
+
module Nitro
|
|
4
|
+
|
|
5
|
+
# :section: Property controls.
|
|
6
|
+
|
|
7
|
+
# A Form control.
|
|
8
|
+
|
|
9
|
+
class Control
|
|
10
|
+
include Nitro::XhtmlHelper
|
|
11
|
+
|
|
12
|
+
# Fetch the instance vars in a nice way use either rel
|
|
13
|
+
# or prop.
|
|
14
|
+
#
|
|
15
|
+
# values/value contain the contents of the prop or rel,
|
|
16
|
+
# (values reads better for relations)
|
|
17
|
+
|
|
18
|
+
attr_reader :prop
|
|
19
|
+
alias_method :rel, :prop
|
|
20
|
+
|
|
21
|
+
attr_reader :obj
|
|
22
|
+
|
|
23
|
+
attr_reader :value
|
|
24
|
+
alias_method :values, :value
|
|
25
|
+
|
|
26
|
+
# setup instance vars to use in methods
|
|
27
|
+
|
|
28
|
+
def initialize(obj, key, value=nil)
|
|
29
|
+
@obj = obj
|
|
30
|
+
@prop = key
|
|
31
|
+
@value = value || obj.send(key.name.to_sym)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Main bulk of the control. Overide to customise
|
|
35
|
+
|
|
36
|
+
def render
|
|
37
|
+
"No view for this control"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Label item. Override to customise
|
|
41
|
+
|
|
42
|
+
def label
|
|
43
|
+
%{<label for="#{prop.name}">#{prop[:title] || prop.name.to_s.humanize}</label>}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Custom callback to process the request information
|
|
47
|
+
# posted back from the form
|
|
48
|
+
#
|
|
49
|
+
# When Property.populate_object (or fill) is called
|
|
50
|
+
# with the :preprocess => true option then this
|
|
51
|
+
# method will get called before the value is pushed
|
|
52
|
+
# onto the object that is getting 'filled'
|
|
53
|
+
#
|
|
54
|
+
# Overide this on controls that require special mods
|
|
55
|
+
# to the incoming values
|
|
56
|
+
|
|
57
|
+
def on_populate(val)
|
|
58
|
+
puts "PREPROCESSING !"
|
|
59
|
+
return val
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def emit_style
|
|
65
|
+
if prop.respond_to?(:control_style)
|
|
66
|
+
style = prop.control_style
|
|
67
|
+
elsif self.class.respond_to?(:style)
|
|
68
|
+
style = self.class.style
|
|
69
|
+
else
|
|
70
|
+
style = nil
|
|
71
|
+
end
|
|
72
|
+
style ? %{ style="#{style}"} : ''
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Fixnum
|
|
78
|
+
|
|
79
|
+
class FixnumControl < Control
|
|
80
|
+
setting :style, :default => 'width: 100px', :doc => 'The default style'
|
|
81
|
+
|
|
82
|
+
def render
|
|
83
|
+
style = prop.control_style ||self.class.style
|
|
84
|
+
%{<input type="text" id="#{prop.symbol}_ctl" name="#{prop.symbol}" value="#{value}"#{emit_style} /> + -}
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Float
|
|
89
|
+
|
|
90
|
+
class FloatControl < Control
|
|
91
|
+
setting :style, :default => 'width: 100px', :doc => 'The default style'
|
|
92
|
+
|
|
93
|
+
def render
|
|
94
|
+
style = prop.control_style ||self.class.style
|
|
95
|
+
%{<input type="text" id="#{prop.symbol}_ctl" name="#{prop.symbol}" value="#{value}"#{emit_style} /> + -}
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Text
|
|
100
|
+
|
|
101
|
+
class TextControl < Control
|
|
102
|
+
setting :style, :default => 'width: 250px', :doc => 'The default style'
|
|
103
|
+
|
|
104
|
+
def render
|
|
105
|
+
%{<input type="text" id="#{prop.symbol}_ctl" name="#{prop.symbol}" value="#{value}"#{emit_style} />}
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Textarea
|
|
110
|
+
|
|
111
|
+
class TextareaControl < Control
|
|
112
|
+
setting :style, :default => 'width: 500px; height: 100px', :doc => 'The default style'
|
|
113
|
+
|
|
114
|
+
def render
|
|
115
|
+
%{<textarea id="#{prop.symbol}_ctl" name="#{prop.symbol}"#{emit_style}>#{value}</textarea>}
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# CheckboxControl < Control
|
|
120
|
+
|
|
121
|
+
class CheckboxControl < Control
|
|
122
|
+
setting :style, :default => '', :doc => 'The default style'
|
|
123
|
+
|
|
124
|
+
def render
|
|
125
|
+
checked = value == true ? ' checked="checked"':''
|
|
126
|
+
%{<input type="checkbox" id="#{prop.symbol}_ctl" name="#{prop.symbol}" value="true"#{emit_style}#{checked} />}
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# :section: Relation controls.
|
|
131
|
+
|
|
132
|
+
# RefersTo. Also used for BelongsTo.
|
|
133
|
+
|
|
134
|
+
class RefersToControl < Control
|
|
135
|
+
def render
|
|
136
|
+
objs = rel.target_class.all
|
|
137
|
+
if selected = value
|
|
138
|
+
selected = selected.pk
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
str = %{<select id="#{rel.name}_ctl" name="#{rel.name}">}
|
|
142
|
+
str << %{<option value="nil">None</option>}
|
|
143
|
+
str << %{#{options(:labels => objs.map{|o| o.to_s}, :values => objs.map{|o| o.pk}, :selected => selected)}</select>}
|
|
144
|
+
|
|
145
|
+
return str
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# HasMany, ManyToMany and JoinsMany
|
|
150
|
+
|
|
151
|
+
class HasManyControl < Control
|
|
152
|
+
|
|
153
|
+
#pre :do_this, :on => :populate_object
|
|
154
|
+
|
|
155
|
+
def render
|
|
156
|
+
str = emit_container_start
|
|
157
|
+
str << emit_js
|
|
158
|
+
if selected_items.empty?
|
|
159
|
+
str << emit_selector(all_items, :removable => false)
|
|
160
|
+
else
|
|
161
|
+
removable = selected_items.size != 1 ? true : false
|
|
162
|
+
selected_items.each do |item|
|
|
163
|
+
str << emit_selector(all_items, :selected => item.pk)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
str << emit_container_end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
private
|
|
170
|
+
|
|
171
|
+
# these parts are seperated from render to make it easier
|
|
172
|
+
# to extend and customise the HasManyControl
|
|
173
|
+
|
|
174
|
+
def all_items
|
|
175
|
+
rel.target_class.all
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def selected_items
|
|
179
|
+
values
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def emit_container_start
|
|
183
|
+
%{<div class="many_to_many_container">}
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def emit_container_end
|
|
187
|
+
%{</div>}
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# :removable controls wether the minus button is active
|
|
191
|
+
# :selected denotes the oid to flag as selected in the list
|
|
192
|
+
|
|
193
|
+
def emit_selector(items, options={})
|
|
194
|
+
removable = options.fetch(:removable, true)
|
|
195
|
+
%{
|
|
196
|
+
<div>
|
|
197
|
+
<select class="has_many_ctl" name="#{rel.name}[]" #{emit_style}>
|
|
198
|
+
<option value="nil">None</option>
|
|
199
|
+
#{options(:labels => items.map{|o| o.to_s}, :values => items.map{|o| o.pk}, :selected => options[:selected])}
|
|
200
|
+
</select>
|
|
201
|
+
<input type="button" class="#{rel.name}_remove_btn" value=" - " onclick="rm_#{rel.name}_rel(this);" #{'disabled="disabled"' unless removable} />
|
|
202
|
+
<input type="button" class="#{rel.name}_add_btn" value=" + " onclick="add_#{rel.name}_rel(this);" />
|
|
203
|
+
</div>
|
|
204
|
+
}
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Inline script: override this to change behavior
|
|
208
|
+
|
|
209
|
+
def emit_js
|
|
210
|
+
%{
|
|
211
|
+
<script type="text/javascript">
|
|
212
|
+
rm_#{rel.name}_rel = function(el){
|
|
213
|
+
ctl=el.parentNode;
|
|
214
|
+
container=ctl.parentNode;
|
|
215
|
+
container.removeChild(ctl);
|
|
216
|
+
inputTags = container.getElementsByTagName('input');
|
|
217
|
+
if(inputTags.length==2)
|
|
218
|
+
inputTags[0].disabled='disabled';
|
|
219
|
+
}
|
|
220
|
+
add_#{rel.name}_rel = function(el){
|
|
221
|
+
ctl=el.parentNode;
|
|
222
|
+
container=ctl.parentNode;
|
|
223
|
+
node=ctl.cloneNode(true);
|
|
224
|
+
node.getElementsByTagName('input')[0].removeAttribute('disabled');
|
|
225
|
+
if(container.lastChild==ctl) container.appendChild(node);
|
|
226
|
+
else container.insertBefore(node, ctl.nextSibling);
|
|
227
|
+
if(container.childNodes.length>1) container.getElementsByTagName('input')[0].disabled='';
|
|
228
|
+
}
|
|
229
|
+
</script>
|
|
230
|
+
}
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# The controls map.
|
|
235
|
+
|
|
236
|
+
class Control
|
|
237
|
+
|
|
238
|
+
# Setup the mapping of names => control classes
|
|
239
|
+
|
|
240
|
+
setting :map, :doc => 'Mappings of control names => classes', :default => {
|
|
241
|
+
:fixnum => FixnumControl,
|
|
242
|
+
:float => FloatControl,
|
|
243
|
+
:boolean => CheckboxControl,
|
|
244
|
+
:checkbox => CheckboxControl,
|
|
245
|
+
:string => TextControl,
|
|
246
|
+
:textarea => TextareaControl,
|
|
247
|
+
:true_class => CheckboxControl,
|
|
248
|
+
:refers_to => RefersToControl,
|
|
249
|
+
:belongs_to => RefersToControl,
|
|
250
|
+
:has_many => HasManyControl,
|
|
251
|
+
:many_to_many => HasManyControl,
|
|
252
|
+
:joins_many => HasManyControl
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# Fetch a control, setup for 'obj' for a property, or relation
|
|
256
|
+
# or :symbol defaults to Control if not found
|
|
257
|
+
|
|
258
|
+
def self.fetch(obj, key, missing=self)
|
|
259
|
+
if key.kind_of? Og::Relation
|
|
260
|
+
control_sym = key[:control] || key.class.to_s.demodulize.underscore.to_sym
|
|
261
|
+
elsif key.kind_of? Property
|
|
262
|
+
control_sym = key[:control] || key.klass.to_s.underscore.to_sym
|
|
263
|
+
else
|
|
264
|
+
control_sym = key.to_sym
|
|
265
|
+
end
|
|
266
|
+
self.map.fetch(control_sym, missing).new(obj, key)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# * George Moschovitis <gm@navel.gr>
|
|
274
|
+
# * Chris Farmiloe <chris.farmiloe@farmiloe.com>
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
require 'nano/inflect'
|
|
2
|
+
|
|
3
|
+
require 'nitro/compiler/morphing'
|
|
4
|
+
|
|
1
5
|
module Nitro
|
|
2
6
|
|
|
3
7
|
# A collection of useful Javascript helpers. This modules
|
|
@@ -11,7 +15,15 @@ module Nitro
|
|
|
11
15
|
|
|
12
16
|
module JavascriptHelper
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
# Insert an anchor to execute a given function when the link is followed.
|
|
19
|
+
# Call with the name of the link, and the function to be called:
|
|
20
|
+
# link_to_function "Do it." :go
|
|
21
|
+
|
|
22
|
+
def link_to_function(name, function)
|
|
23
|
+
%{<a href="#" onclick="#{function}; return false;">#{name}</a>}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# -- older stuff --
|
|
15
27
|
|
|
16
28
|
unless const_defined? :DEFAULT_JAVASCRIPT_FILES
|
|
17
29
|
DEFAULT_JAVASCRIPT_FILES = [
|
|
@@ -24,7 +36,23 @@ private
|
|
|
24
36
|
end
|
|
25
37
|
|
|
26
38
|
# :section: behaviour.js
|
|
39
|
+
#
|
|
40
|
+
# Behaviour.js is a third-party library for keeping HTML clean of javascript.
|
|
41
|
+
# The +behaviour+ method provides an interface to that library.
|
|
42
|
+
# To learn more about the concept, visit the distributor:
|
|
43
|
+
# http://bennolan.com/behaviour/
|
|
27
44
|
|
|
45
|
+
# Register javascript code with an HTML element of a given id with the
|
|
46
|
+
# +behaviour+ method.
|
|
47
|
+
#
|
|
48
|
+
# Example:
|
|
49
|
+
#
|
|
50
|
+
# behaviour '#alert', %{
|
|
51
|
+
# el.onclick = function() {
|
|
52
|
+
# alert('Hello world');
|
|
53
|
+
# }
|
|
54
|
+
# }
|
|
55
|
+
|
|
28
56
|
def behaviour(id, js)
|
|
29
57
|
@_behaviours ||= []
|
|
30
58
|
@_behaviours << [id, js]
|
|
@@ -32,6 +60,24 @@ private
|
|
|
32
60
|
end
|
|
33
61
|
|
|
34
62
|
# :section: prototype.js
|
|
63
|
+
#
|
|
64
|
+
# Prototype.js is a third-party library that provides a number of functions
|
|
65
|
+
# for AJAX-style interaction with the browser. It depends on the Behaviour.js
|
|
66
|
+
# library. Prototype's homepage is http://prototype.conio.net/
|
|
67
|
+
|
|
68
|
+
# A live, or asynchronous, request is one that does not bring the user to a
|
|
69
|
+
# new page. It is used to send data back to the web server while the user is
|
|
70
|
+
# still interacting with a document.
|
|
71
|
+
#
|
|
72
|
+
# Call +live+ with the id of an achor element as a string or a symbol.
|
|
73
|
+
# Alternatively, add <tt>async="true"</tt> to the anchor (A) element. Specify the
|
|
74
|
+
# anchor to be called either as a second parameter to the +live+ method, or
|
|
75
|
+
# in the HREF option of the anchor element.
|
|
76
|
+
#
|
|
77
|
+
# Examples:
|
|
78
|
+
#
|
|
79
|
+
# live :id_of_anchor_element [:method]
|
|
80
|
+
# <a href="receiver" async="true">Go!</a>
|
|
35
81
|
|
|
36
82
|
def live_request(id, options = {})
|
|
37
83
|
__append_script_file__ 'js/behaviour.js'
|
|
@@ -57,7 +103,8 @@ private
|
|
|
57
103
|
alias_method :live, :live_request
|
|
58
104
|
alias_method :async, :live_request
|
|
59
105
|
|
|
60
|
-
#
|
|
106
|
+
# Clicking the element will make it disappear. If you want it to reappear,
|
|
107
|
+
# you'll have to call <tt>toggle()</tt>.
|
|
61
108
|
|
|
62
109
|
def toggleable(id, options = {})
|
|
63
110
|
__append_script_file__ 'js/prototype.js'
|
|
@@ -74,7 +121,7 @@ private
|
|
|
74
121
|
|
|
75
122
|
# :section: script.aculo.us dragdrop.js
|
|
76
123
|
|
|
77
|
-
#
|
|
124
|
+
# The user may click and drag the element about the screen.
|
|
78
125
|
|
|
79
126
|
def draggable(id, options = {})
|
|
80
127
|
__append_script_file__ 'js/behaviour.js'
|
|
@@ -215,7 +262,8 @@ private
|
|
|
215
262
|
# -----------------------------------------------------------
|
|
216
263
|
# :section: general javascript helpers.
|
|
217
264
|
|
|
218
|
-
#
|
|
265
|
+
# Inserts links to the .js files necessary for your page. Call it from within
|
|
266
|
+
# HEAD. Add other script files as arguments if desired.
|
|
219
267
|
|
|
220
268
|
def include_script(*files)
|
|
221
269
|
return if @_script_files.nil? and files.empty?
|
|
@@ -253,13 +301,15 @@ private
|
|
|
253
301
|
end
|
|
254
302
|
alias_method :helper_css, :emit_css
|
|
255
303
|
|
|
256
|
-
#
|
|
304
|
+
# Call this in your template/page to include the javascript statements that
|
|
305
|
+
# link your HTML to the javascript libraries. Must be called after the HTML
|
|
306
|
+
# elements involved, i.e., at the bottom of the page.
|
|
257
307
|
#--
|
|
258
308
|
# FIXME: refactor this!
|
|
259
309
|
#++
|
|
260
310
|
|
|
261
311
|
def emit_script
|
|
262
|
-
code = %|<script type="text/javascript">\n|
|
|
312
|
+
code = %|<script type="text/javascript">\n<!--\n|
|
|
263
313
|
unless @_behaviours.empty?
|
|
264
314
|
code << %|var _behaviours = {\n|
|
|
265
315
|
compo = []
|
|
@@ -276,6 +326,7 @@ private
|
|
|
276
326
|
#{@_script.join("\n")}
|
|
277
327
|
| if @_script
|
|
278
328
|
code << %|
|
|
329
|
+
//-->
|
|
279
330
|
</script>
|
|
280
331
|
|
|
|
281
332
|
end
|
|
@@ -307,6 +358,35 @@ private
|
|
|
307
358
|
|
|
308
359
|
end
|
|
309
360
|
|
|
361
|
+
# :section: Javascript related morphers.
|
|
362
|
+
|
|
363
|
+
# Transform a normal achor into an asynchronous request:
|
|
364
|
+
# <a href="..." async="true">...</a>
|
|
365
|
+
# becomes
|
|
366
|
+
# <a href="#" onclick="new Ajax.Request...; return false;">...</a>
|
|
367
|
+
|
|
368
|
+
class AsyncMorpher < Morpher
|
|
369
|
+
def before_start(buffer)
|
|
370
|
+
href = @attributes['href']
|
|
371
|
+
@attributes['href'] = '#'
|
|
372
|
+
@attributes['onclick'] = "new Ajax.Request('#{href}'); return false;"
|
|
373
|
+
@attributes.delete(@key)
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
class LocalMorpher < Morpher
|
|
378
|
+
def before_start(buffer)
|
|
379
|
+
@attributes['href'] = '#'
|
|
380
|
+
@attributes['onclick'] = "ngs#{@value.camelcase(true)}();"
|
|
381
|
+
@attributes.delete(@key)
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Install the morphers.
|
|
386
|
+
|
|
387
|
+
Morphing.add_morpher :async, AsyncMorpher
|
|
388
|
+
Morphing.add_morpher :local, LocalMorpher
|
|
389
|
+
|
|
310
390
|
end
|
|
311
391
|
|
|
312
392
|
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/helper/pager.rb
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Nitro
|
|
2
|
+
|
|
3
|
+
module PrototypeHelper
|
|
4
|
+
|
|
5
|
+
def remote_function()
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
#--
|
|
9
|
+
# TODO: resolve html
|
|
10
|
+
#++
|
|
11
|
+
|
|
12
|
+
class JavascriptGenerator
|
|
13
|
+
attr_accessor :buffer
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@buffer = ''
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# html = A string or a symbol to an action for rendering.
|
|
20
|
+
#--
|
|
21
|
+
# TODO: resolve html.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
def insert_html(id, html, options = {})
|
|
25
|
+
position = options.fetch(:where, :before)
|
|
26
|
+
record "new Insertion.#{position.to_s.camelize}(#{id.inspect}, #{html.inspect})"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def replace_html(id, html, options = {})
|
|
30
|
+
record "Element.update(#{id.inspect}, #{html.inspect})"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def record(code)
|
|
36
|
+
code = "#{line.to_s.chomp.gsub /\;$/, ''};"
|
|
37
|
+
@buffer << code
|
|
38
|
+
return code
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# * George Moschovitis <gm@navel.gr>
|