wee 2.0.0 → 2.1.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/TODO +31 -0
- data/benchmark.rb +37 -0
- data/demo.ru +11 -0
- data/doc/rdoc/classes/Array.html +22 -26
- data/doc/rdoc/classes/Hash.html +22 -26
- data/doc/rdoc/classes/Object.html +21 -26
- data/doc/rdoc/classes/String.html +19 -87
- data/doc/rdoc/classes/Struct.html +22 -26
- data/doc/rdoc/classes/Wee.html +75 -206
- data/doc/rdoc/classes/Wee/AnswerDecoration.html +35 -66
- data/doc/rdoc/classes/Wee/AnswerDecoration/Answer.html +28 -46
- data/doc/rdoc/classes/Wee/Application.html +63 -114
- data/doc/rdoc/classes/Wee/Application/SessionCache.html +30 -44
- data/doc/rdoc/classes/Wee/Brush.html +52 -101
- data/doc/rdoc/classes/Wee/Brush/ActionInputTag.html +29 -51
- data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +44 -101
- data/doc/rdoc/classes/Wee/Brush/CheckboxTag.html +43 -76
- data/doc/rdoc/classes/Wee/Brush/FileUploadTag.html +29 -46
- data/doc/rdoc/classes/Wee/Brush/FormTag.html +48 -110
- data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +30 -42
- data/doc/rdoc/classes/Wee/Brush/GenericSingleTagBrush.html +37 -58
- data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +93 -210
- data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +38 -63
- data/doc/rdoc/classes/Wee/Brush/HiddenInputTag.html +29 -45
- data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +35 -52
- data/doc/rdoc/classes/Wee/Brush/ImageTag.html +28 -61
- data/doc/rdoc/classes/Wee/Brush/InputTag.html +34 -107
- data/doc/rdoc/classes/Wee/Brush/JavascriptTag.html +28 -54
- data/doc/rdoc/classes/Wee/Brush/Page.html +39 -73
- data/doc/rdoc/classes/Wee/Brush/PasswordInputTag.html +29 -45
- data/doc/rdoc/classes/Wee/Brush/RadioButtonTag.html +54 -98
- data/doc/rdoc/classes/Wee/Brush/RadioGroup.html +46 -84
- data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +87 -187
- data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +29 -56
- data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +29 -45
- data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +28 -55
- data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +28 -55
- data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +56 -113
- data/doc/rdoc/classes/Wee/Brush/TableTag.html +27 -58
- data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +48 -140
- data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +29 -45
- data/doc/rdoc/classes/Wee/CallAnswerMixin.html +51 -79
- data/doc/rdoc/classes/Wee/CallbackMixin.html +44 -77
- data/doc/rdoc/classes/Wee/CallbackRegistry.html +69 -125
- data/doc/rdoc/classes/Wee/Callbacks.html +43 -82
- data/doc/rdoc/classes/Wee/Component.html +142 -292
- data/doc/rdoc/classes/Wee/Decoration.html +85 -141
- data/doc/rdoc/classes/Wee/DecorationMixin.html +111 -118
- data/doc/rdoc/classes/Wee/Delegate.html +72 -115
- data/doc/rdoc/classes/Wee/DupReplaceSnapshotMixin.html +37 -54
- data/doc/rdoc/classes/Wee/ErrorResponse.html +31 -48
- data/doc/rdoc/classes/Wee/FormDecoration.html +32 -46
- data/doc/rdoc/classes/Wee/GenericResponse.html +30 -50
- data/doc/rdoc/classes/Wee/HtmlCanvas.html +209 -562
- data/doc/rdoc/classes/Wee/HtmlDocument.html +51 -91
- data/doc/rdoc/classes/Wee/HtmlWriter.html +76 -156
- data/doc/rdoc/classes/Wee/IdGenerator.html +28 -44
- data/doc/rdoc/classes/Wee/IdGenerator/Secure.html +53 -95
- data/doc/rdoc/classes/Wee/IdGenerator/Sequential.html +37 -63
- data/doc/rdoc/classes/Wee/JQuery.html +36 -64
- data/doc/rdoc/classes/Wee/LRUCache.html +94 -189
- data/doc/rdoc/classes/Wee/LRUCache/Item.html +30 -42
- data/doc/rdoc/classes/Wee/ObjectSnapshotMixin.html +37 -54
- data/doc/rdoc/classes/Wee/PageDecoration.html +48 -79
- data/doc/rdoc/classes/Wee/Presenter.html +86 -143
- data/doc/rdoc/classes/Wee/RedirectResponse.html +31 -49
- data/doc/rdoc/classes/Wee/RefreshResponse.html +34 -48
- data/doc/rdoc/classes/Wee/Renderer.html +56 -125
- data/doc/rdoc/classes/Wee/Request.html +57 -115
- data/doc/rdoc/classes/Wee/Response.html +24 -26
- data/doc/rdoc/classes/Wee/Session.html +137 -292
- data/doc/rdoc/classes/Wee/Session/AbortCallbackProcessing.html +29 -46
- data/doc/rdoc/classes/Wee/Session/MutexSerializer.html +29 -42
- data/doc/rdoc/classes/Wee/Session/Page.html +22 -21
- data/doc/rdoc/classes/Wee/Session/ThreadSerializer.html +36 -60
- data/doc/rdoc/classes/Wee/State.html +57 -105
- data/doc/rdoc/classes/Wee/State/Snapshot.html +22 -21
- data/doc/rdoc/classes/Wee/State/SnapshotIVars.html +22 -21
- data/doc/rdoc/classes/Wee/StructSnapshotMixin.html +37 -54
- data/doc/rdoc/classes/Wee/WrapperDecoration.html +42 -68
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/README_rdoc.html +26 -17
- data/doc/rdoc/files/lib/wee/application_rb.html +25 -19
- data/doc/rdoc/files/lib/wee/call_answer_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/callback_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/component_rb.html +25 -19
- data/doc/rdoc/files/lib/wee/decoration_rb.html +23 -15
- data/doc/rdoc/files/lib/wee/html_brushes_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/html_canvas_rb.html +23 -15
- data/doc/rdoc/files/lib/wee/html_document_rb.html +23 -15
- data/doc/rdoc/files/lib/wee/html_writer_rb.html +23 -15
- data/doc/rdoc/files/lib/wee/id_generator_rb.html +24 -17
- data/doc/rdoc/files/lib/wee/jquery/jquery_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/jquery_rb.html +23 -15
- data/doc/rdoc/files/lib/wee/lru_cache_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/presenter_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/renderer_rb.html +23 -12
- data/doc/rdoc/files/lib/wee/request_rb.html +23 -15
- data/doc/rdoc/files/lib/wee/response_rb.html +24 -17
- data/doc/rdoc/files/lib/wee/session_rb.html +26 -21
- data/doc/rdoc/files/lib/wee/state_rb.html +23 -12
- data/doc/rdoc/files/lib/wee_rb.html +37 -47
- data/doc/rdoc/fr_class_index.html +12 -86
- data/doc/rdoc/fr_file_index.html +12 -30
- data/doc/rdoc/fr_method_index.html +242 -473
- data/doc/rdoc/index.html +8 -5
- data/doc/rdoc/rdoc-style.css +119 -210
- data/examples/ObjectSpaceBrowser.rb +4 -4
- data/examples/TODO +21 -0
- data/examples/ajax.rb +6 -4
- data/examples/blog.rb +42 -0
- data/examples/demo.rb +5 -3
- data/examples/demo/calculator.rb +3 -3
- data/examples/demo/calendar.rb +4 -4
- data/examples/demo/counter.rb +2 -2
- data/examples/demo/editable_counter.rb +2 -2
- data/examples/demo/example.rb +25 -16
- data/examples/demo/window.rb +10 -3
- data/examples/hw2.rb +17 -0
- data/examples/recipe/description.rb +170 -0
- data/examples/recipe/migrations/001_create_recipes.rb +13 -0
- data/examples/recipe/model.rb +27 -0
- data/examples/recipe/models/recipe.rb +18 -0
- data/examples/recipe/recipe_editor.rb +28 -0
- data/lib/wee.rb +1 -7
- data/lib/wee/component.rb +37 -74
- data/lib/wee/decoration.rb +16 -15
- data/lib/wee/html_brushes.rb +16 -17
- data/lib/wee/presenter.rb +2 -1
- data/lib/wee/response.rb +4 -4
- data/lib/wee/session.rb +2 -2
- data/lib/wee/state.rb +2 -2
- data/test/t.rb +67 -0
- data/wee.gemspec +1 -1
- metadata +157 -167
data/examples/TODO
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
* Tab
|
|
2
|
+
|
|
3
|
+
* Simple form.
|
|
4
|
+
- with buttons
|
|
5
|
+
(calculator)
|
|
6
|
+
|
|
7
|
+
* message box
|
|
8
|
+
|
|
9
|
+
* multiple forms with form decoration
|
|
10
|
+
|
|
11
|
+
* file upload
|
|
12
|
+
|
|
13
|
+
* pager component
|
|
14
|
+
|
|
15
|
+
* check boxes
|
|
16
|
+
|
|
17
|
+
* radio buttons
|
|
18
|
+
|
|
19
|
+
* code browser. live code: rendering.
|
|
20
|
+
|
|
21
|
+
* calculator
|
data/examples/ajax.rb
CHANGED
|
@@ -10,9 +10,9 @@ class AjaxCounter < Wee::Component
|
|
|
10
10
|
@counter = 0
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def
|
|
13
|
+
def state(s)
|
|
14
14
|
super
|
|
15
|
-
|
|
15
|
+
s.add_ivar(self, :@counter, @counter)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def render(r)
|
|
@@ -28,9 +28,11 @@ end
|
|
|
28
28
|
class HelloWorld < Wee::Component
|
|
29
29
|
def initialize
|
|
30
30
|
super
|
|
31
|
-
@
|
|
31
|
+
@counters = (1..10).map { AjaxCounter.new }
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
def children() @counters end
|
|
35
|
+
|
|
34
36
|
def render(r)
|
|
35
37
|
r.html {
|
|
36
38
|
r.head {
|
|
@@ -40,7 +42,7 @@ class HelloWorld < Wee::Component
|
|
|
40
42
|
r.body {
|
|
41
43
|
render_hello(r)
|
|
42
44
|
r.div.onclick_callback { p "refresh" }.with("Refresh")
|
|
43
|
-
@
|
|
45
|
+
@counters.each {|c| r.render(c); r.break}
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
end
|
data/examples/blog.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
$LOAD_PATH.unshift "../lib"
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'wee'
|
|
4
|
+
|
|
5
|
+
class Page < Wee::Component
|
|
6
|
+
def initialize
|
|
7
|
+
add_decoration Wee::PageDecoration.new('Title')
|
|
8
|
+
super
|
|
9
|
+
end
|
|
10
|
+
def render(r)
|
|
11
|
+
r.anchor.callback {
|
|
12
|
+
if callcc YesNoMessageBox.new('Really delete?')
|
|
13
|
+
callcc InfoMessageBox.new('Deleted!')
|
|
14
|
+
else
|
|
15
|
+
callcc InfoMessageBox.new('Deleted action aborted')
|
|
16
|
+
end
|
|
17
|
+
}.with("delete?")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class InfoMessageBox < Wee::Component
|
|
22
|
+
def initialize(msg)
|
|
23
|
+
@msg = msg
|
|
24
|
+
super()
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def render(r)
|
|
28
|
+
r.h1(@msg)
|
|
29
|
+
r.anchor.callback { answer }.with('OK')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class YesNoMessageBox < InfoMessageBox
|
|
34
|
+
def render(r)
|
|
35
|
+
r.h1(@msg)
|
|
36
|
+
r.anchor.callback { answer true }.with('YES')
|
|
37
|
+
r.space(1)
|
|
38
|
+
r.anchor.callback { answer false }.with('NO')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Wee.runcc(Page)
|
data/examples/demo.rb
CHANGED
|
@@ -23,13 +23,15 @@ class Demo < Wee::Component
|
|
|
23
23
|
@components << E.new(RadioTest.new, "Radio Buttons", 'demo/radio.rb')
|
|
24
24
|
@components << E.new(FileUploadTest.new, "File Upload", 'demo/file_upload.rb')
|
|
25
25
|
|
|
26
|
-
@
|
|
27
|
-
|
|
28
|
-
@editor = add_child Editor.new
|
|
26
|
+
@editor = Editor.new
|
|
29
27
|
|
|
30
28
|
select_component(@components.first)
|
|
31
29
|
end
|
|
32
30
|
|
|
31
|
+
def children
|
|
32
|
+
@components.map {|c| c.component} + [@editor]
|
|
33
|
+
end
|
|
34
|
+
|
|
33
35
|
def select_component(component)
|
|
34
36
|
@editor.entry = @selected_component = component
|
|
35
37
|
end
|
data/examples/demo/calculator.rb
CHANGED
data/examples/demo/calendar.rb
CHANGED
|
@@ -69,9 +69,9 @@ class MiniCalendar < Wee::Component
|
|
|
69
69
|
|
|
70
70
|
# Backtrack state
|
|
71
71
|
#
|
|
72
|
-
def
|
|
72
|
+
def state(s)
|
|
73
73
|
super
|
|
74
|
-
|
|
74
|
+
s.add(self)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# Set to browse-only (no answer will be given)
|
|
@@ -299,9 +299,9 @@ class CustomCalendarDemo < Wee::Component
|
|
|
299
299
|
|
|
300
300
|
# Backtrack state
|
|
301
301
|
#
|
|
302
|
-
def
|
|
302
|
+
def state(s)
|
|
303
303
|
super
|
|
304
|
-
|
|
304
|
+
s.add(self)
|
|
305
305
|
end
|
|
306
306
|
|
|
307
307
|
# Render calendar icon
|
data/examples/demo/counter.rb
CHANGED
|
@@ -9,9 +9,9 @@ class EditableCounter < Counter
|
|
|
9
9
|
@show_edit_field = false
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def state(s)
|
|
13
13
|
super
|
|
14
|
-
|
|
14
|
+
s.add_ivar(self, :@show_edit_field, @show_edit_field)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def render_count(r)
|
data/examples/demo/example.rb
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
$LOAD_PATH.unshift "../lib"
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'wee'
|
|
4
|
+
|
|
1
5
|
require 'demo/window'
|
|
2
6
|
require 'demo/editable_counter'
|
|
3
7
|
require 'demo/messagebox'
|
|
@@ -11,9 +15,9 @@ class RegexpValidatedInput < Wee::Component
|
|
|
11
15
|
@error = false
|
|
12
16
|
end
|
|
13
17
|
|
|
14
|
-
def
|
|
18
|
+
def state(s)
|
|
15
19
|
super
|
|
16
|
-
|
|
20
|
+
s.add(self)
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
def value
|
|
@@ -53,16 +57,15 @@ class MainPage < Wee::Component
|
|
|
53
57
|
def initialize
|
|
54
58
|
super()
|
|
55
59
|
@counters = (1..10).map {|i|
|
|
56
|
-
|
|
60
|
+
Window.new {|w|
|
|
57
61
|
w.title = "Cnt #{ i }"
|
|
58
62
|
w.pos_x = "200px"
|
|
59
63
|
w.pos_y = "#{i*50}px"
|
|
60
|
-
w
|
|
64
|
+
w << EditableCounter.new(i)
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
add_child(@val_inp = RegexpValidatedInput.new('Michael Neumann', /^\w+\s+\w+$/))
|
|
68
|
+
@val_inp = RegexpValidatedInput.new('Michael Neumann', /^\w+\s+\w+$/)
|
|
66
69
|
|
|
67
70
|
@arr = []
|
|
68
71
|
@text = ""
|
|
@@ -73,17 +76,21 @@ class MainPage < Wee::Component
|
|
|
73
76
|
@selected2 = []
|
|
74
77
|
end
|
|
75
78
|
|
|
76
|
-
def
|
|
79
|
+
def children
|
|
80
|
+
[@val_inp, *@counters]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def state(s)
|
|
77
84
|
super
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
s.add(@counters)
|
|
86
|
+
state_decoration(s)
|
|
87
|
+
s.add(@arr)
|
|
88
|
+
s.add(@text)
|
|
89
|
+
|
|
90
|
+
s.add(@list1)
|
|
91
|
+
s.add(@selected1)
|
|
92
|
+
s.add(@list2)
|
|
93
|
+
s.add(@selected2)
|
|
87
94
|
end
|
|
88
95
|
|
|
89
96
|
attr_accessor :text
|
|
@@ -131,3 +138,5 @@ class MainPage < Wee::Component
|
|
|
131
138
|
end
|
|
132
139
|
end
|
|
133
140
|
end
|
|
141
|
+
|
|
142
|
+
Wee.run(MainPage) if __FILE__ == $0
|
data/examples/demo/window.rb
CHANGED
|
@@ -6,12 +6,19 @@ class Window < Wee::Component
|
|
|
6
6
|
super()
|
|
7
7
|
@status = :normal
|
|
8
8
|
@pos_x, @pos_y = "0px", "0px"
|
|
9
|
+
@children = []
|
|
9
10
|
block.call(self) if block
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def
|
|
13
|
+
def <<(c)
|
|
14
|
+
@children << c
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def children() @children end
|
|
18
|
+
|
|
19
|
+
def state(s)
|
|
13
20
|
super
|
|
14
|
-
|
|
21
|
+
s.add_ivar(self, :@status, @status)
|
|
15
22
|
end
|
|
16
23
|
|
|
17
24
|
def process_callbacks(callbacks)
|
|
@@ -38,7 +45,7 @@ class Window < Wee::Component
|
|
|
38
45
|
r.table_row do
|
|
39
46
|
r.table_data.colspan(2).with do
|
|
40
47
|
if @status == :normal
|
|
41
|
-
|
|
48
|
+
for child in self.children do
|
|
42
49
|
r.render(child)
|
|
43
50
|
end
|
|
44
51
|
end
|
data/examples/hw2.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
$LOAD_PATH.unshift "../lib"
|
|
2
|
+
require 'rubygems' if RUBY_VERSION < "1.9"
|
|
3
|
+
require 'wee'
|
|
4
|
+
|
|
5
|
+
class HelloWorld < Wee::Component
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
add_decoration Wee::PageDecoration.new(title="Hello World")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def render(r)
|
|
12
|
+
r.h1 "Hello World from Wee!"
|
|
13
|
+
r.div.onclick_callback { p "clicked" }.with("click here2")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Wee.run(HelloWorld) if __FILE__ == $0
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
class Accessor
|
|
2
|
+
end
|
|
3
|
+
|
|
4
|
+
class SelectorAccessor < Accessor
|
|
5
|
+
def initialize(symbol, write_symbol=nil)
|
|
6
|
+
@read_symbol = symbol
|
|
7
|
+
@write_symbol = write_symbol || :"#{symbol}="
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def [](object)
|
|
11
|
+
object.send(@read_symbol)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def []=(object, value)
|
|
15
|
+
object.send(@write_symbol, value)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
####################################################
|
|
20
|
+
|
|
21
|
+
class Description
|
|
22
|
+
def initialize
|
|
23
|
+
yield self if block_given?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_string(value)
|
|
27
|
+
value.to_s
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class ContainerDescription < Description
|
|
32
|
+
def initialize
|
|
33
|
+
super
|
|
34
|
+
@elements = []
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
include Enumerable
|
|
38
|
+
|
|
39
|
+
def each(&block)
|
|
40
|
+
@elements.each(&block)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def <<(element)
|
|
44
|
+
@elements << element
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def push(*args)
|
|
48
|
+
@elements.push(*args)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class ElementDescription < Description
|
|
53
|
+
attr_accessor :accessor
|
|
54
|
+
attr_accessor :label
|
|
55
|
+
|
|
56
|
+
def initialize
|
|
57
|
+
@conditions = []
|
|
58
|
+
super
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def selector_accessor(*args)
|
|
62
|
+
self.accessor = SelectorAccessor.new(*args)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def required
|
|
66
|
+
@required = true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def add_condition(cond, label=nil)
|
|
70
|
+
@conditions = cond
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class StringDescription < ElementDescription
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
####################################################
|
|
78
|
+
|
|
79
|
+
class Description
|
|
80
|
+
TYPE_MAP = {
|
|
81
|
+
String => StringDescription
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class Module
|
|
86
|
+
def describe_self
|
|
87
|
+
coll = ContainerDescription.new
|
|
88
|
+
#
|
|
89
|
+
# we want mixed in modules
|
|
90
|
+
#
|
|
91
|
+
ancestors.each {|m|
|
|
92
|
+
next if m == self or m.is_a?(Class)
|
|
93
|
+
coll.push(*m.describe_self)
|
|
94
|
+
}
|
|
95
|
+
methods.each {|m|
|
|
96
|
+
coll << send(m) if m.to_s.start_with?('describe_') and m.to_s != 'describe_self'
|
|
97
|
+
}
|
|
98
|
+
coll
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
=begin
|
|
102
|
+
def describe(attribute, type)
|
|
103
|
+
self.class.send(:define_method, "describe_#{attribute}") do
|
|
104
|
+
description = Description::TYPE_MAP[type] || Description
|
|
105
|
+
d = description.new
|
|
106
|
+
d.accessor ||= SymbolAccessor.new(attribute)
|
|
107
|
+
d
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
=end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class Object
|
|
114
|
+
def describe_self
|
|
115
|
+
self.class.describe_self
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
module Mixin
|
|
120
|
+
attr_accessor :mixin
|
|
121
|
+
def self.describe_mixin
|
|
122
|
+
"blah"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class Person
|
|
127
|
+
attr_accessor :name
|
|
128
|
+
|
|
129
|
+
def self.describe_name
|
|
130
|
+
#StringDescription.new.selector_accessor(:name).label('Name').required
|
|
131
|
+
|
|
132
|
+
StringDescription.new {|s|
|
|
133
|
+
s.selector_accessor(:name)
|
|
134
|
+
s.label = 'Name'
|
|
135
|
+
s.required
|
|
136
|
+
s.add_condition(proc {|value| value.size <= 5}, 'too long')
|
|
137
|
+
}
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class Recipe
|
|
142
|
+
attr_accessor :a, :b
|
|
143
|
+
|
|
144
|
+
#describe :a, String
|
|
145
|
+
#describe :b, String
|
|
146
|
+
|
|
147
|
+
#def self.describe_b
|
|
148
|
+
# "bello"
|
|
149
|
+
#end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
=begin
|
|
153
|
+
recipe = Recipe.new
|
|
154
|
+
Recipe.describe_self.each do |r|
|
|
155
|
+
r.accessor[recipe] = rand()
|
|
156
|
+
p r.accessor[recipe]
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
p recipe
|
|
160
|
+
=end
|
|
161
|
+
|
|
162
|
+
#p Person.describe_self
|
|
163
|
+
|
|
164
|
+
a = Person.new
|
|
165
|
+
a.name = "Michael Neumann"
|
|
166
|
+
|
|
167
|
+
a.describe_self.each {|d|
|
|
168
|
+
print "#{d.label}: "
|
|
169
|
+
puts d.to_string(d.accessor[a])
|
|
170
|
+
}
|