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.
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
+ }