nitro 0.19.0 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|