raw 0.49.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/doc/CONTRIBUTORS +106 -0
- data/doc/LICENSE +32 -0
- data/doc/coding_conventions.txt +11 -0
- data/lib/raw.rb +42 -0
- data/lib/raw/adapter.rb +113 -0
- data/lib/raw/adapter/cgi.rb +41 -0
- data/lib/raw/adapter/fastcgi.rb +48 -0
- data/lib/raw/adapter/mongrel.rb +146 -0
- data/lib/raw/adapter/script.rb +94 -0
- data/lib/raw/adapter/webrick.rb +144 -0
- data/lib/raw/adapter/webrick/vcr.rb +91 -0
- data/lib/raw/cgi.rb +323 -0
- data/lib/raw/cgi/cookie.rb +47 -0
- data/lib/raw/cgi/http.rb +62 -0
- data/lib/raw/compiler.rb +138 -0
- data/lib/raw/compiler/filter/cleanup.rb +21 -0
- data/lib/raw/compiler/filter/elements.rb +166 -0
- data/lib/raw/compiler/filter/elements/element.rb +210 -0
- data/lib/raw/compiler/filter/localization.rb +23 -0
- data/lib/raw/compiler/filter/markup.rb +32 -0
- data/lib/raw/compiler/filter/morph.rb +123 -0
- data/lib/raw/compiler/filter/morph/each.rb +34 -0
- data/lib/raw/compiler/filter/morph/for.rb +11 -0
- data/lib/raw/compiler/filter/morph/if.rb +26 -0
- data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
- data/lib/raw/compiler/filter/morph/standard.rb +55 -0
- data/lib/raw/compiler/filter/morph/times.rb +27 -0
- data/lib/raw/compiler/filter/script.rb +116 -0
- data/lib/raw/compiler/filter/squeeze.rb +16 -0
- data/lib/raw/compiler/filter/static_include.rb +74 -0
- data/lib/raw/compiler/filter/template.rb +121 -0
- data/lib/raw/compiler/reloader.rb +96 -0
- data/lib/raw/context.rb +154 -0
- data/lib/raw/context/flash.rb +157 -0
- data/lib/raw/context/global.rb +88 -0
- data/lib/raw/context/request.rb +338 -0
- data/lib/raw/context/response.rb +57 -0
- data/lib/raw/context/session.rb +198 -0
- data/lib/raw/context/session/drb.rb +11 -0
- data/lib/raw/context/session/file.rb +15 -0
- data/lib/raw/context/session/memcached.rb +13 -0
- data/lib/raw/context/session/memory.rb +12 -0
- data/lib/raw/context/session/og.rb +15 -0
- data/lib/raw/context/session/pstore.rb +13 -0
- data/lib/raw/control.rb +18 -0
- data/lib/raw/control/attribute.rb +91 -0
- data/lib/raw/control/attribute/checkbox.rb +25 -0
- data/lib/raw/control/attribute/datetime.rb +21 -0
- data/lib/raw/control/attribute/file.rb +20 -0
- data/lib/raw/control/attribute/fixnum.rb +26 -0
- data/lib/raw/control/attribute/float.rb +26 -0
- data/lib/raw/control/attribute/options.rb +38 -0
- data/lib/raw/control/attribute/password.rb +16 -0
- data/lib/raw/control/attribute/text.rb +16 -0
- data/lib/raw/control/attribute/textarea.rb +16 -0
- data/lib/raw/control/none.rb +16 -0
- data/lib/raw/control/relation.rb +59 -0
- data/lib/raw/control/relation/belongs_to.rb +0 -0
- data/lib/raw/control/relation/has_many.rb +97 -0
- data/lib/raw/control/relation/joins_many.rb +0 -0
- data/lib/raw/control/relation/many_to_many.rb +0 -0
- data/lib/raw/control/relation/refers_to.rb +29 -0
- data/lib/raw/controller.rb +37 -0
- data/lib/raw/controller/publishable.rb +160 -0
- data/lib/raw/dispatcher.rb +209 -0
- data/lib/raw/dispatcher/format.rb +108 -0
- data/lib/raw/dispatcher/format/atom.rb +31 -0
- data/lib/raw/dispatcher/format/css.rb +0 -0
- data/lib/raw/dispatcher/format/html.rb +42 -0
- data/lib/raw/dispatcher/format/json.rb +31 -0
- data/lib/raw/dispatcher/format/rss.rb +33 -0
- data/lib/raw/dispatcher/format/xoxo.rb +31 -0
- data/lib/raw/dispatcher/mounter.rb +60 -0
- data/lib/raw/dispatcher/router.rb +111 -0
- data/lib/raw/errors.rb +19 -0
- data/lib/raw/helper.rb +86 -0
- data/lib/raw/helper/benchmark.rb +23 -0
- data/lib/raw/helper/buffer.rb +60 -0
- data/lib/raw/helper/cookie.rb +32 -0
- data/lib/raw/helper/debug.rb +28 -0
- data/lib/raw/helper/default.rb +16 -0
- data/lib/raw/helper/feed.rb +451 -0
- data/lib/raw/helper/form.rb +284 -0
- data/lib/raw/helper/javascript.rb +59 -0
- data/lib/raw/helper/layout.rb +40 -0
- data/lib/raw/helper/navigation.rb +87 -0
- data/lib/raw/helper/pager.rb +305 -0
- data/lib/raw/helper/table.rb +247 -0
- data/lib/raw/helper/xhtml.rb +218 -0
- data/lib/raw/helper/xml.rb +125 -0
- data/lib/raw/mixin/magick.rb +35 -0
- data/lib/raw/mixin/sweeper.rb +71 -0
- data/lib/raw/mixin/thumbnails.rb +1 -0
- data/lib/raw/mixin/webfile.rb +165 -0
- data/lib/raw/render.rb +271 -0
- data/lib/raw/render/builder.rb +26 -0
- data/lib/raw/render/caching.rb +81 -0
- data/lib/raw/render/call.rb +43 -0
- data/lib/raw/render/send_file.rb +46 -0
- data/lib/raw/render/stream.rb +39 -0
- data/lib/raw/scaffold.rb +13 -0
- data/lib/raw/scaffold/controller.rb +25 -0
- data/lib/raw/scaffold/model.rb +157 -0
- data/lib/raw/test.rb +5 -0
- data/lib/raw/test/assertions.rb +169 -0
- data/lib/raw/test/context.rb +55 -0
- data/lib/raw/test/testcase.rb +79 -0
- data/lib/raw/util/attr.rb +128 -0
- data/lib/raw/util/encode_uri.rb +149 -0
- data/lib/raw/util/html_filter.rb +538 -0
- data/lib/raw/util/markup.rb +130 -0
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/CONFIG.rb +3 -0
- data/test/nitro/adapter/raw_post1.bin +9 -0
- data/test/nitro/adapter/tc_webrick.rb +16 -0
- data/test/nitro/cgi/tc_cookie.rb +14 -0
- data/test/nitro/cgi/tc_request.rb +61 -0
- data/test/nitro/compiler/tc_client_morpher.rb +47 -0
- data/test/nitro/compiler/tc_compiler.rb +25 -0
- data/test/nitro/dispatcher/tc_mounter.rb +47 -0
- data/test/nitro/helper/tc_feed.rb +135 -0
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_pager.rb +35 -0
- data/test/nitro/helper/tc_table.rb +68 -0
- data/test/nitro/helper/tc_xhtml.rb +19 -0
- data/test/nitro/tc_caching.rb +19 -0
- data/test/nitro/tc_cgi.rb +222 -0
- data/test/nitro/tc_context.rb +17 -0
- data/test/nitro/tc_controller.rb +103 -0
- data/test/nitro/tc_controller_aspect.rb +32 -0
- data/test/nitro/tc_controller_params.rb +885 -0
- data/test/nitro/tc_dispatcher.rb +109 -0
- data/test/nitro/tc_element.rb +85 -0
- data/test/nitro/tc_flash.rb +59 -0
- data/test/nitro/tc_helper.rb +47 -0
- data/test/nitro/tc_render.rb +119 -0
- data/test/nitro/tc_router.rb +61 -0
- data/test/nitro/tc_server.rb +35 -0
- data/test/nitro/tc_session.rb +66 -0
- data/test/nitro/tc_template.rb +71 -0
- data/test/nitro/util/tc_encode_url.rb +87 -0
- data/test/nitro/util/tc_markup.rb +31 -0
- data/test/public/blog/another/very_litle/index.xhtml +1 -0
- data/test/public/blog/inc1.xhtml +2 -0
- data/test/public/blog/inc2.xhtml +1 -0
- data/test/public/blog/list.xhtml +9 -0
- data/test/public/dummy_mailer/registration.xhtml +5 -0
- metadata +244 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Raw
|
|
2
|
+
|
|
3
|
+
# HTTP Response. This module is included in Context.
|
|
4
|
+
|
|
5
|
+
module Response
|
|
6
|
+
|
|
7
|
+
# The Response status.
|
|
8
|
+
|
|
9
|
+
attr_accessor :status
|
|
10
|
+
|
|
11
|
+
# The Response headers.
|
|
12
|
+
|
|
13
|
+
attr_accessor :response_headers
|
|
14
|
+
|
|
15
|
+
# The Response cookies.
|
|
16
|
+
|
|
17
|
+
attr_accessor :response_cookies
|
|
18
|
+
|
|
19
|
+
# Return the content type for this response.
|
|
20
|
+
|
|
21
|
+
def content_type
|
|
22
|
+
@response_headers["Content-Type"]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Set the content type for this response.
|
|
26
|
+
|
|
27
|
+
def content_type=(ctype)
|
|
28
|
+
@response_headers["Content-Type"] = ctype
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Add a cookie to the response. Better use this
|
|
32
|
+
# method to avoid precreating the cookies array
|
|
33
|
+
# for every request.
|
|
34
|
+
#
|
|
35
|
+
# === Examples
|
|
36
|
+
#
|
|
37
|
+
# add_cookie('nsid', 'gmosx')
|
|
38
|
+
# add_cookie(Cookie.new('nsid', 'gmosx')
|
|
39
|
+
|
|
40
|
+
def add_cookie(cookie, value = nil)
|
|
41
|
+
if value
|
|
42
|
+
(@response_cookies ||= []) << Cookie.new(cookie, value)
|
|
43
|
+
else
|
|
44
|
+
(@response_cookies ||= []) << cookie
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
alias_method :send_cookie, :add_cookie
|
|
48
|
+
|
|
49
|
+
# Return the output buffer.
|
|
50
|
+
|
|
51
|
+
def body
|
|
52
|
+
@output_buffer
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
require "md5"
|
|
2
|
+
|
|
3
|
+
require "facets/core/class/cattr"
|
|
4
|
+
require "facets/more/synchash"
|
|
5
|
+
require "facets/more/times"
|
|
6
|
+
require "facets/more/expirable"
|
|
7
|
+
require "facets/more/settings"
|
|
8
|
+
|
|
9
|
+
require "raw/cgi/cookie"
|
|
10
|
+
|
|
11
|
+
module Raw
|
|
12
|
+
|
|
13
|
+
# A web application session.
|
|
14
|
+
#
|
|
15
|
+
# State is a neccessary evil but session variables
|
|
16
|
+
# should be avoided as much as possible. Session state
|
|
17
|
+
# is typically distributed to many servers so avoid
|
|
18
|
+
# storing complete objects in session variables, only
|
|
19
|
+
# store oids and small integer/strings.
|
|
20
|
+
#
|
|
21
|
+
# The session should be persistable to survive server
|
|
22
|
+
# shutdowns.
|
|
23
|
+
#
|
|
24
|
+
# The session can be considered as a Hash where key-value
|
|
25
|
+
# pairs are stored. Typically symbols are used as keys. By
|
|
26
|
+
# convention uppercase symbols are used for internal Nitro
|
|
27
|
+
# session variables (ie :FLASH, :USER, etc). User applications
|
|
28
|
+
# typically use lowercase symbols (ie :cart, :history, etc).
|
|
29
|
+
#
|
|
30
|
+
#--
|
|
31
|
+
# TODO: rehash of the session cookie
|
|
32
|
+
# TODO: store -> cache, reimplement helpers.
|
|
33
|
+
#++
|
|
34
|
+
|
|
35
|
+
class Session < Hash
|
|
36
|
+
include Expirable
|
|
37
|
+
|
|
38
|
+
# Session id salt.
|
|
39
|
+
|
|
40
|
+
setting :session_id_salt, :default => 'SALT', :doc => 'Session id salt'
|
|
41
|
+
|
|
42
|
+
# The name of the cookie that stores the session id.
|
|
43
|
+
|
|
44
|
+
setting :cookie_name, :default => 'nsid', :doc => 'The name of the cookie that stores the session id'
|
|
45
|
+
|
|
46
|
+
# useful with persistents sessions stores
|
|
47
|
+
|
|
48
|
+
setting :cookie_expires, :default => false, :doc => 'Set expires parameter of session cookie equal to the keepalive setting?'
|
|
49
|
+
|
|
50
|
+
# The session keepalive time. The session is eligable for
|
|
51
|
+
# garbage collection after this time passes.
|
|
52
|
+
|
|
53
|
+
setting :keepalive, :default => 30.minutes, :doc => 'The session keepalive time'
|
|
54
|
+
|
|
55
|
+
# The type of the session cache. The generalized caching
|
|
56
|
+
# system in Glue is used. The following options are available:
|
|
57
|
+
#
|
|
58
|
+
# * :memory [default]
|
|
59
|
+
# * :drb
|
|
60
|
+
# * :og
|
|
61
|
+
# * :file
|
|
62
|
+
# * :memcached
|
|
63
|
+
|
|
64
|
+
setting :cache_type, :default => :memory, :doc => 'The type of session cache'
|
|
65
|
+
|
|
66
|
+
# The address of the cache store.
|
|
67
|
+
|
|
68
|
+
setting :cache_address, :default => '127.0.0.1', :doc => 'The address of the cache store'
|
|
69
|
+
|
|
70
|
+
# The port of the cache store.
|
|
71
|
+
|
|
72
|
+
setting :cache_port, :default => 9069, :doc => 'The port of the cache store'
|
|
73
|
+
|
|
74
|
+
class << self
|
|
75
|
+
|
|
76
|
+
# The sessions cache (store).
|
|
77
|
+
|
|
78
|
+
attr_accessor :cache
|
|
79
|
+
alias_method :store, :cache
|
|
80
|
+
|
|
81
|
+
# Load the correct Session specialization according to the
|
|
82
|
+
# cache type.
|
|
83
|
+
|
|
84
|
+
def setup(type = Session.cache_type)
|
|
85
|
+
# gmosx: RDoc friendly.
|
|
86
|
+
require "raw/context/session/" + type.to_s
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Lookup the session in the cache by using the session
|
|
90
|
+
# cookie value as a key. If the session does not exist
|
|
91
|
+
# creates a new session, inserts it in the cache and
|
|
92
|
+
# appends a new session cookie in the response.
|
|
93
|
+
|
|
94
|
+
def lookup(context)
|
|
95
|
+
if session_id = context.cookies[Session.cookie_name]
|
|
96
|
+
session = Session.cache[session_id]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
unless session
|
|
100
|
+
# Create new session.
|
|
101
|
+
session = Session.new(context)
|
|
102
|
+
cookie = Cookie.new(Session.cookie_name, session.session_id)
|
|
103
|
+
if Session.cookie_expires
|
|
104
|
+
cookie.expires = Time.now + Session.keepalive
|
|
105
|
+
end
|
|
106
|
+
context.add_cookie(cookie)
|
|
107
|
+
Session.cache[session.session_id] = session
|
|
108
|
+
else
|
|
109
|
+
# Access ('touch') the existing session.
|
|
110
|
+
session.touch!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
return session
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# The number of active (online) sessions.
|
|
117
|
+
# DON'T use yet!
|
|
118
|
+
|
|
119
|
+
def count
|
|
120
|
+
Session.cache.size
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Perform Session garbage collection. You may call this
|
|
124
|
+
# method from a cron job.
|
|
125
|
+
|
|
126
|
+
def garbage_collect
|
|
127
|
+
expired = []
|
|
128
|
+
for s in Session.cache.all
|
|
129
|
+
expired << s.session_id if s.expired?
|
|
130
|
+
end
|
|
131
|
+
for sid in expired
|
|
132
|
+
Session.cache.delete(sid)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
alias_method :gc!, :garbage_collect
|
|
136
|
+
|
|
137
|
+
# Returns the current session from the context thread local
|
|
138
|
+
# variable.
|
|
139
|
+
|
|
140
|
+
def current
|
|
141
|
+
Context.current.session
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# The unique id of this session.
|
|
147
|
+
|
|
148
|
+
attr_reader :session_id
|
|
149
|
+
|
|
150
|
+
# Create the session for the given context.
|
|
151
|
+
# If the hook method 'created' is defined it is called
|
|
152
|
+
# at the end. Typically used to initialize the session
|
|
153
|
+
# hash.
|
|
154
|
+
|
|
155
|
+
def initialize(context = nil)
|
|
156
|
+
@session_id = create_id
|
|
157
|
+
expires_after(Session.keepalive)
|
|
158
|
+
created if respond_to?(:created)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Synchronize the session store, by
|
|
162
|
+
# restoring this session. Especially useful
|
|
163
|
+
# in distributed and/or multiprocess setups.
|
|
164
|
+
|
|
165
|
+
def sync
|
|
166
|
+
Session.cache[@session_id] = self
|
|
167
|
+
end
|
|
168
|
+
alias_method :restore, :sync
|
|
169
|
+
|
|
170
|
+
def touch!
|
|
171
|
+
expires_after(Session.keepalive)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
protected
|
|
175
|
+
|
|
176
|
+
# Calculates a unique id.
|
|
177
|
+
#
|
|
178
|
+
# The session id must be unique, a monotonically
|
|
179
|
+
# increasing function like time is appropriate.
|
|
180
|
+
# Random may produce equal ids? add a prefix
|
|
181
|
+
# (SALT) to stop hackers from creating session_ids.
|
|
182
|
+
#--
|
|
183
|
+
# THINK: Is MD5 slow??? Allow for pluggable hashes.
|
|
184
|
+
#++
|
|
185
|
+
|
|
186
|
+
def create_id
|
|
187
|
+
now = Time.now
|
|
188
|
+
md5 = Digest::MD5.new
|
|
189
|
+
md5.update(now.to_s)
|
|
190
|
+
md5.update(now.usec.to_s)
|
|
191
|
+
md5.update(rand(0).to_s)
|
|
192
|
+
md5.update(Session.session_id_salt)
|
|
193
|
+
md5.hexdigest
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require "glue/cache/drb"
|
|
2
|
+
|
|
3
|
+
require "raw/context/session"
|
|
4
|
+
|
|
5
|
+
module Raw
|
|
6
|
+
|
|
7
|
+
Logger.info "Using DRb sessions at #{Session.cache_address}:#{Session.cache_port}." if defined?(Logger) && $DBG
|
|
8
|
+
|
|
9
|
+
Session.cache = Glue::DrbCache.new(Session.cache_address, Session.cache_port)
|
|
10
|
+
|
|
11
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "glue/cache/file"
|
|
2
|
+
|
|
3
|
+
require "raw/context/session"
|
|
4
|
+
|
|
5
|
+
module Raw
|
|
6
|
+
|
|
7
|
+
# A Session manager that persists sessions on disk.
|
|
8
|
+
|
|
9
|
+
Logger.info "Using File sessions." if defined?(Logger) && $DBG
|
|
10
|
+
|
|
11
|
+
Session.cache = Glue::FileCache.new("session_#{Session.cookie_name}", Session.keepalive)
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "glue/cache/memcached"
|
|
2
|
+
|
|
3
|
+
require "raw/context/session"
|
|
4
|
+
|
|
5
|
+
module Raw
|
|
6
|
+
|
|
7
|
+
# A Session manager that persists sessions on disk.
|
|
8
|
+
|
|
9
|
+
Logger.debug "Using MemCached sessions." if defined?(Logger) && $DBG
|
|
10
|
+
|
|
11
|
+
Session.cache = Glue::MemCached.new("session_#{Session.cookie_name}", Session.keepalive)
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "glue/cache/og"
|
|
2
|
+
|
|
3
|
+
require "raw/context/session"
|
|
4
|
+
|
|
5
|
+
module Raw
|
|
6
|
+
|
|
7
|
+
# A Session manager that persists sessions on an Og store.
|
|
8
|
+
|
|
9
|
+
Logger.debug "Using Og sessions." if defined?(Logger) && $DBG
|
|
10
|
+
|
|
11
|
+
Session.cache = OgCache.new("session_#{Session.cookie_name}", Session.keepalive)
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "glue/cache/pstore"
|
|
2
|
+
|
|
3
|
+
require "raw/context/session"
|
|
4
|
+
|
|
5
|
+
module Raw
|
|
6
|
+
|
|
7
|
+
# A Session manager that is using PStore to store state
|
|
8
|
+
|
|
9
|
+
Logger.info "Using PStore sessions." if defined?(Logger) && $DBG
|
|
10
|
+
|
|
11
|
+
Session.cache = Glue::PStoreCache.new(Session.keepalive)
|
|
12
|
+
|
|
13
|
+
end
|
data/lib/raw/control.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "raw/compiler/filter/elements/element"
|
|
2
|
+
require "raw/helper/xhtml"
|
|
3
|
+
|
|
4
|
+
module Raw
|
|
5
|
+
|
|
6
|
+
# A specialized kind of element used for implementing UI
|
|
7
|
+
# controls.
|
|
8
|
+
#--
|
|
9
|
+
# TODO: add support for the singleton pattern to avoid excessive
|
|
10
|
+
# memory usage.
|
|
11
|
+
#++
|
|
12
|
+
|
|
13
|
+
class Control < Element
|
|
14
|
+
# THINK: maybe include this in element too?
|
|
15
|
+
include XhtmlHelper
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require "raw/control"
|
|
2
|
+
|
|
3
|
+
module Raw
|
|
4
|
+
|
|
5
|
+
# The base class for controls used to inspect object
|
|
6
|
+
# attributes.
|
|
7
|
+
#--
|
|
8
|
+
# TODO: find a better name.
|
|
9
|
+
#++
|
|
10
|
+
|
|
11
|
+
class AttributeControl < Control
|
|
12
|
+
|
|
13
|
+
# The attribute that this control renders.
|
|
14
|
+
|
|
15
|
+
attr_accessor :attribute
|
|
16
|
+
|
|
17
|
+
# The annotations used for rendering
|
|
18
|
+
|
|
19
|
+
attr_accessor :anno
|
|
20
|
+
|
|
21
|
+
# The value
|
|
22
|
+
|
|
23
|
+
attr_accessor :value
|
|
24
|
+
alias_method :values, :value
|
|
25
|
+
|
|
26
|
+
# === Input
|
|
27
|
+
#
|
|
28
|
+
# * object = the object to inspect
|
|
29
|
+
# * a = the attribute to inspect
|
|
30
|
+
# * options = additional options
|
|
31
|
+
|
|
32
|
+
def initialize(object, a, options)
|
|
33
|
+
@object = object
|
|
34
|
+
@attribute = a
|
|
35
|
+
@anno = @object.class.ann(@attribute)
|
|
36
|
+
@value = @object.send(@attribute)
|
|
37
|
+
@options = options
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# Used as id attribute in HTML markup.
|
|
43
|
+
def control_id
|
|
44
|
+
"#{@attribute}_ctl"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Emit the label for this control.
|
|
48
|
+
# The label is skipped if the control is created with the
|
|
49
|
+
# option :no_label set to true.
|
|
50
|
+
|
|
51
|
+
def emit_label
|
|
52
|
+
return "" if @options[:no_label]
|
|
53
|
+
title = @anno[:title] || @options[:label] || @attribute.to_s.humanize
|
|
54
|
+
%{<label for="#{control_id}">#{title}</label>}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Emit the css style for this control.
|
|
58
|
+
# This mehtod takes into account the passed options (first)
|
|
59
|
+
# and then the attribute annotations.
|
|
60
|
+
|
|
61
|
+
def emit_style
|
|
62
|
+
unless style = (@options[:style] || @anno[:control_style])
|
|
63
|
+
if self.class.respond_to? :style
|
|
64
|
+
style = self.class.style
|
|
65
|
+
else
|
|
66
|
+
style = nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
style ? %{ style="#{style}"} : ''
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Add support to your controls for being disabled
|
|
73
|
+
# by including an emit_disabled on form items
|
|
74
|
+
# or testing for is_disabled? on more complex controls.
|
|
75
|
+
|
|
76
|
+
def emit_disabled
|
|
77
|
+
is_disabled? ? %{ disabled="disabled"} : ''
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#--
|
|
81
|
+
# FIXME
|
|
82
|
+
#++
|
|
83
|
+
|
|
84
|
+
def is_disabled?
|
|
85
|
+
return false if @options[:all]
|
|
86
|
+
@options[:disable_controls] || @anno[:disable_control]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|