wee 0.1.0 → 0.3.1
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/INSTALL +7 -0
- data/README +268 -0
- data/Rakefile +26 -0
- data/TODO +116 -0
- data/benchmark/Centrino1300/result.2000.counter.action +45 -0
- data/benchmark/Centrino1300/result.2000.counter.render +43 -0
- data/benchmark/Centrino1300/result.2000.filehandler +43 -0
- data/benchmark/Centrino600/result.2000.counter.action +47 -0
- data/benchmark/Centrino600/result.2000.counter.render +45 -0
- data/benchmark/Centrino600/result.2000.filehandler +43 -0
- data/benchmark/Makefile +48 -0
- data/benchmark/bench.sh +24 -0
- data/benchmark/counter.rb +96 -0
- data/benchmark/filehandler.rb +6 -0
- data/doc/rdoc/classes/Array.html +172 -0
- data/doc/rdoc/classes/Cache.html +126 -0
- data/doc/rdoc/classes/Cache/StorageCache.html +320 -0
- data/doc/rdoc/classes/Cache/Strategy.html +128 -0
- data/doc/rdoc/classes/Cache/Strategy/CapacityBounded.html +269 -0
- data/doc/rdoc/classes/Cache/Strategy/LFU.html +238 -0
- data/doc/rdoc/classes/Cache/Strategy/LFU/Item.html +111 -0
- data/doc/rdoc/classes/Cache/Strategy/LRU.html +238 -0
- data/doc/rdoc/classes/Cache/Strategy/LRU/Item.html +111 -0
- data/doc/rdoc/classes/Cache/Strategy/Unbounded.html +225 -0
- data/doc/rdoc/classes/Cache/Strategy/Unbounded/Item.html +111 -0
- data/doc/rdoc/classes/Enumerable.html +146 -0
- data/doc/rdoc/classes/LiteralMethod.html +196 -0
- data/doc/rdoc/classes/Object.html +178 -0
- data/doc/rdoc/classes/String.html +172 -0
- data/doc/rdoc/classes/Struct.html +174 -0
- data/doc/rdoc/classes/Wee.html +160 -0
- data/doc/rdoc/classes/Wee/AnswerDecoration.html +182 -0
- data/doc/rdoc/classes/Wee/Application.html +337 -0
- data/doc/rdoc/classes/Wee/Brush.html +245 -0
- data/doc/rdoc/classes/Wee/Brush/ActionCallbackMixin.html +149 -0
- data/doc/rdoc/classes/Wee/Brush/ActionMixin.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/ActionURLCallbackMixin.html +157 -0
- data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +210 -0
- data/doc/rdoc/classes/Wee/Brush/AssignMixin.html +141 -0
- data/doc/rdoc/classes/Wee/Brush/CallbackMixin.html +141 -0
- data/doc/rdoc/classes/Wee/Brush/FormTag.html +225 -0
- data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +176 -0
- data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +283 -0
- data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +176 -0
- data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +195 -0
- data/doc/rdoc/classes/Wee/Brush/InputCallbackMixin.html +149 -0
- data/doc/rdoc/classes/Wee/Brush/InputTag.html +172 -0
- data/doc/rdoc/classes/Wee/Brush/Page.html +193 -0
- data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +267 -0
- data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +177 -0
- data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +154 -0
- data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +173 -0
- data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +277 -0
- data/doc/rdoc/classes/Wee/Brush/TableTag.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +229 -0
- data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +154 -0
- data/doc/rdoc/classes/Wee/Callback.html +231 -0
- data/doc/rdoc/classes/Wee/CallbackRegistry.html +308 -0
- data/doc/rdoc/classes/Wee/CallbackStream.html +227 -0
- data/doc/rdoc/classes/Wee/Canvas.html +235 -0
- data/doc/rdoc/classes/Wee/Component.html +933 -0
- data/doc/rdoc/classes/Wee/Context.html +111 -0
- data/doc/rdoc/classes/Wee/Decoration.html +338 -0
- data/doc/rdoc/classes/Wee/Delegate.html +247 -0
- data/doc/rdoc/classes/Wee/ErrorPage.html +175 -0
- data/doc/rdoc/classes/Wee/ErrorResponse.html +180 -0
- data/doc/rdoc/classes/Wee/GenericResponse.html +162 -0
- data/doc/rdoc/classes/Wee/HtmlCanvas.html +751 -0
- data/doc/rdoc/classes/Wee/HtmlWriter.html +351 -0
- data/doc/rdoc/classes/Wee/LiteralMethodCallback.html +180 -0
- data/doc/rdoc/classes/Wee/MethodCallback.html +193 -0
- data/doc/rdoc/classes/Wee/Page.html +111 -0
- data/doc/rdoc/classes/Wee/Presenter.html +521 -0
- data/doc/rdoc/classes/Wee/RedirectResponse.html +150 -0
- data/doc/rdoc/classes/Wee/RefreshResponse.html +157 -0
- data/doc/rdoc/classes/Wee/RenderingContext.html +111 -0
- data/doc/rdoc/classes/Wee/Request.html +268 -0
- data/doc/rdoc/classes/Wee/RequestHandler.html +336 -0
- data/doc/rdoc/classes/Wee/Response.html +260 -0
- data/doc/rdoc/classes/Wee/Session.html +469 -0
- data/doc/rdoc/classes/Wee/SimpleIdGenerator.html +198 -0
- data/doc/rdoc/classes/Wee/Snapshot.html +211 -0
- data/doc/rdoc/classes/Wee/StateHolder.html +149 -0
- data/doc/rdoc/classes/Wee/StateRegistry.html +434 -0
- data/doc/rdoc/classes/Wee/StateRegistry/Snapshot.html +320 -0
- data/doc/rdoc/classes/Wee/StateRegistry/WithObject.html +153 -0
- data/doc/rdoc/classes/Wee/Utils.html +111 -0
- data/doc/rdoc/classes/Wee/Utils/LRUCache.html +148 -0
- data/doc/rdoc/classes/Wee/ValueHolder.html +220 -0
- data/doc/rdoc/classes/Wee/WEBrickAdaptor.html +330 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/INSTALL.html +118 -0
- data/doc/rdoc/files/README.html +466 -0
- data/doc/rdoc/files/lib/cache/cache_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/adaptors/webrick_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/application_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/callback_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/component_ext_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/component_rb.html +109 -0
- data/doc/rdoc/files/lib/wee/context_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/core/callback_rb.html +115 -0
- data/doc/rdoc/files/lib/wee/core/component_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/core/decoration_rb.html +133 -0
- data/doc/rdoc/files/lib/wee/core/presenter_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/core/snapshot_rb.html +113 -0
- data/doc/rdoc/files/lib/wee/core/valueholder_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/core_rb.html +131 -0
- data/doc/rdoc/files/lib/wee/decoration_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/holder_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/html_canvas_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/html_writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/idgen_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/page_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/presenter_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/renderer/html/brushes_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/renderer/html/canvas_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/renderer/html/writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/rendering/html/brushes_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/rendering/html/canvas_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/rendering/html/writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/request_rb.html +113 -0
- data/doc/rdoc/files/lib/wee/requesthandler_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/response_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/session_rb.html +109 -0
- data/doc/rdoc/files/lib/wee/snapshot_ext_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/snapshot_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/state_registry_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/stuff_rb.html +144 -0
- data/doc/rdoc/files/lib/wee/utils/cache_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/webrick_rb.html +108 -0
- data/doc/rdoc/files/lib/wee_rb.html +132 -0
- data/doc/rdoc/fr_class_index.html +93 -0
- data/doc/rdoc/fr_file_index.html +51 -0
- data/doc/rdoc/fr_method_index.html +242 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/examples/ObjectSpaceBrowser.rb +199 -0
- data/examples/calendar.rb +366 -0
- data/examples/cc.rb +94 -0
- data/examples/draw.rb +91 -0
- data/examples/example.rb +223 -0
- data/examples/test.rb +66 -0
- data/examples/window.rb +53 -0
- data/lib/cache/cache.rb +9 -0
- data/lib/wee.rb +18 -8
- data/lib/wee/adaptors/webrick.rb +73 -0
- data/lib/wee/application.rb +69 -71
- data/lib/wee/context.rb +2 -12
- data/lib/wee/core.rb +15 -0
- data/lib/wee/core/callback.rb +108 -0
- data/lib/wee/core/component.rb +314 -0
- data/lib/wee/core/decoration.rb +129 -0
- data/lib/wee/core/presenter.rb +132 -0
- data/lib/wee/core/snapshot.rb +21 -0
- data/lib/wee/core/valueholder.rb +19 -0
- data/lib/wee/idgen.rb +13 -0
- data/lib/wee/page.rb +1 -1
- data/lib/wee/renderer/html/brushes.rb +435 -0
- data/lib/wee/renderer/html/canvas.rb +148 -0
- data/lib/wee/{html_writer.rb → renderer/html/writer.rb} +31 -16
- data/lib/wee/request.rb +57 -0
- data/lib/wee/requesthandler.rb +77 -0
- data/lib/wee/response.rb +77 -0
- data/lib/wee/session.rb +70 -64
- data/lib/wee/{snapshot.rb → snapshot_ext.rb} +4 -4
- data/test/components/calltest.rb +16 -0
- data/test/components/counter.rb +17 -0
- data/test/components/messagebox.rb +15 -0
- data/test/components/page.rb +14 -0
- data/test/components/page_decoration.rb +7 -0
- data/test/stress.rb +64 -0
- data/test/test_component.rb +106 -0
- data/test/test_html_canvas.rb +25 -0
- data/test/test_html_writer.rb +27 -0
- data/test/test_request.rb +13 -0
- data/test/utils/cross.rb +65 -0
- data/test/utils/generic_plotter.rb +28 -0
- data/test/utils/gnuplot.rb +31 -0
- data/test/utils/measure_memory.rb +9 -0
- data/test/utils/memory_plotter.rb +10 -0
- data/test/utils/object_plotter.rb +10 -0
- data/test/utils/webrick_background.rb +31 -0
- data/wee.gemspec +22 -0
- metadata +222 -18
- data/lib/wee/component.rb +0 -126
- data/lib/wee/delegate_decoration.rb +0 -22
- data/lib/wee/handler_registry.rb +0 -89
- data/lib/wee/holder.rb +0 -14
- data/lib/wee/html_canvas.rb +0 -379
- data/lib/wee/state_registry.rb +0 -173
- data/lib/wee/stuff.rb +0 -29
- data/lib/wee/webrick.rb +0 -15
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
$LOAD_PATH.unshift << "../lib"
|
|
2
|
+
require 'wee'
|
|
3
|
+
require 'wee/webrick'
|
|
4
|
+
require 'wee/utils/cache'
|
|
5
|
+
require 'cgi'
|
|
6
|
+
|
|
7
|
+
require 'enumerator'
|
|
8
|
+
|
|
9
|
+
module ObjectSpaceBrowser
|
|
10
|
+
|
|
11
|
+
class Klasses < Wee::Component
|
|
12
|
+
|
|
13
|
+
def klasses
|
|
14
|
+
ObjectSpace.to_enum(:each_object, Class).sort_by{|k| k.name}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def choose(klass)
|
|
18
|
+
call(Klass.new(klass))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def render
|
|
22
|
+
r.h1 "Classes"
|
|
23
|
+
|
|
24
|
+
r.ul {
|
|
25
|
+
klasses.each do |klass|
|
|
26
|
+
r.li { r.anchor.action(:choose, klass).with(klass.name) }
|
|
27
|
+
end
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Klass < Wee::Component
|
|
33
|
+
|
|
34
|
+
def initialize(klass)
|
|
35
|
+
super()
|
|
36
|
+
@klass = klass
|
|
37
|
+
set_instances
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def choose(instance)
|
|
41
|
+
call Instance.new(instance)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Fetches all instances of the klass sorted by object_id
|
|
46
|
+
|
|
47
|
+
def set_instances
|
|
48
|
+
@instances =
|
|
49
|
+
case @klass
|
|
50
|
+
when Symbol
|
|
51
|
+
Symbol.all_symbols.sort_by do |s| s.to_s end
|
|
52
|
+
else
|
|
53
|
+
ObjectSpace.to_enum(:each_object, @klass).sort_by{|i| i.object_id}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def render
|
|
58
|
+
instances = @instances
|
|
59
|
+
r.h1 "Class #{@klass.name}"
|
|
60
|
+
r.h2 "#{@instances.length} Instances"
|
|
61
|
+
|
|
62
|
+
return if @instances.length.zero?
|
|
63
|
+
|
|
64
|
+
r.ul {
|
|
65
|
+
@instances.each do |instance|
|
|
66
|
+
r.li { r.anchor.action(:choose, instance).with("0x%x" % instance.object_id) }
|
|
67
|
+
end
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class Instance < Wee::Component
|
|
74
|
+
|
|
75
|
+
def initialize(instance)
|
|
76
|
+
super()
|
|
77
|
+
@instance = instance
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def choose(instance)
|
|
81
|
+
call Instance.new(instance)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def back
|
|
85
|
+
answer
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def render
|
|
89
|
+
r.anchor.action(:back).with("back")
|
|
90
|
+
|
|
91
|
+
r.break
|
|
92
|
+
r.h1 "Instance 0x%x of #{@instance.class.name}" % @instance.object_id
|
|
93
|
+
|
|
94
|
+
case @instance
|
|
95
|
+
when Array
|
|
96
|
+
r.bold("array elements: ")
|
|
97
|
+
r.break
|
|
98
|
+
r.ul do
|
|
99
|
+
@instance.each do |obj|
|
|
100
|
+
r.li { render_obj(obj, r) }
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
when Hash
|
|
104
|
+
r.bold("hash elements: ")
|
|
105
|
+
r.break
|
|
106
|
+
r.table.border(1).with do
|
|
107
|
+
r.table_row do
|
|
108
|
+
r.table_data do r.bold("Key") end
|
|
109
|
+
r.table_data do r.bold("Value") end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
@instance.each_pair do |k, v|
|
|
113
|
+
r.table_row do
|
|
114
|
+
r.table_data { render_obj(k, r) }
|
|
115
|
+
r.table_data { render_obj(v, r) }
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
when String, Float, Fixnum, Bignum, Numeric, Integer, Symbol
|
|
121
|
+
r.encode_text(@instance.inspect)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
return if @instance.instance_variables.empty?
|
|
125
|
+
r.break
|
|
126
|
+
|
|
127
|
+
render_instance_variables(r)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def render_instance_variables(r)
|
|
131
|
+
r.table.border(1).with do
|
|
132
|
+
r.table_row do
|
|
133
|
+
r.table_data do r.bold("Instance Variable") end
|
|
134
|
+
r.table_data do r.bold("Object") end
|
|
135
|
+
end
|
|
136
|
+
@instance.instance_variables.each do |var| render_ivar_row(var, r) end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def render_ivar_row(var, r)
|
|
141
|
+
r.table_row do
|
|
142
|
+
r.table_data(var)
|
|
143
|
+
r.table_data do
|
|
144
|
+
v = @instance.instance_variable_get(var)
|
|
145
|
+
render_obj(v, r)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def render_obj(obj, r)
|
|
151
|
+
r.anchor.action(:choose, obj).with do
|
|
152
|
+
r.bold(obj.class.name)
|
|
153
|
+
r.space
|
|
154
|
+
r.text("(#{ obj.object_id })")
|
|
155
|
+
r.space
|
|
156
|
+
r.space
|
|
157
|
+
|
|
158
|
+
case obj
|
|
159
|
+
when String, Float, Integer, Symbol
|
|
160
|
+
r.encode_text(obj.inspect)
|
|
161
|
+
else
|
|
162
|
+
r.encode_text(obj.inspect[0, 40] + "...")
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end # module ObjectSpaceBrowser
|
|
170
|
+
|
|
171
|
+
if $0 == __FILE__ then
|
|
172
|
+
|
|
173
|
+
OBJ = {
|
|
174
|
+
"hello" => { [1,2,3] => [5,6,7], "test" => :super },
|
|
175
|
+
"other" => %w(a b c d e f)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
class MySession < Wee::Session
|
|
179
|
+
def initialize
|
|
180
|
+
super do
|
|
181
|
+
self.root_component = ObjectSpaceBrowser::Instance.new(OBJ)
|
|
182
|
+
self.page_store = Wee::Utils::LRUCache.new(10) # backtrack up to 10 pages
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
class MyApplication < Wee::Application
|
|
188
|
+
def shutdown
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
Wee::Application.new {|app|
|
|
193
|
+
app.name = 'ObjectBrowser'
|
|
194
|
+
app.path = '/ob'
|
|
195
|
+
app.session_class = MySession
|
|
196
|
+
app.session_store = Wee::Utils::LRUCache.new(10)
|
|
197
|
+
app.dumpfile = ''
|
|
198
|
+
}.start
|
|
199
|
+
end
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Copyright by Kevin Howe (kh@newclear.ca)
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift << "../lib"
|
|
4
|
+
require 'wee'
|
|
5
|
+
require 'wee/adaptors/webrick'
|
|
6
|
+
require 'wee/utils/cache'
|
|
7
|
+
require 'date'
|
|
8
|
+
|
|
9
|
+
class Date
|
|
10
|
+
# Fetch the number of days in the given month
|
|
11
|
+
#
|
|
12
|
+
def days_in
|
|
13
|
+
((Date.new(self.year, self.month, 1) >> 1)-1).day
|
|
14
|
+
end
|
|
15
|
+
# Calendar represenation of a month. Consists of a
|
|
16
|
+
# list of weeks, each week a list of 7 days, each day a Date object.
|
|
17
|
+
# Padded with days showing for previous and next month.
|
|
18
|
+
#
|
|
19
|
+
def calendar
|
|
20
|
+
# months
|
|
21
|
+
curr_month = Date.new(self.year, self.month, 1)
|
|
22
|
+
prev_month = (curr_month << 1)
|
|
23
|
+
next_month = (curr_month >> 1)
|
|
24
|
+
|
|
25
|
+
# previous month days
|
|
26
|
+
prev_days = Array.new
|
|
27
|
+
prev_in_curr = curr_month.wday
|
|
28
|
+
((curr_month-1)-(prev_in_curr-1)).upto(curr_month-1) { |d| prev_days << d }
|
|
29
|
+
|
|
30
|
+
# current month days
|
|
31
|
+
curr_days = Array.new
|
|
32
|
+
curr_month.upto(next_month-1) { |d| curr_days << d }
|
|
33
|
+
|
|
34
|
+
# next month days
|
|
35
|
+
next_days = Array.new
|
|
36
|
+
days = prev_days+curr_days
|
|
37
|
+
weeks = (days.size.to_f/7).ceil
|
|
38
|
+
cdays_size = weeks*7
|
|
39
|
+
next_in_curr = (cdays_size-days.size)
|
|
40
|
+
next_month.upto(next_month+(next_in_curr-1)) { |d| next_days << d }
|
|
41
|
+
days += next_days
|
|
42
|
+
|
|
43
|
+
# split into weeks
|
|
44
|
+
table = Array.new
|
|
45
|
+
days.each do |day|
|
|
46
|
+
table << Array.new if table.size == 0 or table.last.size == 7
|
|
47
|
+
table.last << day
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
table
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Generates a browsable calendar.
|
|
55
|
+
# Each day is linked, clicking will set the date to that particular day.
|
|
56
|
+
#
|
|
57
|
+
class MiniCalendar < Wee::Component
|
|
58
|
+
|
|
59
|
+
# Browse mode: no answer will be given
|
|
60
|
+
attr_accessor :browse
|
|
61
|
+
|
|
62
|
+
# Holds the current chosen date
|
|
63
|
+
attr_accessor :date
|
|
64
|
+
|
|
65
|
+
# Initialize the MiniCalendar
|
|
66
|
+
#
|
|
67
|
+
def initialize(date=Date.today)
|
|
68
|
+
super()
|
|
69
|
+
@month = Date.new(date.year, date.month, 1)
|
|
70
|
+
@day = date
|
|
71
|
+
@browse = false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Backtrack state
|
|
75
|
+
#
|
|
76
|
+
def backtrack_state(snap)
|
|
77
|
+
super
|
|
78
|
+
snap.add(self)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Set to browse-only (no answer will be given)
|
|
82
|
+
#
|
|
83
|
+
def browse(value=true)
|
|
84
|
+
@browse = (value && true)
|
|
85
|
+
self
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# True if in browser-only mode
|
|
89
|
+
#
|
|
90
|
+
def browse?
|
|
91
|
+
@browse
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# True if the given date is the currently selected month
|
|
95
|
+
#
|
|
96
|
+
def current_month?(date)
|
|
97
|
+
Date.new(date.year, date.month, 1) == @month
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# True if the given date is the currently selected day
|
|
101
|
+
#
|
|
102
|
+
def selected_day?(date)
|
|
103
|
+
date == @day
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Date object representing the previous month
|
|
107
|
+
#
|
|
108
|
+
def prev_month
|
|
109
|
+
@month << 1
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Date object representing the next month
|
|
113
|
+
#
|
|
114
|
+
def next_month
|
|
115
|
+
@month >> 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Previous month's abbreviation
|
|
119
|
+
#
|
|
120
|
+
def prev_month_abbr
|
|
121
|
+
Date::ABBR_MONTHNAMES[prev_month.month]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Next month's abbreviation
|
|
125
|
+
#
|
|
126
|
+
def next_month_abbr
|
|
127
|
+
Date::ABBR_MONTHNAMES[next_month.month]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# String to be displayed as the month heading
|
|
131
|
+
#
|
|
132
|
+
def month_heading
|
|
133
|
+
Date::MONTHNAMES[@month.month].to_s+' '+@month.year.to_s
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# String to be displayed indicating the current date
|
|
137
|
+
#
|
|
138
|
+
def today_string
|
|
139
|
+
date = Date.today
|
|
140
|
+
mon_abbr = Date::ABBR_MONTHNAMES[date.month]
|
|
141
|
+
day_abbr = Date::ABBR_DAYNAMES[date.wday]
|
|
142
|
+
sprintf('Today is %s, %s %s %s', day_abbr, mon_abbr, date.day, date.year)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Render a given day
|
|
146
|
+
#
|
|
147
|
+
def render_day(date)
|
|
148
|
+
if current_month?(date)
|
|
149
|
+
selected_day?(date) ? render_selected_day(date) : render_month_day(date)
|
|
150
|
+
else
|
|
151
|
+
render_other_day(date)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Render a day of the currently selected month
|
|
156
|
+
#
|
|
157
|
+
def render_month_day(date)
|
|
158
|
+
r.table_data { r.anchor.callback { save(date) }.with(date.day) }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Render the currently selected day
|
|
162
|
+
#
|
|
163
|
+
def render_selected_day(date)
|
|
164
|
+
r.table_data.style('border: 1px solid black').with do
|
|
165
|
+
r.anchor.style('font-weight: bold').callback { save(date) }.with(date.day)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Render days of the previous or next month
|
|
170
|
+
#
|
|
171
|
+
def render_other_day(date)
|
|
172
|
+
r.table_data do
|
|
173
|
+
r.anchor.style('color: silver').callback { save(date) }.with(date.day)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# CSS styles
|
|
178
|
+
#
|
|
179
|
+
def render_styles
|
|
180
|
+
# ...
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Render Calender header
|
|
184
|
+
#
|
|
185
|
+
def render_header
|
|
186
|
+
r.table_row do
|
|
187
|
+
r.table_header.colspan(4).with { r.encoded_text(month_heading) }
|
|
188
|
+
r.table_header { r.anchor.callback { go_prev }.with(prev_month_abbr) }
|
|
189
|
+
r.table_header { r.anchor.callback { go_next }.with(next_month_abbr) }
|
|
190
|
+
r.table_header { browse? ? r.space : r.anchor.callback { back }.style('color: black').with('X') }
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Render Calendar footer
|
|
195
|
+
#
|
|
196
|
+
def render_footer
|
|
197
|
+
r.table_row { r.table_header.colspan(7).with { r.encoded_text(today_string) } }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Render Calendar
|
|
201
|
+
#
|
|
202
|
+
def render
|
|
203
|
+
r.html do
|
|
204
|
+
r.head { r.title('Calendar'); render_styles }
|
|
205
|
+
r.body do
|
|
206
|
+
r.text(sprintf('<!--Month: %s, Day: %s-->', @month, @day))
|
|
207
|
+
r.table { r.table_row { r.table_header {
|
|
208
|
+
r.table do
|
|
209
|
+
render_header
|
|
210
|
+
r.table_row { Date::ABBR_DAYNAMES.each { |day| r.table_header(day) } }
|
|
211
|
+
@month.calendar.each do |week|
|
|
212
|
+
r.table_row do
|
|
213
|
+
week.each { |day| render_day(day) }
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
render_footer
|
|
217
|
+
end
|
|
218
|
+
}}}
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Return without changes
|
|
224
|
+
#
|
|
225
|
+
def back
|
|
226
|
+
answer nil unless browse?
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Select the previous month
|
|
230
|
+
#
|
|
231
|
+
def go_prev
|
|
232
|
+
@month = prev_month
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Select the next month
|
|
236
|
+
#
|
|
237
|
+
def go_next
|
|
238
|
+
@month = next_month
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Save the given day
|
|
242
|
+
#
|
|
243
|
+
def save(day)
|
|
244
|
+
@day = day
|
|
245
|
+
@month = Date.new(day.year, day.month, 1)
|
|
246
|
+
answer(day) unless browse?
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
if __FILE__ == $0
|
|
251
|
+
|
|
252
|
+
# Custom CSS styles
|
|
253
|
+
#
|
|
254
|
+
module StyleMixin
|
|
255
|
+
def render_styles
|
|
256
|
+
r.style("
|
|
257
|
+
a {
|
|
258
|
+
text-decoration: none;
|
|
259
|
+
}
|
|
260
|
+
body {
|
|
261
|
+
font-size : 11px;
|
|
262
|
+
font-family : Arial, Helvetica, sans-serif;
|
|
263
|
+
text-align: center;
|
|
264
|
+
}
|
|
265
|
+
td {
|
|
266
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
267
|
+
font-size: 11px;
|
|
268
|
+
border: 1px solid;
|
|
269
|
+
background-color: #FFFFFF;
|
|
270
|
+
vertical-align: top;
|
|
271
|
+
text-align: center;
|
|
272
|
+
}
|
|
273
|
+
th {
|
|
274
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
275
|
+
font-size: 11px;
|
|
276
|
+
font-style: normal;
|
|
277
|
+
font-weight: bold;
|
|
278
|
+
background-color: #BBCCFF;
|
|
279
|
+
border: 1px solid;
|
|
280
|
+
vertical-align: top;
|
|
281
|
+
text-align: center;
|
|
282
|
+
}
|
|
283
|
+
")
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Calendar with custom CSS styles
|
|
288
|
+
#
|
|
289
|
+
class CustomCalendar < MiniCalendar
|
|
290
|
+
include StyleMixin
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Calendar demo
|
|
294
|
+
#
|
|
295
|
+
class CustomCalendarDemo < Wee::Component
|
|
296
|
+
include StyleMixin
|
|
297
|
+
|
|
298
|
+
# Holds the current chosen date
|
|
299
|
+
attr_accessor :date
|
|
300
|
+
|
|
301
|
+
# Initialize with a Date object (defaults to today)
|
|
302
|
+
#
|
|
303
|
+
def initialize(date=Date.today)
|
|
304
|
+
super()
|
|
305
|
+
@date = date
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Backtrack state
|
|
309
|
+
#
|
|
310
|
+
def backtrack_state(snap)
|
|
311
|
+
super
|
|
312
|
+
snap.add(self)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# Render calendar icon
|
|
316
|
+
#
|
|
317
|
+
def render_icon
|
|
318
|
+
icon = 'http://www.softcomplex.com/products/tigra_calendar/img/cal.gif'
|
|
319
|
+
r.img.src(icon).width(16).height(16).border(0).alt('Calendar')
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# Render Calendar demo
|
|
323
|
+
#
|
|
324
|
+
def render
|
|
325
|
+
r.html do
|
|
326
|
+
r.head { r.title('Calendar Demo'); render_styles }
|
|
327
|
+
r.body do
|
|
328
|
+
r.break
|
|
329
|
+
r.table { r.table_row { r.table_header {
|
|
330
|
+
r.table do
|
|
331
|
+
r.table_row { r.table_header('Calendar Demo') }
|
|
332
|
+
r.table_row { r.table_data {
|
|
333
|
+
r.text_input.value(@date).attr(:date)
|
|
334
|
+
r.space
|
|
335
|
+
r.anchor.callback { calendar }.with { render_icon }
|
|
336
|
+
}}
|
|
337
|
+
end
|
|
338
|
+
}}}
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# Call the calendar component
|
|
344
|
+
#
|
|
345
|
+
def calendar()
|
|
346
|
+
if date = call( CustomCalendar.new(@date) )
|
|
347
|
+
@date = date
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
class MySession < Wee::Session
|
|
353
|
+
def initialize
|
|
354
|
+
super do
|
|
355
|
+
self.root_component = CustomCalendarDemo.new
|
|
356
|
+
self.page_store = Wee::Utils::LRUCache.new(10) # backtrack up to 10 pages
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
app = Wee::Application.new {|app|
|
|
362
|
+
app.default_request_handler { MySession.new }
|
|
363
|
+
app.id_generator = Wee::SimpleIdGenerator.new(rand(1_000_000))
|
|
364
|
+
}
|
|
365
|
+
Wee::WEBrickAdaptor.register('/app' => app).start
|
|
366
|
+
end
|