nitro 0.19.0 → 0.20.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 +187 -0
- data/INSTALL +5 -0
- data/README +11 -5
- data/doc/AUTHORS +11 -1
- data/doc/RELEASES +217 -0
- data/doc/tutorial.txt +1 -2
- data/lib/nitro.rb +9 -6
- data/lib/nitro/adapter/webrick.rb +13 -2
- data/lib/nitro/builder/form.rb +11 -9
- data/lib/nitro/builder/rss.rb +2 -2
- data/lib/nitro/builder/xhtml.rb +15 -0
- data/lib/nitro/caching.rb +15 -10
- data/lib/nitro/conf.rb +0 -5
- data/lib/nitro/controller.rb +118 -81
- data/lib/nitro/cookie.rb +6 -6
- data/lib/nitro/dispatcher.rb +62 -18
- data/lib/nitro/element.rb +4 -1
- data/lib/nitro/element/java_script.rb +15 -0
- data/lib/nitro/localization.rb +3 -4
- data/lib/nitro/markup.rb +4 -4
- data/lib/nitro/mixin/debug.rb +30 -0
- data/lib/nitro/mixin/helper.rb +14 -0
- data/lib/nitro/mixin/javascript.rb +137 -0
- data/lib/nitro/{ui → mixin}/pager.rb +110 -82
- data/lib/nitro/render.rb +20 -8
- data/lib/nitro/request.rb +6 -0
- data/lib/nitro/routing.rb +6 -5
- data/lib/nitro/runner.rb +21 -9
- data/lib/nitro/server.rb +95 -0
- data/lib/nitro/service.rb +0 -1
- data/lib/nitro/session.rb +4 -5
- data/lib/nitro/shaders.rb +2 -2
- data/lib/nitro/template.rb +1 -1
- data/lib/nitro/testing/assertions.rb +2 -4
- data/lib/nitro/testing/context.rb +4 -6
- data/proto/public/js/behaviour.js +254 -0
- data/proto/public/js/controls.js +446 -0
- data/proto/public/js/dragdrop.js +537 -0
- data/proto/public/js/effects.js +612 -0
- data/proto/public/js/prototype.js +644 -370
- data/proto/public/settings.xhtml +64 -0
- data/test/nitro/adapter/tc_cgi.rb +2 -2
- data/test/nitro/builder/tc_rss.rb +1 -1
- data/test/nitro/mixin/tc_pager.rb +35 -0
- data/test/nitro/tc_controller.rb +1 -1
- data/test/nitro/tc_cookie.rb +14 -0
- data/test/nitro/tc_dispatcher.rb +11 -6
- data/test/nitro/tc_server.rb +35 -0
- metadata +20 -15
- data/lib/nitro/builder/atom.rb +0 -74
- data/lib/nitro/part.rb +0 -22
- data/lib/nitro/simple.rb +0 -11
- data/lib/nitro/ui/popup.rb +0 -41
- data/lib/nitro/ui/tabs.rb +0 -25
- data/lib/nitro/uri.rb +0 -193
- data/test/nitro/builder/tc_atom.rb +0 -24
- data/test/nitro/tc_uri.rb +0 -97
- data/test/nitro/ui/tc_pager.rb +0 -49
data/lib/nitro/simple.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'nitro/controller'
|
2
|
-
|
3
|
-
# A simple controller, only handles templates.
|
4
|
-
# Useful to implement php/asp/jsp style applications.
|
5
|
-
# Dispatcher uses this as the default Controller.
|
6
|
-
#--
|
7
|
-
# gmosx, FIXME: this is a nasty hack, remove!
|
8
|
-
#++
|
9
|
-
|
10
|
-
class SimpleController < Nitro::Controller;
|
11
|
-
end
|
data/lib/nitro/ui/popup.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: popup.rb 1 2005-04-11 11:04:30Z gmosx $
|
4
|
-
|
5
|
-
module Nitro
|
6
|
-
|
7
|
-
# Display a popup window.
|
8
|
-
|
9
|
-
class Popup
|
10
|
-
|
11
|
-
# Emit the needed javascript.
|
12
|
-
# Alternatively use this code: <script src="/r/js/std.js">#{}</script>
|
13
|
-
|
14
|
-
def self.script
|
15
|
-
%[
|
16
|
-
function newWin(url, name, w, h, scroll) {
|
17
|
-
var pleft = (screen.width - w) / 2;
|
18
|
-
var ptop = (screen.height - h) / 2;
|
19
|
-
var settings = 'height=' + h + ',width=' + w + ',top=' + ptop + ',left=' + pleft + ',scrollbars=' + scroll + ',resizable';
|
20
|
-
|
21
|
-
win = window.open(url, name, settings);
|
22
|
-
|
23
|
-
return false;
|
24
|
-
}
|
25
|
-
]
|
26
|
-
end
|
27
|
-
|
28
|
-
# gmosx: keep the leading / to be IE friendly.
|
29
|
-
|
30
|
-
def self.onclick(uri, width, height, title = "Popup", type="PAGE", options = "scrollbars=yes,resizable", container = "/p/glue/popup.sx")
|
31
|
-
%[javascript: var pwl = (screen.width - #{width}) / 2; var pwt = (screen.height - #{height}) / 2; window.open('#{container}?uri=#{uri};type=#{type}', '#{title}', 'width=#{width},height=#{height},top='+pwt+',left='+pwl+', #{options}'); return false"]
|
32
|
-
end
|
33
|
-
|
34
|
-
# gmosx: keep the leading / to be IE friendly.
|
35
|
-
|
36
|
-
def self.link(uri, width, height, link = "link", title = "Popup", type="PAGE", options = "scrollbars=yes,resizable", container = "/p/glue/popup.sx")
|
37
|
-
%[<a href="#" onclick="#{self.onclick(uri, width, height, title, type, options, container)}">#{link}</a>]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
data/lib/nitro/ui/tabs.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: tabs.rb 1 2005-04-11 11:04:30Z gmosx $
|
4
|
-
|
5
|
-
module Nitro
|
6
|
-
|
7
|
-
# Render a tabs bar
|
8
|
-
|
9
|
-
def self.tabs(request, options, param)
|
10
|
-
tabs = []
|
11
|
-
|
12
|
-
selected = request.get(param, 0)
|
13
|
-
|
14
|
-
options.each_with_index { |opt, idx|
|
15
|
-
if idx == selected
|
16
|
-
tabs << %|<strong>#{opt}</strong>|
|
17
|
-
else
|
18
|
-
tabs << %|<a href="#{request.expand_uri(param => idx)}">#{opt}</a>|
|
19
|
-
end
|
20
|
-
}
|
21
|
-
|
22
|
-
return %|<div class="tabs">#{tabs.join('<span class="sep">|</span>')}</div>|
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
data/lib/nitro/uri.rb
DELETED
@@ -1,193 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: uri.rb 1 2005-04-11 11:04:30Z gmosx $
|
4
|
-
|
5
|
-
require 'uri'
|
6
|
-
require 'cgi'
|
7
|
-
|
8
|
-
require 'glue/string'
|
9
|
-
|
10
|
-
module Nitro
|
11
|
-
|
12
|
-
# URI utilities collection.
|
13
|
-
#
|
14
|
-
# === Design
|
15
|
-
#
|
16
|
-
# Implement as a module to avoid class polution. You can still
|
17
|
-
# use Ruby's advanced features to include the module in your
|
18
|
-
# class. Passing the object to act upon allows to check for nil,
|
19
|
-
# which isn't possible if you use self.
|
20
|
-
#
|
21
|
-
# The uris passed as parameters are typically strings.
|
22
|
-
#--
|
23
|
-
# gmosx, TODO: deprecate this.
|
24
|
-
#++
|
25
|
-
|
26
|
-
module UriUtils
|
27
|
-
|
28
|
-
# Decode the uri components.
|
29
|
-
|
30
|
-
def self.decode(uri)
|
31
|
-
# gmosx: hmm is this needed?
|
32
|
-
# guard against invalid filenames for example pictures with
|
33
|
-
# spaces uploaded by users
|
34
|
-
escaped_uri = uri.gsub(/ /, "+")
|
35
|
-
|
36
|
-
if md = URI::REGEXP::REL_URI.match(escaped_uri)
|
37
|
-
|
38
|
-
path = "#{md[5]}#{md[6]}"
|
39
|
-
type = File.extname(path)
|
40
|
-
query_string = md[7]
|
41
|
-
|
42
|
-
# real_path = "#{$root_dir}/#{path}"
|
43
|
-
|
44
|
-
parameters = UriUtils.query_string_to_hash(query_string)
|
45
|
-
path.gsub!(/\+/, " ")
|
46
|
-
|
47
|
-
return [path, type, parameters, query_string]
|
48
|
-
|
49
|
-
end # match
|
50
|
-
|
51
|
-
# this is usefull for uncovering bugs!
|
52
|
-
raise ArgumentError.new("the parameter '#{uri}' is not a valid uri")
|
53
|
-
end
|
54
|
-
|
55
|
-
# Extend the basic query string parser provided by the cgi module.
|
56
|
-
# converts single valued params (the most common case) to
|
57
|
-
# objects instead of arrays
|
58
|
-
#
|
59
|
-
# Input:
|
60
|
-
# the query string
|
61
|
-
#
|
62
|
-
# Output:
|
63
|
-
# hash of parameters, contains arrays for multivalued parameters
|
64
|
-
# (multiselect, checkboxes , etc)
|
65
|
-
# If no query string is provided (nil or "") returns an empty hash.
|
66
|
-
|
67
|
-
def self.query_string_to_hash(query_string)
|
68
|
-
return {} unless query_string
|
69
|
-
|
70
|
-
query_parameters = CGI::parse(query_string)
|
71
|
-
|
72
|
-
query_parameters.each { |key, val|
|
73
|
-
# replace the array with an object
|
74
|
-
query_parameters[key] = val[0] if 1 == val.length
|
75
|
-
}
|
76
|
-
|
77
|
-
# set default value to nil! cgi sets this to []
|
78
|
-
query_parameters.default = nil
|
79
|
-
|
80
|
-
return query_parameters
|
81
|
-
end
|
82
|
-
|
83
|
-
# Given a hash with parameter/value pairs construct a
|
84
|
-
# standard query string. This method only encodes simple
|
85
|
-
# types (Numeric, String) to avoid query string polution
|
86
|
-
# with marshal, etc.
|
87
|
-
#
|
88
|
-
# gmosx, FIXME: only numeric and strings are passed to
|
89
|
-
# the latest code, so update old code and optimize this!
|
90
|
-
#
|
91
|
-
# Input:
|
92
|
-
# the parameter hash
|
93
|
-
#
|
94
|
-
# Output:
|
95
|
-
# the query string
|
96
|
-
|
97
|
-
def self.hash_to_query_string(parameters)
|
98
|
-
return nil unless parameters
|
99
|
-
pairs = []
|
100
|
-
parameters.each { |param, value|
|
101
|
-
# only encode simple classes !
|
102
|
-
|
103
|
-
if value.is_a?(Numeric) or value.is_a?(String)
|
104
|
-
pairs << "#{param}=#{value}"
|
105
|
-
end
|
106
|
-
}
|
107
|
-
return pairs.join(";")
|
108
|
-
end
|
109
|
-
|
110
|
-
# This method returns the query string of a uri
|
111
|
-
#
|
112
|
-
# Input:
|
113
|
-
# the uri
|
114
|
-
#
|
115
|
-
# Output:
|
116
|
-
# the query string.
|
117
|
-
# returns nil if no query string
|
118
|
-
|
119
|
-
def self.get_query_string(uri)
|
120
|
-
return nil unless uri
|
121
|
-
# gmosx: INVESTIGATE ruby's URI seems to differently handle
|
122
|
-
# abs and rel uris.
|
123
|
-
if md = URI::REGEXP::ABS_URI.match(uri)
|
124
|
-
return md[8]
|
125
|
-
elsif md = URI::REGEXP::REL_URI.match(uri)
|
126
|
-
return md[7]
|
127
|
-
end
|
128
|
-
return nil
|
129
|
-
end
|
130
|
-
|
131
|
-
# Removes the query string from a uri
|
132
|
-
#
|
133
|
-
# Input:
|
134
|
-
# the uri
|
135
|
-
#
|
136
|
-
# Output:
|
137
|
-
# the chomped uri.
|
138
|
-
|
139
|
-
def self.chomp_query_string(uri)
|
140
|
-
return nil unless uri
|
141
|
-
query_string = self.get_query_string(uri)
|
142
|
-
return uri.dup.chomp("?#{query_string}")
|
143
|
-
end
|
144
|
-
|
145
|
-
# Get a uri and a hash of parameters. Inject the hash values
|
146
|
-
# as parameters in the query sting path. Returns the full
|
147
|
-
# uri.
|
148
|
-
#
|
149
|
-
# Input:
|
150
|
-
# the uri to filter (String)
|
151
|
-
# hash of parameters to update
|
152
|
-
#
|
153
|
-
# Output:
|
154
|
-
# the full updated query string
|
155
|
-
#
|
156
|
-
# === TODO:
|
157
|
-
# optimize this a litle bit.
|
158
|
-
|
159
|
-
def self.update_query_string(uri, parameters)
|
160
|
-
query_string = self.get_query_string(uri)
|
161
|
-
rest = uri.dup.gsub(/\?#{query_string}/, "")
|
162
|
-
|
163
|
-
hash = self.query_string_to_hash(query_string)
|
164
|
-
hash.update(parameters)
|
165
|
-
query_string = self.hash_to_query_string(hash)
|
166
|
-
|
167
|
-
if Glue::StringUtils.valid?(query_string)
|
168
|
-
return "#{rest}?#{query_string}"
|
169
|
-
else
|
170
|
-
return rest
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# TODO: find a better name.
|
175
|
-
# Gets the request uri, injects extra parameters in the query string
|
176
|
-
# and returns a new uri. The request object is not modified.
|
177
|
-
# There is always a qs string so an extra test is skipped.
|
178
|
-
|
179
|
-
def self.update_request_uri(request, parameters)
|
180
|
-
hash = request.parameters.dup()
|
181
|
-
hash.update(parameters)
|
182
|
-
|
183
|
-
# use this in hash_to_querystring.
|
184
|
-
query_string = hash.collect { |k, v|
|
185
|
-
"#{k}=#{v}"
|
186
|
-
}.join(";")
|
187
|
-
|
188
|
-
return "#{request.translated_uri}?#{query_string}"
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
$:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
|
2
|
-
|
3
|
-
require 'test/unit'
|
4
|
-
require 'nitro/builder/atom'
|
5
|
-
|
6
|
-
class TestCaseBuildersAtom < Test::Unit::TestCase # :nodoc: all
|
7
|
-
include Nitro
|
8
|
-
|
9
|
-
Blog = Struct.new(:title, :body, :view_uri, :author)
|
10
|
-
|
11
|
-
def test_render
|
12
|
-
=begin
|
13
|
-
blogs = []
|
14
|
-
blogs << Blog.new('Hello1', 'World1', 'uri1', 'George');
|
15
|
-
blogs << Blog.new('Hello2', 'World2', 'uri2', 'Stella');
|
16
|
-
blogs << Blog.new('Hello3', 'World3', 'uri3', 'Renos');
|
17
|
-
|
18
|
-
rss = AtomBuilder.build(blogs, :link => 'http://www.navel.gr')
|
19
|
-
=end
|
20
|
-
# assert_match %r{<link>http://www.navel.gr/uri1</link>}, rss
|
21
|
-
# assert_match %r{<link>http://www.navel.gr/uri2</link>}, rss
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
data/test/nitro/tc_uri.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'nitro/uri'
|
3
|
-
|
4
|
-
class Dummy # :nodoc: all
|
5
|
-
attr_accessor :test1, :test2
|
6
|
-
end
|
7
|
-
|
8
|
-
class TC_Uri < Test::Unit::TestCase # :nodoc: all
|
9
|
-
include Nitro
|
10
|
-
|
11
|
-
def test_query_string_to_hash
|
12
|
-
# bad query string
|
13
|
-
|
14
|
-
assert_equal(0, UriUtils.query_string_to_hash("").length)
|
15
|
-
assert_equal(0, UriUtils.query_string_to_hash(nil).length)
|
16
|
-
|
17
|
-
# single valued
|
18
|
-
|
19
|
-
parameters = UriUtils.query_string_to_hash("koko=2&lala=3")
|
20
|
-
assert_equal("2", parameters["koko"])
|
21
|
-
assert_equal("3", parameters["lala"])
|
22
|
-
|
23
|
-
parameters = UriUtils.query_string_to_hash("koko=2;lala=3")
|
24
|
-
assert_equal("2", parameters["koko"])
|
25
|
-
assert_equal("3", parameters["lala"])
|
26
|
-
|
27
|
-
# multivalued
|
28
|
-
|
29
|
-
parameters = UriUtils.query_string_to_hash("koko=2;lala=3&koko=5")
|
30
|
-
assert_equal(2, parameters["koko"].length)
|
31
|
-
assert_equal("2", parameters["koko"][0])
|
32
|
-
assert_equal("3", parameters["lala"])
|
33
|
-
assert_equal("5", parameters["koko"][1])
|
34
|
-
|
35
|
-
# non existing value
|
36
|
-
assert_equal(nil, parameters["non-existing-value"])
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_hash_to_query_string
|
40
|
-
hash = { "koko" => 1, "lala" => 2}
|
41
|
-
qs = "koko=1;lala=2"
|
42
|
-
assert_equal(qs, UriUtils.hash_to_query_string(hash))
|
43
|
-
|
44
|
-
assert_equal(nil, UriUtils.hash_to_query_string(nil))
|
45
|
-
|
46
|
-
# bug: dont encode complex objects
|
47
|
-
hash = { "a" => 2, "b" => 3, "c" => Dummy.new }
|
48
|
-
qs = "a=2;b=3"
|
49
|
-
assert_equal(qs, UriUtils.hash_to_query_string(hash))
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_get_query_string
|
53
|
-
uri = "people/gmosx.sx?koko=1;lala=2"
|
54
|
-
assert_equal("koko=1;lala=2", UriUtils.get_query_string(uri))
|
55
|
-
|
56
|
-
uri = "http://www.navel.gr/people/gmosx.sx?koko=1&lala=2"
|
57
|
-
assert_equal("koko=1&lala=2", UriUtils.get_query_string(uri))
|
58
|
-
|
59
|
-
uri = "http://www.navel.gr:8080/people/gmosx.sx?koko=1;lala=2"
|
60
|
-
assert_equal("koko=1;lala=2", UriUtils.get_query_string(uri))
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_chomp_query_string
|
64
|
-
uri = "people/gmosx.sx"
|
65
|
-
assert_equal("people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
66
|
-
|
67
|
-
uri = "people/gmosx.sx?koko=1;lala=2"
|
68
|
-
assert_equal("people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
69
|
-
|
70
|
-
uri = "http://www.navel.gr/people/gmosx.sx?koko=1&lala=2"
|
71
|
-
assert_equal("http://www.navel.gr/people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
72
|
-
|
73
|
-
uri = "http://www.navel.gr:8080/people/gmosx.sx?koko=1;lala=2"
|
74
|
-
assert_equal("http://www.navel.gr:8080/people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
75
|
-
|
76
|
-
assert_equal(nil, UriUtils.chomp_query_string(nil))
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_update_query_string
|
80
|
-
uri = "ko/index.sx?koko=1"
|
81
|
-
hash = {"lala" => 2, "kaka" => 3}
|
82
|
-
assert_equal("ko/index.sx?koko=1;lala=2;kaka=3", UriUtils.update_query_string(uri, hash))
|
83
|
-
|
84
|
-
uri = "http://www.navel.gr:8080/ko/index.sx?koko=1"
|
85
|
-
hash = {"lala" => 2, "kaka" => 3}
|
86
|
-
assert_equal("http://www.navel.gr:8080/ko/index.sx?koko=1;lala=2;kaka=3", UriUtils.update_query_string(uri, hash))
|
87
|
-
|
88
|
-
uri = "http://www.navel.gr"
|
89
|
-
hash = {"lala" => 2, "kaka" => 3}
|
90
|
-
assert_equal("http://www.navel.gr?lala=2;kaka=3", UriUtils.update_query_string(uri, hash))
|
91
|
-
|
92
|
-
# bug: no ? when passed an empty hash
|
93
|
-
uri = "http://www.navel.gr"
|
94
|
-
assert_equal("http://www.navel.gr", UriUtils.update_query_string(uri, {}))
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
data/test/nitro/ui/tc_pager.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# :nodoc: all
|
2
|
-
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
require 'glue/logger'
|
6
|
-
|
7
|
-
require 'og'
|
8
|
-
require 'nitro/ui/pager'
|
9
|
-
|
10
|
-
class RequestMock < Hash
|
11
|
-
attr_accessor :query
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@query = {}
|
15
|
-
end
|
16
|
-
|
17
|
-
def get(k, default)
|
18
|
-
return self[k] || default
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class TC_N_UI_Pager < Test::Unit::TestCase
|
23
|
-
include Nitro
|
24
|
-
|
25
|
-
def setup
|
26
|
-
end
|
27
|
-
|
28
|
-
def teardown
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_all
|
32
|
-
items = [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
33
|
-
count = items.size()
|
34
|
-
|
35
|
-
request = RequestMock.new()
|
36
|
-
pager = UI::Pager.new('tst', request, 2, items)
|
37
|
-
|
38
|
-
assert_equal(pager.total_count, count)
|
39
|
-
|
40
|
-
# bug: bad rounding.
|
41
|
-
|
42
|
-
assert_equal(5, pager.page_count)
|
43
|
-
|
44
|
-
# bug: FIXME
|
45
|
-
# assert_equal(2, items.size())
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|