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
File without changes
|
@@ -1,9 +1,58 @@
|
|
1
1
|
require 'nano/inflect'
|
2
2
|
|
3
|
-
require 'nitro/compiler/morphing'
|
4
|
-
|
5
3
|
module Nitro
|
6
4
|
|
5
|
+
# Javascript utilities.
|
6
|
+
|
7
|
+
module JavascriptUtils
|
8
|
+
private
|
9
|
+
# Escape carrier returns and single and double quotes for JavaScript segments.
|
10
|
+
|
11
|
+
def escape_javascript(js)
|
12
|
+
(js || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Converts a Ruby hash to a Javascript hash.
|
16
|
+
|
17
|
+
def hash_to_js(options)
|
18
|
+
'{' + options.map {|k, v| "#{k}:#{v}"}.join(', ') + '}'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Converts the name of a javascript file to the actual
|
22
|
+
# filename. Override if you don't like the defaults.
|
23
|
+
|
24
|
+
def name_to_jsfile(name)
|
25
|
+
"js/#{name}.js"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Generates cliend side javascript.
|
30
|
+
|
31
|
+
module ScriptGenerator
|
32
|
+
include JavascriptUtils
|
33
|
+
|
34
|
+
attr_accessor :buffer
|
35
|
+
|
36
|
+
# Present an alert dialog box.
|
37
|
+
|
38
|
+
def alert(text)
|
39
|
+
js "alert('#{text}');"
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def record(code)
|
45
|
+
@buffer << code
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
alias_method :js, :record
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'nitro/helper/javascript/prototype'
|
53
|
+
require 'nitro/helper/javascript/scriptaculous'
|
54
|
+
require 'nitro/helper/javascript/morphing'
|
55
|
+
|
7
56
|
# A collection of useful Javascript helpers. This modules
|
8
57
|
# integrates helpers for the following javascript libraries:
|
9
58
|
#
|
@@ -12,16 +61,22 @@ module Nitro
|
|
12
61
|
# * effects.js
|
13
62
|
# * dragdrop.js
|
14
63
|
# * controls.js
|
64
|
+
#
|
65
|
+
#--
|
66
|
+
# gmosx: this code is kinda old, will be deprecated soon.
|
67
|
+
#++
|
15
68
|
|
16
69
|
module JavascriptHelper
|
17
|
-
|
18
|
-
|
19
|
-
#
|
70
|
+
include JavascriptUtils
|
71
|
+
|
72
|
+
# Insert an anchor to execute a given function when the link
|
73
|
+
# is followed. Call with the name of the link, and the
|
74
|
+
# function to be called:
|
20
75
|
# link_to_function "Do it." :go
|
21
76
|
|
22
77
|
def link_to_function(name, function)
|
23
78
|
%{<a href="#" onclick="#{function}; return false;">#{name}</a>}
|
24
|
-
end
|
79
|
+
end
|
25
80
|
|
26
81
|
# -- older stuff --
|
27
82
|
|
@@ -37,13 +92,13 @@ module JavascriptHelper
|
|
37
92
|
|
38
93
|
# :section: behaviour.js
|
39
94
|
#
|
40
|
-
# Behaviour.js is a third-party library for keeping HTML clean
|
41
|
-
# The +behaviour+ method provides an interface
|
42
|
-
# To learn more about the concept, visit the
|
43
|
-
# http://bennolan.com/behaviour/
|
95
|
+
# Behaviour.js is a third-party library for keeping HTML clean
|
96
|
+
# of javascript. The +behaviour+ method provides an interface
|
97
|
+
# to that library. To learn more about the concept, visit the
|
98
|
+
# distributor: http://bennolan.com/behaviour/
|
44
99
|
|
45
|
-
# Register javascript code with an HTML element of a given id
|
46
|
-
# +behaviour+ method.
|
100
|
+
# Register javascript code with an HTML element of a given id
|
101
|
+
# with the +behaviour+ method.
|
47
102
|
#
|
48
103
|
# Example:
|
49
104
|
#
|
@@ -266,32 +321,16 @@ module JavascriptHelper
|
|
266
321
|
# HEAD. Add other script files as arguments if desired.
|
267
322
|
|
268
323
|
def include_script(*files)
|
269
|
-
return
|
324
|
+
return nil if files.empty?
|
270
325
|
|
271
326
|
code = ''
|
272
327
|
|
273
328
|
for file in files
|
274
|
-
code << %|<script src="#{file}" type="text/javascript">//</script>\n|
|
329
|
+
code << %|<script src="#{name_to_jsfile(file)}" type="text/javascript">//</script>\n|
|
275
330
|
end if files
|
276
331
|
|
277
|
-
for file in @_script_files
|
278
|
-
code << %|<script src="#{file}" type="text/javascript">//</script>\n|
|
279
|
-
end if @_script_files
|
280
|
-
|
281
332
|
return code
|
282
333
|
end
|
283
|
-
|
284
|
-
# Escape carrier returns and single and double quotes for JavaScript segments.
|
285
|
-
|
286
|
-
def escape_javascript(js)
|
287
|
-
(js || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
|
288
|
-
end
|
289
|
-
|
290
|
-
# Converts a Ruby hash to a Javascript hash.
|
291
|
-
|
292
|
-
def hash_to_js(options)
|
293
|
-
'{' + options.map {|k, v| "#{k}:#{v}"}.join(', ') + '}'
|
294
|
-
end
|
295
334
|
|
296
335
|
# Emits the aggregated css.
|
297
336
|
|
@@ -358,35 +397,6 @@ module JavascriptHelper
|
|
358
397
|
|
359
398
|
end
|
360
399
|
|
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
|
-
|
390
400
|
end
|
391
401
|
|
392
402
|
# * George Moschovitis <gm@navel.gr>
|
File without changes
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'mega/dictionary'
|
2
|
+
|
3
|
+
require 'nitro/compiler/morphing'
|
4
|
+
|
5
|
+
# Javascript related morphers.
|
6
|
+
|
7
|
+
module Nitro
|
8
|
+
|
9
|
+
#--
|
10
|
+
# A useful superclass for morphers. Provides easy access to
|
11
|
+
# js/css shared buffers.
|
12
|
+
#++
|
13
|
+
|
14
|
+
class SharedMorpher < Morpher # :nodoc: all
|
15
|
+
include JavascriptUtils
|
16
|
+
|
17
|
+
# Record javascript to be injected in the template.
|
18
|
+
|
19
|
+
def record_js(code)
|
20
|
+
(@compiler.shared[:js_buffer] ||= '') << code
|
21
|
+
end
|
22
|
+
alias_method :js, :record_js
|
23
|
+
|
24
|
+
# Record css to be injected in the template.
|
25
|
+
|
26
|
+
def record_css(css)
|
27
|
+
(@compiler.shared[:css_buffer] ||= '') << css
|
28
|
+
end
|
29
|
+
alias_method :css, :record_css
|
30
|
+
|
31
|
+
# Require javascript files.
|
32
|
+
|
33
|
+
def require_script_file(*names)
|
34
|
+
files = (@compiler.shared[:js_required_files] ||= Dictionary.new)
|
35
|
+
for name in names
|
36
|
+
files[name] = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
alias_method :add_script_file, :require_script_file
|
40
|
+
end
|
41
|
+
|
42
|
+
# Transform a normal achor into an asynchronous request:
|
43
|
+
# <a href="..." async="true">...</a>
|
44
|
+
# becomes
|
45
|
+
# <a href="#" onclick="new Ajax.Request...; return false;">...</a>
|
46
|
+
|
47
|
+
class AsyncMorpher < SharedMorpher
|
48
|
+
def before_start(buffer)
|
49
|
+
require_script_file :prototype
|
50
|
+
|
51
|
+
href = @attributes['href']
|
52
|
+
@attributes['href'] = '#'
|
53
|
+
@attributes['onclick'] = "new Ajax.Request('#{href}'); return false;"
|
54
|
+
@attributes.delete(@key)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Transform script attributes.
|
59
|
+
#
|
60
|
+
# <form script="action">...
|
61
|
+
# becomes
|
62
|
+
# <form onsubmit="action(); return false">...
|
63
|
+
#
|
64
|
+
# <a script="action">..</a>
|
65
|
+
# becomes
|
66
|
+
# <a href="#" onclick="action(); return false">...</a>
|
67
|
+
|
68
|
+
class ScriptMorpher < SharedMorpher
|
69
|
+
def before_start(buffer)
|
70
|
+
require_script_file :prototype
|
71
|
+
|
72
|
+
case @name
|
73
|
+
when 'form'
|
74
|
+
@attributes['onsubmit'] = "#@value(); return false"
|
75
|
+
else
|
76
|
+
@attributes['href'] = '#'
|
77
|
+
@attributes['onclick'] = "#@value(); return false"
|
78
|
+
end
|
79
|
+
@attributes.delete(@key)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Transform client attributes. '__nc_' marks Nitro generated
|
84
|
+
# javascript functions.
|
85
|
+
#
|
86
|
+
# <form client="action">...
|
87
|
+
# becomes
|
88
|
+
# <form onsubmit="__nc_action(); return false">...
|
89
|
+
#
|
90
|
+
# <a client="action">..</a>
|
91
|
+
# becomes
|
92
|
+
# <a href="#" onclick="__nc_action(); return false">...</a>
|
93
|
+
|
94
|
+
class ClientMorpher < SharedMorpher
|
95
|
+
def before_start(buffer)
|
96
|
+
require_script_file :prototype, :effects
|
97
|
+
|
98
|
+
case @name
|
99
|
+
when 'form'
|
100
|
+
@attributes['onsubmit'] = "__nc_#@value(); return false"
|
101
|
+
else
|
102
|
+
@attributes['href'] = '#'
|
103
|
+
@attributes['onclick'] = "__nc_#@value(); return false"
|
104
|
+
end
|
105
|
+
@attributes.delete(@key)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Makes a DOM element draggable.
|
110
|
+
|
111
|
+
class DraggableMorpher < SharedMorpher
|
112
|
+
def before_start(buffer)
|
113
|
+
require_script_file :prototype, :effects, :dragdrop
|
114
|
+
|
115
|
+
id = @attributes['id'] || @attributes['name']
|
116
|
+
options = @attributes['drag_options'] || ''
|
117
|
+
js "new Draggable('#{id}', #{hash_to_js(options)});"
|
118
|
+
|
119
|
+
@attributes.delete(@key)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Adds auto-complete functionality to a standard input field.
|
124
|
+
#
|
125
|
+
# === Example
|
126
|
+
#
|
127
|
+
# <input type="text" id="myfield" name="myfield" auto_complete="true" />
|
128
|
+
#
|
129
|
+
# You need to provide the autocomplete values by means of a
|
130
|
+
# custom action: {field_id}_auto_complete. The method should
|
131
|
+
# return a <ul> list. In this example:
|
132
|
+
#
|
133
|
+
# def myfield_auto_complete
|
134
|
+
# %{<ul><li>....</ul>}
|
135
|
+
|
136
|
+
class AutoCompleteMorpher < SharedMorpher
|
137
|
+
def before_start(buffer)
|
138
|
+
require_script_file :prototype, :effects, :controls
|
139
|
+
|
140
|
+
id = @id = @attributes['id'] || @attributes['name']
|
141
|
+
update = @attributes['auto_complete_update'] || "#{id}_auto_complete"
|
142
|
+
url = @attributes['auto_complete_url'] || "#{id}_auto_complete"
|
143
|
+
js "new Ajax.Autocompleter('#{id}', '#{update}', '#{url}');"
|
144
|
+
|
145
|
+
@attributes.delete(@key)
|
146
|
+
end
|
147
|
+
|
148
|
+
def after_end(buffer)
|
149
|
+
buffer << %|<div id="#{@id}_auto_complete" class="auto_complete"> </div>|
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Install the morphers.
|
154
|
+
|
155
|
+
Morphing.add_morpher :async, AsyncMorpher
|
156
|
+
Morphing.add_morpher :script, ScriptMorpher
|
157
|
+
Morphing.add_morpher :client, ClientMorpher
|
158
|
+
Morphing.add_morpher :auto_complete, AutoCompleteMorpher
|
159
|
+
Morphing.add_morpher :draggable, DraggableMorpher
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Nitro
|
2
|
+
|
3
|
+
# Add Prototype methods to the ScriptGenerator.
|
4
|
+
# Prototype.js is a third-party library that provides a number
|
5
|
+
# of functions for AJAX-style interaction with the browser.
|
6
|
+
# Prototype's homepage is http://prototype.conio.net/
|
7
|
+
|
8
|
+
module ScriptGenerator
|
9
|
+
|
10
|
+
# html = A string or a symbol to an action for rendering.
|
11
|
+
#--
|
12
|
+
# TODO: resolve html.
|
13
|
+
#++
|
14
|
+
|
15
|
+
def insert_html(id, html, options = {})
|
16
|
+
position = options.fetch(:where, :before)
|
17
|
+
js "new Insertion.#{position.to_s.camelize}('#{id}', '#{html}');"
|
18
|
+
end
|
19
|
+
|
20
|
+
def replace_html(id, html, options = {})
|
21
|
+
js "Element.update('#{id}', '#{html}');"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Hide a DOM element.
|
25
|
+
|
26
|
+
def hide(id)
|
27
|
+
js "$('#{id}').style.display = 'none';"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Show a DOM element.
|
31
|
+
|
32
|
+
def show(id)
|
33
|
+
js "$('#{id}').style.display = 'block';"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Toggle a DOM element.
|
37
|
+
|
38
|
+
def toggle(id)
|
39
|
+
js "Element.toggle('#{id}');"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Perform an ajax, async update.
|
43
|
+
|
44
|
+
def ajax_update(id, options = {})
|
45
|
+
code = %~
|
46
|
+
new Ajax.Updater(
|
47
|
+
{ success: '#{id}' },
|
48
|
+
'#{options[:action] || options[:url]}',
|
49
|
+
{
|
50
|
+
method: '#{options.fetch(:method, :post)}',
|
51
|
+
parameters: #{options[:params] || options[:parameters]},
|
52
|
+
~
|
53
|
+
|
54
|
+
if before = options[:before]
|
55
|
+
if before.is_a? Proc
|
56
|
+
old_buffer = @buffer
|
57
|
+
@buffer = ''
|
58
|
+
before.call
|
59
|
+
before = @buffer
|
60
|
+
@buffer = old_buffer + @buffer
|
61
|
+
end
|
62
|
+
code << %~
|
63
|
+
onLoading: function(request) {
|
64
|
+
#{before}
|
65
|
+
},
|
66
|
+
~
|
67
|
+
end
|
68
|
+
|
69
|
+
if success = options[:success]
|
70
|
+
if success.is_a? Proc
|
71
|
+
old_buffer = @buffer
|
72
|
+
@buffer = ''
|
73
|
+
success.call
|
74
|
+
success = @buffer
|
75
|
+
@buffer = old_buffer
|
76
|
+
end
|
77
|
+
code << %~
|
78
|
+
onComplete: function(request) {
|
79
|
+
#{success}
|
80
|
+
}
|
81
|
+
~
|
82
|
+
end
|
83
|
+
|
84
|
+
code << %~
|
85
|
+
}
|
86
|
+
);
|
87
|
+
~
|
88
|
+
|
89
|
+
js(code)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nitro
|
2
|
+
|
3
|
+
# Add Scriptaculous methods to the ScriptGenerator.
|
4
|
+
|
5
|
+
module ScriptGenerator
|
6
|
+
|
7
|
+
def visual_effect(name, id = false, options = {})
|
8
|
+
element = id ? "'#{id}'" : "element"
|
9
|
+
options[:queue] = "'#{options[:queue]}'" if options[:queue]
|
10
|
+
js "new Effect.#{name.to_s.camelize}(#{element}, #{hash_to_js(options)});"
|
11
|
+
end
|
12
|
+
alias_method :effect, :visual_effect
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# * George Moschovitis <gm@navel.gr>
|