wee 0.5.0 → 0.6.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/ChangeLog +132 -0
- data/INSTALL +13 -3
- data/README +3 -3
- data/Rakefile +5 -1
- data/bin/wee +100 -0
- data/doc/rdoc/classes/Array.html +12 -12
- data/doc/rdoc/classes/Cache/StorageCache.html +38 -38
- data/doc/rdoc/classes/Cache/Strategy/CapacityBounded.html +30 -30
- data/doc/rdoc/classes/Cache/Strategy/LFU.html +24 -24
- data/doc/rdoc/classes/Cache/Strategy/LRU.html +24 -24
- data/doc/rdoc/classes/Cache/Strategy/Unbounded.html +24 -24
- data/doc/rdoc/classes/Enumerable.html +6 -6
- data/doc/rdoc/classes/Main.html +265 -0
- data/doc/rdoc/classes/Object.html +12 -12
- data/doc/rdoc/classes/OgApplication.html +2 -2
- data/doc/rdoc/classes/OgScaffolder.html +444 -64
- data/doc/rdoc/classes/OgScaffolder/Editor.html +490 -0
- data/doc/rdoc/classes/OgSession.html +4 -4
- data/doc/rdoc/classes/Recipe.html +113 -0
- data/doc/rdoc/classes/String.html +12 -12
- data/doc/rdoc/classes/Struct.html +12 -12
- data/doc/rdoc/classes/Wee.html +10 -1
- data/doc/rdoc/classes/Wee/AnswerDecoration.html +9 -9
- data/doc/rdoc/classes/Wee/Application.html +48 -47
- data/doc/rdoc/classes/Wee/Brush.html +19 -23
- data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +17 -14
- data/doc/rdoc/classes/Wee/Brush/FileUploadTag.html +20 -14
- data/doc/rdoc/classes/Wee/Brush/FormTag.html +25 -21
- data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +12 -12
- data/doc/rdoc/classes/Wee/Brush/GenericSingleTagBrush.html +7 -7
- data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +234 -100
- data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +12 -12
- data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +28 -22
- data/doc/rdoc/classes/Wee/Brush/ImageTag.html +23 -24
- data/doc/rdoc/classes/Wee/Brush/InputTag.html +14 -14
- data/doc/rdoc/classes/Wee/Brush/JavascriptTag.html +7 -7
- data/doc/rdoc/classes/Wee/Brush/Page.html +14 -14
- data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +33 -57
- data/doc/rdoc/classes/Wee/Brush/SelectListTag/SelectListCallback.html +154 -0
- data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +7 -7
- data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +20 -14
- data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +14 -14
- data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +7 -7
- data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +42 -42
- data/doc/rdoc/classes/Wee/Brush/TableTag.html +7 -7
- data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +27 -21
- data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +20 -14
- data/doc/rdoc/classes/Wee/CallbackRegistry.html +64 -36
- data/doc/rdoc/classes/Wee/CallbackStream.html +21 -21
- data/doc/rdoc/classes/Wee/Canvas.html +24 -24
- data/doc/rdoc/classes/Wee/Component.html +179 -151
- data/doc/rdoc/classes/Wee/Component/OnAnswer.html +12 -12
- data/doc/rdoc/classes/Wee/Decoration.html +42 -42
- data/doc/rdoc/classes/Wee/Delegate.html +27 -27
- data/doc/rdoc/classes/Wee/ErrorResponse.html +14 -14
- data/doc/rdoc/classes/Wee/FormDecoration.html +6 -6
- data/doc/rdoc/classes/Wee/GenericResponse.html +7 -7
- data/doc/rdoc/classes/Wee/HtmlCanvas.html +326 -219
- data/doc/rdoc/classes/Wee/HtmlWriter.html +40 -40
- data/doc/rdoc/classes/Wee/LiteralMethodCallback.html +19 -19
- data/doc/rdoc/classes/Wee/Md5IdGenerator.html +181 -0
- data/doc/rdoc/classes/Wee/MessageBox.html +12 -12
- data/doc/rdoc/classes/Wee/PageDecoration.html +18 -18
- data/doc/rdoc/classes/Wee/PagelessApplication.html +152 -0
- data/doc/rdoc/classes/Wee/PagelessRequest.html +177 -0
- data/doc/rdoc/classes/Wee/PagelessSession.html +320 -0
- data/doc/rdoc/classes/Wee/Presenter.html +145 -89
- data/doc/rdoc/classes/Wee/RedirectResponse.html +7 -7
- data/doc/rdoc/classes/Wee/RefreshResponse.html +7 -7
- data/doc/rdoc/classes/Wee/Request.html +116 -50
- data/doc/rdoc/classes/Wee/RequestHandler.html +31 -31
- data/doc/rdoc/classes/Wee/Response.html +76 -28
- data/doc/rdoc/classes/Wee/Session.html +129 -506
- data/doc/rdoc/classes/Wee/SimpleIdGenerator.html +22 -40
- data/doc/rdoc/classes/Wee/Snapshot.html +19 -19
- data/doc/rdoc/classes/Wee/Utils.html +70 -17
- data/doc/rdoc/classes/Wee/Utils/LRUCache.html +6 -6
- data/doc/rdoc/classes/Wee/ValueHolder.html +18 -18
- data/doc/rdoc/classes/Wee/WEBrickAdaptor.html +82 -49
- data/doc/rdoc/classes/Wee/WrapperDecoration.html +6 -6
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/INSTALL.html +17 -5
- data/doc/rdoc/files/README.html +9 -11
- data/doc/rdoc/files/lib/wee/adaptors/webrick_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/application_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/components/page_decoration_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/continuation/session_rb.html +1 -3
- data/doc/rdoc/files/lib/wee/core/callback_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/core/component_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/core_rb.html +3 -3
- data/doc/rdoc/files/lib/wee/databases/og/application_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/databases/og/old_scaffolder_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/databases/og/scaffolder_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/databases/og/session_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/databases/og_rb.html +4 -1
- data/doc/rdoc/files/lib/wee/idgen/md5_rb.html +115 -0
- data/doc/rdoc/files/lib/wee/idgen/simple_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/pageless/application_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/pageless/request_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/pageless/session_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/pageless_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/renderer/html/brushes_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/renderer/html/canvas_rb.html +8 -1
- data/doc/rdoc/files/lib/wee/request_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/response_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/session_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/skeleton/og/components/main_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/skeleton/og/conf/db_rb.html +114 -0
- data/doc/rdoc/files/lib/wee/skeleton/og/models/recipe_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/skeleton/og/run_rb.html +115 -0
- data/doc/rdoc/files/lib/wee/skeleton/simple/components/main_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/skeleton/simple/run_rb.html +111 -0
- data/doc/rdoc/files/lib/wee/template_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/utils/autoreload_rb.html +1 -1
- data/doc/rdoc/files/lib/wee/utils/helper_rb.html +1 -1
- data/doc/rdoc/files/lib/wee_rb.html +4 -2
- data/doc/rdoc/fr_class_index.html +8 -4
- data/doc/rdoc/fr_file_index.html +17 -1
- data/doc/rdoc/fr_method_index.html +312 -267
- data/examples/live-update.rb +1 -1
- data/install.rb +14 -0
- data/lib/wee.rb +6 -2
- data/lib/wee/adaptors/webrick.rb +17 -5
- data/lib/wee/application.rb +2 -1
- data/lib/wee/continuation/session.rb +1 -146
- data/lib/wee/core/callback.rb +11 -5
- data/lib/wee/core/component.rb +14 -10
- data/lib/wee/databases/og.rb +3 -113
- data/lib/wee/databases/og/application.rb +3 -0
- data/lib/wee/databases/og/old_scaffolder.rb +98 -0
- data/lib/wee/databases/og/scaffolder.rb +174 -0
- data/lib/wee/databases/og/session.rb +9 -0
- data/lib/wee/idgen/md5.rb +21 -0
- data/lib/wee/{idgen.rb → idgen/simple.rb} +2 -4
- data/lib/wee/pageless.rb +3 -0
- data/lib/wee/pageless/application.rb +9 -0
- data/lib/wee/pageless/request.rb +15 -0
- data/lib/wee/pageless/session.rb +89 -0
- data/lib/wee/renderer/html/brushes.rb +100 -115
- data/lib/wee/renderer/html/canvas.rb +32 -2
- data/lib/wee/request.rb +36 -24
- data/lib/wee/response.rb +8 -1
- data/lib/wee/session.rb +13 -7
- data/lib/wee/skeleton/og/README +38 -0
- data/lib/wee/skeleton/og/components/main.rb +16 -0
- data/lib/wee/skeleton/og/conf/db.rb +8 -0
- data/lib/wee/skeleton/og/models/recipe.rb +5 -0
- data/lib/wee/skeleton/og/run.rb +23 -0
- data/lib/wee/skeleton/simple/README +32 -0
- data/lib/wee/skeleton/simple/components/main.rb +25 -0
- data/lib/wee/skeleton/simple/run.rb +12 -0
- data/lib/wee/template.rb +28 -0
- data/lib/wee/utils/autoreload.rb +29 -0
- data/lib/wee/utils/helper.rb +9 -5
- data/test/test_request.rb +4 -3
- data/wee.gemspec +3 -1
- metadata +91 -22
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
class OgScaffolder < Wee::Component
|
|
2
|
+
|
|
3
|
+
def initialize(domain_class)
|
|
4
|
+
super()
|
|
5
|
+
@domain_class = domain_class
|
|
6
|
+
@attributes = domain_class.__props.map {|a| a.name}.reject {|a| a == 'oid'}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def delete(obj)
|
|
10
|
+
call Wee::MessageBox.new('Really delete?'), :confirm_delete, obj
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def confirm_delete(confirmed, obj)
|
|
14
|
+
if confirmed
|
|
15
|
+
@objs.delete(obj)
|
|
16
|
+
obj.delete!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def edit(obj)
|
|
21
|
+
@edit = obj
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def save(obj)
|
|
25
|
+
obj.save!
|
|
26
|
+
@edit = nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def cancel
|
|
30
|
+
@objs.delete(@edit) if @edit and @edit.oid.nil?
|
|
31
|
+
@edit = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def refresh
|
|
35
|
+
@objs = @domain_class.all || []
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create
|
|
39
|
+
@objs << (@edit = @domain_class.new)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def render
|
|
43
|
+
refresh if @objs.nil?
|
|
44
|
+
|
|
45
|
+
r.h1 "#{ @domain_class } List"
|
|
46
|
+
r.anchor.callback { refresh }.with("Refresh")
|
|
47
|
+
|
|
48
|
+
r.form do
|
|
49
|
+
r.table.border(1).with {
|
|
50
|
+
|
|
51
|
+
r.table_row.with {
|
|
52
|
+
@attributes.each {|a|
|
|
53
|
+
r.table_header.with {
|
|
54
|
+
r.bold(a.capitalize)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
r.table_header.with(" ")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@objs.each {|o|
|
|
61
|
+
r.table_row.with do
|
|
62
|
+
if @edit == o
|
|
63
|
+
|
|
64
|
+
@attributes.each { |attr|
|
|
65
|
+
r.table_data.with { r.text_input.callback {|v| o.send(attr+"=",v) }.value(o.send(attr)) }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
r.table_data.with {
|
|
69
|
+
r.submit_button.callback { save(o) }.value("Save")
|
|
70
|
+
r.space
|
|
71
|
+
r.submit_button.callback { cancel() }.value("Cancel")
|
|
72
|
+
r.space
|
|
73
|
+
r.anchor.callback { delete(o) }.with("Delete")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
else
|
|
77
|
+
|
|
78
|
+
@attributes.each { |attr|
|
|
79
|
+
r.table_data(o.send(attr))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
r.table_data.with {
|
|
83
|
+
r.anchor.callback { edit(o) }.with("Edit")
|
|
84
|
+
r.space
|
|
85
|
+
r.anchor.callback { delete(o) }.with("Delete")
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
r.anchor.callback { create() }.with("Add new #{ @domain_class }")
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# This is a Rails-like scaffolder for use with Og (http://navel.gr/nitro)
|
|
2
|
+
# domain objects.
|
|
3
|
+
|
|
4
|
+
class OgScaffolder < Wee::Component
|
|
5
|
+
def initialize(domain_class)
|
|
6
|
+
super()
|
|
7
|
+
@domain_class = domain_class
|
|
8
|
+
# DON'T use @properties here as it is already used by Wee
|
|
9
|
+
@props = @domain_class.__props.reject {|a| a.name == 'oid'}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def render
|
|
13
|
+
r.h1 "List #{ @domain_class }"
|
|
14
|
+
r.paragraph
|
|
15
|
+
r.table.border(1).with {
|
|
16
|
+
render_header
|
|
17
|
+
render_body
|
|
18
|
+
}
|
|
19
|
+
r.paragraph
|
|
20
|
+
r.anchor.callback(:add).with("Add new #{ @domain_class }")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def render_header
|
|
24
|
+
r.table_row.with {
|
|
25
|
+
@props.each {|prop|
|
|
26
|
+
render_property_header(prop)
|
|
27
|
+
}
|
|
28
|
+
render_action_header
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def render_action_header
|
|
33
|
+
r.paragraph
|
|
34
|
+
r.table_header.with { r.space(2) } # the action column
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def render_property_header(prop)
|
|
38
|
+
r.table_header.with {
|
|
39
|
+
r.bold(prop.name.to_s.capitalize)
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def render_body
|
|
44
|
+
domain_objects.each {|obj| render_object(obj) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def render_object(obj)
|
|
48
|
+
r.table_row {
|
|
49
|
+
@props.each {|prop| render_property(obj, prop) }
|
|
50
|
+
render_action(obj)
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def render_action(obj)
|
|
55
|
+
r.table_data.with {
|
|
56
|
+
r.anchor.callback(:edit, obj).with("Edit")
|
|
57
|
+
r.space
|
|
58
|
+
r.anchor.callback(:destroy, obj).with("Destroy")
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def render_property(obj, prop)
|
|
63
|
+
r.table_data(obj.send(prop.name).to_s)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def edit(obj)
|
|
67
|
+
call Editor.new(obj).add_decoration(Wee::FormDecoration.new)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def add
|
|
71
|
+
call Editor.new(@domain_class.new, "Create").
|
|
72
|
+
add_decoration(Wee::FormDecoration.new)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def destroy(obj)
|
|
76
|
+
call Wee::MessageBox.new('Do you really want to destroy the object?'),
|
|
77
|
+
:confirm_destroy, obj
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def confirm_destroy(obj, confirmed)
|
|
81
|
+
obj.delete! if confirmed
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def domain_objects
|
|
85
|
+
@domain_class.all || []
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class OgScaffolder::Editor < Wee::Component
|
|
90
|
+
|
|
91
|
+
def initialize(domain_object, action="Edit")
|
|
92
|
+
super()
|
|
93
|
+
@domain_object = domain_object
|
|
94
|
+
@action = action
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def render
|
|
98
|
+
render_header
|
|
99
|
+
each_property {|prop|
|
|
100
|
+
render_property(prop) unless prop.name == 'oid'
|
|
101
|
+
}
|
|
102
|
+
render_buttons
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def render_header
|
|
106
|
+
r.h1 "#{ @action } #{ @domain_object.class }"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def render_property(prop)
|
|
110
|
+
render_label(prop)
|
|
111
|
+
|
|
112
|
+
if prop.klass.ancestors.include?(Numeric)
|
|
113
|
+
render_numeric(prop)
|
|
114
|
+
elsif prop.klass.ancestors.include?(String)
|
|
115
|
+
render_string(prop)
|
|
116
|
+
elsif prop.klass.ancestors.include?(TrueClass)
|
|
117
|
+
render_bool(prop)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def render_numeric(prop)
|
|
122
|
+
r.text_input.value(get_value_of(prop)).callback(:set_value_of, prop)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def render_string(prop)
|
|
126
|
+
if prop.meta[:ui] == :textarea
|
|
127
|
+
r.text_area.callback(:set_value_of, prop).with(get_value_of(prop))
|
|
128
|
+
else
|
|
129
|
+
r.text_input.value(get_value_of(prop)).callback(:set_value_of, prop)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def render_bool(prop)
|
|
134
|
+
selected = [ get_value_of(prop) ? true : false ]
|
|
135
|
+
r.select_list([true, false]).labels(["Yes", "No"]).selected(selected).
|
|
136
|
+
callback {|choosen| set_value_of(prop, choosen.first) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def render_buttons
|
|
140
|
+
r.paragraph
|
|
141
|
+
r.submit_button.value('Save').callback(:save)
|
|
142
|
+
r.space
|
|
143
|
+
r.submit_button.value('Cancel').callback(:cancel)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def render_label(prop)
|
|
147
|
+
r.paragraph
|
|
148
|
+
r.text prop.name.capitalize
|
|
149
|
+
r.break
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
|
|
154
|
+
def each_property(&block)
|
|
155
|
+
@domain_object.class.__props.each(&block)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def get_value_of(prop)
|
|
159
|
+
@domain_object.send(prop.symbol)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def set_value_of(prop, value)
|
|
163
|
+
@domain_object.send(prop.symbol.to_s + "=", value)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def save
|
|
167
|
+
@domain_object.save!
|
|
168
|
+
answer @domain_object
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def cancel
|
|
172
|
+
answer nil
|
|
173
|
+
end
|
|
174
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Returned ids might not be unique, but it should be very hard to guess the
|
|
2
|
+
# next id.
|
|
3
|
+
|
|
4
|
+
require 'digest/md5'
|
|
5
|
+
|
|
6
|
+
class Wee::Md5IdGenerator
|
|
7
|
+
def initialize(salt='wee')
|
|
8
|
+
@salt = salt
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def next
|
|
12
|
+
now = Time.now
|
|
13
|
+
md5 = Digest::MD5.new
|
|
14
|
+
md5.update(now.to_s)
|
|
15
|
+
md5.update(now.usec.to_s)
|
|
16
|
+
md5.update(rand(0).to_s)
|
|
17
|
+
md5.update($$.to_s)
|
|
18
|
+
md5.update(@salt.to_s)
|
|
19
|
+
md5.hexdigest
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/wee/pageless.rb
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class Wee::PagelessApplication < Wee::Application
|
|
2
|
+
def request_handler_expired(context)
|
|
3
|
+
context.response = Wee::RedirectResponse.new(context.request.application_path)
|
|
4
|
+
# TODO: depends on WEBrick
|
|
5
|
+
cookie = WEBrick::Cookie.new('SID', '')
|
|
6
|
+
cookie.max_age = 0
|
|
7
|
+
context.response.cookies << cookie
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class Wee::PagelessRequest < Wee::Request
|
|
2
|
+
|
|
3
|
+
def build_url(request_handler_id=nil, page_id=nil, callback_id=nil)
|
|
4
|
+
url = ""
|
|
5
|
+
url << @app_path
|
|
6
|
+
url << ('?' + callback_id) if callback_id
|
|
7
|
+
return url
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parse_path
|
|
11
|
+
if sid = @cookies.find {|c| c.name == 'SID'}
|
|
12
|
+
@request_handler_id = sid.value
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
# A session class, which does not have a page-store and as such cannot
|
|
4
|
+
# backtrack.
|
|
5
|
+
|
|
6
|
+
class Wee::PagelessSession < Wee::Session
|
|
7
|
+
attr_accessor :root_component
|
|
8
|
+
undef page_store
|
|
9
|
+
|
|
10
|
+
attr_accessor :callbacks
|
|
11
|
+
alias current_callbacks callbacks
|
|
12
|
+
|
|
13
|
+
def initialize(&block)
|
|
14
|
+
Thread.current[:wee_session] = self
|
|
15
|
+
|
|
16
|
+
# to serialize the requests we need a mutex
|
|
17
|
+
@mutex = Mutex.new
|
|
18
|
+
|
|
19
|
+
block.call(self)
|
|
20
|
+
|
|
21
|
+
raise ArgumentError, "No root component specified" if @root_component.nil?
|
|
22
|
+
|
|
23
|
+
super()
|
|
24
|
+
ensure
|
|
25
|
+
Thread.current[:wee_session] = nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def process_request
|
|
29
|
+
p @context.request.fields if $DEBUG
|
|
30
|
+
|
|
31
|
+
if @context.request.fields.empty?
|
|
32
|
+
|
|
33
|
+
# No action/inputs were specified -> render page
|
|
34
|
+
#
|
|
35
|
+
# 1. Reset the action/input fields (as they are regenerated in the
|
|
36
|
+
# rendering process).
|
|
37
|
+
# 2. Render the page (respond).
|
|
38
|
+
# 3. Store the page back into the store
|
|
39
|
+
|
|
40
|
+
new_callbacks = Wee::CallbackRegistry.new(Wee::SimpleIdGenerator.new)
|
|
41
|
+
respond(@context, new_callbacks) # render
|
|
42
|
+
self.callbacks = new_callbacks
|
|
43
|
+
|
|
44
|
+
else
|
|
45
|
+
|
|
46
|
+
# Actions/inputs were specified.
|
|
47
|
+
#
|
|
48
|
+
# We process the request and invoke actions/inputs. Then we generate a
|
|
49
|
+
# new page view.
|
|
50
|
+
|
|
51
|
+
callback_stream = Wee::CallbackStream.new(self.callbacks, @context.request.fields)
|
|
52
|
+
|
|
53
|
+
if callback_stream.all_of_type(:action).size > 1
|
|
54
|
+
raise "Not allowed to specify more than one action callback"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
live_update_response = catch(:wee_live_update) {
|
|
58
|
+
catch(:wee_back_to_session) {
|
|
59
|
+
@root_component.process_callbacks_chain(callback_stream)
|
|
60
|
+
}
|
|
61
|
+
nil
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if live_update_response
|
|
65
|
+
@context.response = live_update_response
|
|
66
|
+
else
|
|
67
|
+
handle_new_page_view(@context)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def handle_new_page_view(context)
|
|
77
|
+
redirect_url = context.request.build_url(context.request.request_handler_id, nil)
|
|
78
|
+
set_response(context, Wee::RedirectResponse.new(redirect_url))
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def set_response(context, response)
|
|
82
|
+
# TODO: depends on WEBrick!
|
|
83
|
+
response.cookies << WEBrick::Cookie.new('SID', self.id)
|
|
84
|
+
response.header.delete('Expire')
|
|
85
|
+
response.header['Pragma'] = 'No-Cache'
|
|
86
|
+
super
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|