wee 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/TODO +31 -0
  2. data/benchmark.rb +37 -0
  3. data/demo.ru +11 -0
  4. data/doc/rdoc/classes/Array.html +22 -26
  5. data/doc/rdoc/classes/Hash.html +22 -26
  6. data/doc/rdoc/classes/Object.html +21 -26
  7. data/doc/rdoc/classes/String.html +19 -87
  8. data/doc/rdoc/classes/Struct.html +22 -26
  9. data/doc/rdoc/classes/Wee.html +75 -206
  10. data/doc/rdoc/classes/Wee/AnswerDecoration.html +35 -66
  11. data/doc/rdoc/classes/Wee/AnswerDecoration/Answer.html +28 -46
  12. data/doc/rdoc/classes/Wee/Application.html +63 -114
  13. data/doc/rdoc/classes/Wee/Application/SessionCache.html +30 -44
  14. data/doc/rdoc/classes/Wee/Brush.html +52 -101
  15. data/doc/rdoc/classes/Wee/Brush/ActionInputTag.html +29 -51
  16. data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +44 -101
  17. data/doc/rdoc/classes/Wee/Brush/CheckboxTag.html +43 -76
  18. data/doc/rdoc/classes/Wee/Brush/FileUploadTag.html +29 -46
  19. data/doc/rdoc/classes/Wee/Brush/FormTag.html +48 -110
  20. data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +30 -42
  21. data/doc/rdoc/classes/Wee/Brush/GenericSingleTagBrush.html +37 -58
  22. data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +93 -210
  23. data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +38 -63
  24. data/doc/rdoc/classes/Wee/Brush/HiddenInputTag.html +29 -45
  25. data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +35 -52
  26. data/doc/rdoc/classes/Wee/Brush/ImageTag.html +28 -61
  27. data/doc/rdoc/classes/Wee/Brush/InputTag.html +34 -107
  28. data/doc/rdoc/classes/Wee/Brush/JavascriptTag.html +28 -54
  29. data/doc/rdoc/classes/Wee/Brush/Page.html +39 -73
  30. data/doc/rdoc/classes/Wee/Brush/PasswordInputTag.html +29 -45
  31. data/doc/rdoc/classes/Wee/Brush/RadioButtonTag.html +54 -98
  32. data/doc/rdoc/classes/Wee/Brush/RadioGroup.html +46 -84
  33. data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +87 -187
  34. data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +29 -56
  35. data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +29 -45
  36. data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +28 -55
  37. data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +28 -55
  38. data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +56 -113
  39. data/doc/rdoc/classes/Wee/Brush/TableTag.html +27 -58
  40. data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +48 -140
  41. data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +29 -45
  42. data/doc/rdoc/classes/Wee/CallAnswerMixin.html +51 -79
  43. data/doc/rdoc/classes/Wee/CallbackMixin.html +44 -77
  44. data/doc/rdoc/classes/Wee/CallbackRegistry.html +69 -125
  45. data/doc/rdoc/classes/Wee/Callbacks.html +43 -82
  46. data/doc/rdoc/classes/Wee/Component.html +142 -292
  47. data/doc/rdoc/classes/Wee/Decoration.html +85 -141
  48. data/doc/rdoc/classes/Wee/DecorationMixin.html +111 -118
  49. data/doc/rdoc/classes/Wee/Delegate.html +72 -115
  50. data/doc/rdoc/classes/Wee/DupReplaceSnapshotMixin.html +37 -54
  51. data/doc/rdoc/classes/Wee/ErrorResponse.html +31 -48
  52. data/doc/rdoc/classes/Wee/FormDecoration.html +32 -46
  53. data/doc/rdoc/classes/Wee/GenericResponse.html +30 -50
  54. data/doc/rdoc/classes/Wee/HtmlCanvas.html +209 -562
  55. data/doc/rdoc/classes/Wee/HtmlDocument.html +51 -91
  56. data/doc/rdoc/classes/Wee/HtmlWriter.html +76 -156
  57. data/doc/rdoc/classes/Wee/IdGenerator.html +28 -44
  58. data/doc/rdoc/classes/Wee/IdGenerator/Secure.html +53 -95
  59. data/doc/rdoc/classes/Wee/IdGenerator/Sequential.html +37 -63
  60. data/doc/rdoc/classes/Wee/JQuery.html +36 -64
  61. data/doc/rdoc/classes/Wee/LRUCache.html +94 -189
  62. data/doc/rdoc/classes/Wee/LRUCache/Item.html +30 -42
  63. data/doc/rdoc/classes/Wee/ObjectSnapshotMixin.html +37 -54
  64. data/doc/rdoc/classes/Wee/PageDecoration.html +48 -79
  65. data/doc/rdoc/classes/Wee/Presenter.html +86 -143
  66. data/doc/rdoc/classes/Wee/RedirectResponse.html +31 -49
  67. data/doc/rdoc/classes/Wee/RefreshResponse.html +34 -48
  68. data/doc/rdoc/classes/Wee/Renderer.html +56 -125
  69. data/doc/rdoc/classes/Wee/Request.html +57 -115
  70. data/doc/rdoc/classes/Wee/Response.html +24 -26
  71. data/doc/rdoc/classes/Wee/Session.html +137 -292
  72. data/doc/rdoc/classes/Wee/Session/AbortCallbackProcessing.html +29 -46
  73. data/doc/rdoc/classes/Wee/Session/MutexSerializer.html +29 -42
  74. data/doc/rdoc/classes/Wee/Session/Page.html +22 -21
  75. data/doc/rdoc/classes/Wee/Session/ThreadSerializer.html +36 -60
  76. data/doc/rdoc/classes/Wee/State.html +57 -105
  77. data/doc/rdoc/classes/Wee/State/Snapshot.html +22 -21
  78. data/doc/rdoc/classes/Wee/State/SnapshotIVars.html +22 -21
  79. data/doc/rdoc/classes/Wee/StructSnapshotMixin.html +37 -54
  80. data/doc/rdoc/classes/Wee/WrapperDecoration.html +42 -68
  81. data/doc/rdoc/created.rid +1 -1
  82. data/doc/rdoc/files/README_rdoc.html +26 -17
  83. data/doc/rdoc/files/lib/wee/application_rb.html +25 -19
  84. data/doc/rdoc/files/lib/wee/call_answer_rb.html +23 -12
  85. data/doc/rdoc/files/lib/wee/callback_rb.html +23 -12
  86. data/doc/rdoc/files/lib/wee/component_rb.html +25 -19
  87. data/doc/rdoc/files/lib/wee/decoration_rb.html +23 -15
  88. data/doc/rdoc/files/lib/wee/html_brushes_rb.html +23 -12
  89. data/doc/rdoc/files/lib/wee/html_canvas_rb.html +23 -15
  90. data/doc/rdoc/files/lib/wee/html_document_rb.html +23 -15
  91. data/doc/rdoc/files/lib/wee/html_writer_rb.html +23 -15
  92. data/doc/rdoc/files/lib/wee/id_generator_rb.html +24 -17
  93. data/doc/rdoc/files/lib/wee/jquery/jquery_rb.html +23 -12
  94. data/doc/rdoc/files/lib/wee/jquery_rb.html +23 -15
  95. data/doc/rdoc/files/lib/wee/lru_cache_rb.html +23 -12
  96. data/doc/rdoc/files/lib/wee/presenter_rb.html +23 -12
  97. data/doc/rdoc/files/lib/wee/renderer_rb.html +23 -12
  98. data/doc/rdoc/files/lib/wee/request_rb.html +23 -15
  99. data/doc/rdoc/files/lib/wee/response_rb.html +24 -17
  100. data/doc/rdoc/files/lib/wee/session_rb.html +26 -21
  101. data/doc/rdoc/files/lib/wee/state_rb.html +23 -12
  102. data/doc/rdoc/files/lib/wee_rb.html +37 -47
  103. data/doc/rdoc/fr_class_index.html +12 -86
  104. data/doc/rdoc/fr_file_index.html +12 -30
  105. data/doc/rdoc/fr_method_index.html +242 -473
  106. data/doc/rdoc/index.html +8 -5
  107. data/doc/rdoc/rdoc-style.css +119 -210
  108. data/examples/ObjectSpaceBrowser.rb +4 -4
  109. data/examples/TODO +21 -0
  110. data/examples/ajax.rb +6 -4
  111. data/examples/blog.rb +42 -0
  112. data/examples/demo.rb +5 -3
  113. data/examples/demo/calculator.rb +3 -3
  114. data/examples/demo/calendar.rb +4 -4
  115. data/examples/demo/counter.rb +2 -2
  116. data/examples/demo/editable_counter.rb +2 -2
  117. data/examples/demo/example.rb +25 -16
  118. data/examples/demo/window.rb +10 -3
  119. data/examples/hw2.rb +17 -0
  120. data/examples/recipe/description.rb +170 -0
  121. data/examples/recipe/migrations/001_create_recipes.rb +13 -0
  122. data/examples/recipe/model.rb +27 -0
  123. data/examples/recipe/models/recipe.rb +18 -0
  124. data/examples/recipe/recipe_editor.rb +28 -0
  125. data/lib/wee.rb +1 -7
  126. data/lib/wee/component.rb +37 -74
  127. data/lib/wee/decoration.rb +16 -15
  128. data/lib/wee/html_brushes.rb +16 -17
  129. data/lib/wee/presenter.rb +2 -1
  130. data/lib/wee/response.rb +4 -4
  131. data/lib/wee/session.rb +2 -2
  132. data/lib/wee/state.rb +2 -2
  133. data/test/t.rb +67 -0
  134. data/wee.gemspec +1 -1
  135. metadata +157 -167
@@ -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
@@ -10,9 +10,9 @@ class AjaxCounter < Wee::Component
10
10
  @counter = 0
11
11
  end
12
12
 
13
- def backtrack(state)
13
+ def state(s)
14
14
  super
15
- state.add_ivar(self, :@counter, @counter)
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
- @cs = (1..10).map { add_child AjaxCounter.new }
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
- @cs.each {|c| r.render(c); r.break}
45
+ @counters.each {|c| r.render(c); r.break}
44
46
  }
45
47
  }
46
48
  end
@@ -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)
@@ -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
- @components.each {|c| add_child c.component }
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
@@ -7,10 +7,10 @@ class Calculator < Wee::Component
7
7
  @input = ""
8
8
  end
9
9
 
10
- def backtrack(state)
10
+ def state(s)
11
11
  super
12
- state.add(@number_stack)
13
- state.add(@input)
12
+ s.add(@number_stack)
13
+ s.add(@input)
14
14
  end
15
15
 
16
16
  def render(r)
@@ -69,9 +69,9 @@ class MiniCalendar < Wee::Component
69
69
 
70
70
  # Backtrack state
71
71
  #
72
- def backtrack(state)
72
+ def state(s)
73
73
  super
74
- state.add(self)
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 backtrack(state)
302
+ def state(s)
303
303
  super
304
- state.add(self)
304
+ s.add(self)
305
305
  end
306
306
 
307
307
  # Render calendar icon
@@ -6,9 +6,9 @@ class Counter < Wee::Component
6
6
  @count = initial_count
7
7
  end
8
8
 
9
- def backtrack(state)
9
+ def state(s)
10
10
  super
11
- state.add_ivar(self, :@count, @count)
11
+ s.add_ivar(self, :@count, @count)
12
12
  end
13
13
 
14
14
  def dec
@@ -9,9 +9,9 @@ class EditableCounter < Counter
9
9
  @show_edit_field = false
10
10
  end
11
11
 
12
- def backtrack(state)
12
+ def state(s)
13
13
  super
14
- state.add_ivar(self, :@show_edit_field, @show_edit_field)
14
+ s.add_ivar(self, :@show_edit_field, @show_edit_field)
15
15
  end
16
16
 
17
17
  def render_count(r)
@@ -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 backtrack(state)
18
+ def state(s)
15
19
  super
16
- state.add(self)
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
- add_child Window.new {|w|
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.add_child EditableCounter.new(i)
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 backtrack(state)
79
+ def children
80
+ [@val_inp, *@counters]
81
+ end
82
+
83
+ def state(s)
77
84
  super
78
- backtrack_children(state)
79
- backtrack_decoration(state)
80
- state.add(@arr)
81
- state.add(@text)
82
-
83
- state.add(@list1)
84
- state.add(@selected1)
85
- state.add(@list2)
86
- state.add(@selected2)
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
@@ -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 backtrack(state)
13
+ def <<(c)
14
+ @children << c
15
+ end
16
+
17
+ def children() @children end
18
+
19
+ def state(s)
13
20
  super
14
- state.add_ivar(self, :@status, @status)
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
- each_child do |child|
48
+ for child in self.children do
42
49
  r.render(child)
43
50
  end
44
51
  end
@@ -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
+ }