wee 0.10.0 → 2.0.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/README.rdoc +127 -0
- data/Rakefile +11 -32
- data/doc/rdoc/classes/Array.html +28 -24
- data/doc/rdoc/classes/Hash.html +28 -24
- data/doc/rdoc/classes/Object.html +37 -84
- data/doc/rdoc/classes/String.html +89 -21
- data/doc/rdoc/classes/Struct.html +32 -82
- data/doc/rdoc/classes/Wee.html +285 -86
- data/doc/rdoc/classes/Wee/AnswerDecoration.html +111 -48
- data/doc/rdoc/classes/Wee/{Context.html → AnswerDecoration/Answer.html} +61 -51
- data/doc/rdoc/classes/Wee/Application.html +161 -322
- data/doc/rdoc/classes/Wee/Application/SessionCache.html +162 -0
- data/doc/rdoc/classes/Wee/Brush.html +147 -62
- data/doc/rdoc/classes/{Enumerable.html → Wee/Brush/ActionInputTag.html} +68 -41
- data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +150 -100
- data/doc/rdoc/classes/Wee/Brush/CheckboxTag.html +132 -46
- data/doc/rdoc/classes/Wee/Brush/FileUploadTag.html +63 -41
- data/doc/rdoc/classes/Wee/Brush/FormTag.html +184 -78
- data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +48 -65
- data/doc/rdoc/classes/Wee/Brush/GenericSingleTagBrush.html +83 -37
- data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +334 -310
- data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +74 -54
- data/doc/rdoc/classes/Wee/Brush/HiddenInputTag.html +58 -43
- data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +64 -74
- data/doc/rdoc/classes/Wee/Brush/ImageTag.html +109 -86
- data/doc/rdoc/classes/Wee/Brush/InputTag.html +205 -45
- data/doc/rdoc/classes/Wee/Brush/JavascriptTag.html +96 -34
- data/doc/rdoc/classes/Wee/Brush/Page.html +129 -67
- data/doc/rdoc/classes/Wee/{Utils/LRUCache.html → Brush/PasswordInputTag.html} +65 -38
- data/doc/rdoc/classes/Wee/Brush/RadioButtonTag.html +132 -78
- data/doc/rdoc/classes/Wee/Brush/{RadioButtonTag/RadioGroup.html → RadioGroup.html} +91 -53
- data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +301 -127
- data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +96 -33
- data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +59 -44
- data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +94 -57
- data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +96 -33
- data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +181 -121
- data/doc/rdoc/classes/Wee/Brush/TableTag.html +94 -32
- data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +257 -71
- data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +58 -43
- data/doc/rdoc/classes/Wee/CallAnswerMixin.html +289 -0
- data/doc/rdoc/classes/Wee/CallbackMixin.html +233 -0
- data/doc/rdoc/classes/Wee/CallbackRegistry.html +179 -155
- data/doc/rdoc/classes/Wee/Callbacks.html +262 -0
- data/doc/rdoc/classes/Wee/Component.html +228 -779
- data/doc/rdoc/classes/Wee/Decoration.html +144 -159
- data/doc/rdoc/classes/Wee/DecorationMixin.html +340 -0
- data/doc/rdoc/classes/Wee/Delegate.html +119 -76
- data/doc/rdoc/classes/Wee/DupReplaceSnapshotMixin.html +64 -47
- data/doc/rdoc/classes/Wee/ErrorResponse.html +59 -62
- data/doc/rdoc/classes/Wee/FormDecoration.html +51 -37
- data/doc/rdoc/classes/Wee/GenericResponse.html +60 -35
- data/doc/rdoc/classes/Wee/HtmlCanvas.html +1000 -602
- data/doc/rdoc/classes/Wee/HtmlDocument.html +288 -0
- data/doc/rdoc/classes/Wee/HtmlWriter.html +227 -126
- data/doc/rdoc/classes/Wee/IdGenerator.html +60 -31
- data/doc/rdoc/classes/Wee/IdGenerator/Secure.html +282 -0
- data/doc/rdoc/classes/Wee/{SimpleIdGenerator.html → IdGenerator/Sequential.html} +76 -49
- data/doc/rdoc/classes/Wee/JQuery.html +221 -0
- data/doc/rdoc/classes/Wee/LRUCache.html +514 -0
- data/doc/rdoc/classes/Wee/LRUCache/Item.html +158 -0
- data/doc/rdoc/classes/Wee/ObjectSnapshotMixin.html +187 -0
- data/doc/rdoc/classes/Wee/PageDecoration.html +88 -59
- data/doc/rdoc/classes/Wee/Presenter.html +124 -704
- data/doc/rdoc/classes/Wee/RedirectResponse.html +64 -33
- data/doc/rdoc/classes/Wee/RefreshResponse.html +59 -44
- data/doc/rdoc/classes/Wee/Renderer.html +234 -54
- data/doc/rdoc/classes/Wee/Request.html +151 -286
- data/doc/rdoc/classes/Wee/Response.html +29 -212
- data/doc/rdoc/classes/Wee/Session.html +585 -360
- data/doc/rdoc/classes/Wee/{StateHolder.html → Session/AbortCallbackProcessing.html} +67 -40
- data/doc/rdoc/classes/Wee/Session/MutexSerializer.html +166 -0
- data/doc/rdoc/classes/{Cache/Strategy/LFU/Item.html → Wee/Session/Page.html} +26 -27
- data/doc/rdoc/classes/Wee/Session/ThreadSerializer.html +219 -0
- data/doc/rdoc/classes/Wee/State.html +307 -0
- data/doc/rdoc/classes/{Cache/Strategy/LRU/Item.html → Wee/State/Snapshot.html} +26 -27
- data/doc/rdoc/classes/{Cache/Strategy/Unbounded/Item.html → Wee/State/SnapshotIVars.html} +26 -27
- data/doc/rdoc/classes/Wee/StructSnapshotMixin.html +183 -0
- data/doc/rdoc/classes/Wee/WrapperDecoration.html +101 -35
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/README_rdoc.html +243 -0
- data/doc/rdoc/files/lib/wee/application_rb.html +22 -30
- data/doc/rdoc/files/lib/wee/{page_rb.html → call_answer_rb.html} +14 -25
- data/doc/rdoc/files/lib/wee/callback_rb.html +12 -29
- data/doc/rdoc/files/lib/wee/component_rb.html +22 -27
- data/doc/rdoc/files/lib/wee/decoration_rb.html +19 -20
- data/doc/rdoc/files/lib/wee/{idgen_rb.html → html_brushes_rb.html} +14 -25
- data/doc/rdoc/files/lib/wee/html_canvas_rb.html +15 -23
- data/doc/rdoc/files/lib/wee/{abstractsession_rb.html → html_document_rb.html} +17 -25
- data/doc/rdoc/files/lib/wee/html_writer_rb.html +15 -23
- data/doc/rdoc/files/lib/wee/{webrick_rb.html → id_generator_rb.html} +19 -25
- data/doc/rdoc/files/lib/wee/{core/page_rb.html → jquery/jquery_rb.html} +14 -25
- data/doc/rdoc/files/lib/wee/{state_registry_rb.html → jquery_rb.html} +17 -27
- data/doc/rdoc/files/lib/{cache/cache_rb.html → wee/lru_cache_rb.html} +14 -25
- data/doc/rdoc/files/lib/wee/presenter_rb.html +12 -34
- data/doc/rdoc/files/lib/wee/{holder_rb.html → renderer_rb.html} +14 -25
- data/doc/rdoc/files/lib/wee/request_rb.html +18 -32
- data/doc/rdoc/files/lib/wee/response_rb.html +17 -24
- data/doc/rdoc/files/lib/wee/session_rb.html +21 -23
- data/doc/rdoc/files/lib/wee/state_rb.html +90 -0
- data/doc/rdoc/files/lib/wee_rb.html +48 -40
- data/doc/rdoc/fr_class_index.html +111 -75
- data/doc/rdoc/fr_file_index.html +46 -76
- data/doc/rdoc/fr_method_index.html +473 -480
- data/doc/rdoc/index.html +6 -9
- data/doc/rdoc/rdoc-style.css +210 -119
- data/examples/ObjectSpaceBrowser.rb +33 -23
- data/examples/ajax.rb +71 -0
- data/examples/continuations.rb +28 -0
- data/examples/demo.rb +92 -36
- data/examples/demo/calculator.rb +63 -0
- data/examples/demo/calendar.rb +42 -55
- data/examples/demo/counter.rb +38 -0
- data/{lib/wee/examples → examples/demo}/editable_counter.rb +11 -6
- data/examples/demo/example.rb +28 -24
- data/examples/demo/file_upload.rb +19 -0
- data/{lib/wee/components → examples/demo}/messagebox.rb +3 -3
- data/examples/demo/radio.rb +33 -0
- data/{lib/wee/examples → examples/demo}/window.rb +15 -10
- data/examples/hw.rb +3 -4
- data/{lib/wee/components → examples}/pager.rb +14 -14
- data/lib/wee.rb +48 -25
- data/lib/wee/application.rb +69 -131
- data/lib/wee/call_answer.rb +118 -0
- data/lib/wee/callback.rb +88 -0
- data/lib/wee/component.rb +141 -0
- data/lib/wee/decoration.rb +242 -0
- data/lib/wee/html_brushes.rb +725 -0
- data/lib/wee/html_canvas.rb +241 -0
- data/lib/wee/html_document.rb +45 -0
- data/lib/wee/html_writer.rb +71 -0
- data/lib/wee/id_generator.rb +70 -0
- data/lib/wee/jquery.rb +1 -0
- data/lib/wee/jquery/jquery.rb +17 -0
- data/lib/wee/jquery/public/jquery-1.3.2.min.js +19 -0
- data/lib/wee/jquery/public/wee-jquery.js +19 -0
- data/lib/wee/lru_cache.rb +89 -0
- data/lib/wee/presenter.rb +43 -0
- data/lib/wee/renderer.rb +65 -0
- data/lib/wee/request.rb +37 -113
- data/lib/wee/response.rb +43 -70
- data/lib/wee/session.rb +304 -113
- data/lib/wee/state.rb +85 -0
- data/test/component_spec.rb +17 -0
- data/wee.gemspec +4 -3
- metadata +249 -452
- data/ChangeLog +0 -657
- data/INSTALL +0 -17
- data/README +0 -272
- data/TODO +0 -142
- data/benchmark/Centrino1300/result.2000.counter.action +0 -45
- data/benchmark/Centrino1300/result.2000.counter.render +0 -43
- data/benchmark/Centrino1300/result.2000.filehandler +0 -43
- data/benchmark/Centrino600/result.2000.counter.action +0 -47
- data/benchmark/Centrino600/result.2000.counter.render +0 -45
- data/benchmark/Centrino600/result.2000.filehandler +0 -43
- data/benchmark/Makefile +0 -53
- data/benchmark/counter.rb +0 -77
- data/benchmark/filehandler.rb +0 -6
- data/benchmark/report_req.rb +0 -12
- data/bin/wee +0 -100
- data/doc/rdoc/classes/ActionView.html +0 -107
- data/doc/rdoc/classes/ActionView/Base.html +0 -133
- data/doc/rdoc/classes/Cache.html +0 -126
- data/doc/rdoc/classes/Cache/StorageCache.html +0 -320
- data/doc/rdoc/classes/Cache/Strategy.html +0 -128
- data/doc/rdoc/classes/Cache/Strategy/CapacityBounded.html +0 -269
- data/doc/rdoc/classes/Cache/Strategy/LFU.html +0 -238
- data/doc/rdoc/classes/Cache/Strategy/LRU.html +0 -238
- data/doc/rdoc/classes/Cache/Strategy/Unbounded.html +0 -225
- data/doc/rdoc/classes/LiteralMethod.html +0 -196
- data/doc/rdoc/classes/Main.html +0 -289
- data/doc/rdoc/classes/OgApplication.html +0 -126
- data/doc/rdoc/classes/OgScaffolder.html +0 -827
- data/doc/rdoc/classes/OgScaffolder/Editor.html +0 -565
- data/doc/rdoc/classes/OgSession.html +0 -172
- data/doc/rdoc/classes/Recipe.html +0 -113
- data/doc/rdoc/classes/Wee/AbstractSession.html +0 -502
- data/doc/rdoc/classes/Wee/Brush/ActionCallbackMixin.html +0 -148
- data/doc/rdoc/classes/Wee/Brush/ActionMixin.html +0 -146
- data/doc/rdoc/classes/Wee/Brush/ActionURLCallbackMixin.html +0 -154
- data/doc/rdoc/classes/Wee/Brush/AssignMixin.html +0 -141
- data/doc/rdoc/classes/Wee/Brush/CallbackMixin.html +0 -141
- data/doc/rdoc/classes/Wee/Brush/InputCallbackMixin.html +0 -148
- data/doc/rdoc/classes/Wee/Brush/SelectListTag/SelectListCallback.html +0 -158
- data/doc/rdoc/classes/Wee/Brush/ToCallback.html +0 -146
- data/doc/rdoc/classes/Wee/Callback.html +0 -231
- data/doc/rdoc/classes/Wee/CallbackStream.html +0 -227
- data/doc/rdoc/classes/Wee/Canvas.html +0 -235
- data/doc/rdoc/classes/Wee/CanvasMixin.html +0 -225
- data/doc/rdoc/classes/Wee/Component/OnAnswer.html +0 -153
- data/doc/rdoc/classes/Wee/ComponentDispatcher.html +0 -289
- data/doc/rdoc/classes/Wee/ComponentRunner.html +0 -321
- data/doc/rdoc/classes/Wee/ErrorPage.html +0 -175
- data/doc/rdoc/classes/Wee/Examples.html +0 -114
- data/doc/rdoc/classes/Wee/Examples/Calculator.html +0 -319
- data/doc/rdoc/classes/Wee/Examples/Counter.html +0 -289
- data/doc/rdoc/classes/Wee/Examples/EditableCounter.html +0 -210
- data/doc/rdoc/classes/Wee/Examples/Window.html +0 -346
- data/doc/rdoc/classes/Wee/FastCGIAdaptor.html +0 -227
- data/doc/rdoc/classes/Wee/Helper.html +0 -148
- data/doc/rdoc/classes/Wee/HtmlCanvasRenderer.html +0 -1230
- data/doc/rdoc/classes/Wee/LiteralMethodCallback.html +0 -198
- data/doc/rdoc/classes/Wee/LoginDecoration.html +0 -261
- data/doc/rdoc/classes/Wee/Md5IdGenerator.html +0 -181
- data/doc/rdoc/classes/Wee/MessageBox.html +0 -180
- data/doc/rdoc/classes/Wee/MethodCallback.html +0 -193
- data/doc/rdoc/classes/Wee/Nitro.html +0 -114
- data/doc/rdoc/classes/Wee/Nitro/ControllerClassMixin.html +0 -192
- data/doc/rdoc/classes/Wee/Nitro/ControllerMixin.html +0 -345
- data/doc/rdoc/classes/Wee/Nitro/FormTag.html +0 -155
- data/doc/rdoc/classes/Wee/Nitro/HtmlCanvasRenderer.html +0 -178
- data/doc/rdoc/classes/Wee/Page.html +0 -115
- data/doc/rdoc/classes/Wee/PagelessApplication.html +0 -154
- data/doc/rdoc/classes/Wee/PagelessComponentDriver.html +0 -296
- data/doc/rdoc/classes/Wee/PagelessRequest.html +0 -208
- data/doc/rdoc/classes/Wee/PagelessSession.html +0 -359
- data/doc/rdoc/classes/Wee/Pager.html +0 -534
- data/doc/rdoc/classes/Wee/Rails.html +0 -114
- data/doc/rdoc/classes/Wee/Rails/ControllerClassMixin.html +0 -192
- data/doc/rdoc/classes/Wee/Rails/ControllerMixin.html +0 -342
- data/doc/rdoc/classes/Wee/Rails/FormTag.html +0 -155
- data/doc/rdoc/classes/Wee/Rails/HtmlCanvasRenderer.html +0 -177
- data/doc/rdoc/classes/Wee/RenderingContext.html +0 -283
- data/doc/rdoc/classes/Wee/RequestHandler.html +0 -341
- data/doc/rdoc/classes/Wee/Snapshot.html +0 -211
- data/doc/rdoc/classes/Wee/StateRegistry.html +0 -434
- data/doc/rdoc/classes/Wee/StateRegistry/Snapshot.html +0 -320
- data/doc/rdoc/classes/Wee/StateRegistry/WithObject.html +0 -153
- data/doc/rdoc/classes/Wee/Utils.html +0 -300
- data/doc/rdoc/classes/Wee/ValueHolder.html +0 -220
- data/doc/rdoc/classes/Wee/WEBrickAdaptor.html +0 -368
- data/doc/rdoc/files/INSTALL.html +0 -130
- data/doc/rdoc/files/README.html +0 -471
- data/doc/rdoc/files/lib/wee/adaptors/fastcgi_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/adaptors/nitro_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/adaptors/rails_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/adaptors/webrick_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/component_ext_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components/component_dispatcher_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/components/form_decoration_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components/login_decoration_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components/messagebox_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components/page_decoration_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components/pager_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components/wrapper_decoration_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/components_rb.html +0 -114
- data/doc/rdoc/files/lib/wee/context_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/continuation/core/component_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/continuation/session_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/continuation_rb.html +0 -116
- data/doc/rdoc/files/lib/wee/core/callback_rb.html +0 -115
- data/doc/rdoc/files/lib/wee/core/component_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/core/componentrunner_rb.html +0 -110
- data/doc/rdoc/files/lib/wee/core/context_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/core/decoration_rb.html +0 -133
- data/doc/rdoc/files/lib/wee/core/idgen_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/core/presenter_rb.html +0 -112
- data/doc/rdoc/files/lib/wee/core/renderer_rb.html +0 -107
- data/doc/rdoc/files/lib/wee/core/snapshot_rb.html +0 -113
- data/doc/rdoc/files/lib/wee/core/valueholder_rb.html +0 -110
- data/doc/rdoc/files/lib/wee/core_ext_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/core_rb.html +0 -124
- data/doc/rdoc/files/lib/wee/databases/og/application_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/databases/og/old_scaffolder_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/databases/og/scaffolder_rb.html +0 -115
- data/doc/rdoc/files/lib/wee/databases/og/session_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/databases/og_rb.html +0 -111
- data/doc/rdoc/files/lib/wee/examples/calculator_rb.html +0 -107
- data/doc/rdoc/files/lib/wee/examples/counter_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/examples/editable_counter_rb.html +0 -114
- data/doc/rdoc/files/lib/wee/examples/window_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/idgen/md5_rb.html +0 -115
- data/doc/rdoc/files/lib/wee/idgen/simple_rb.html +0 -107
- data/doc/rdoc/files/lib/wee/pageless/application_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/pageless/request_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/pageless/session_rb.html +0 -109
- data/doc/rdoc/files/lib/wee/pageless_rb.html +0 -110
- data/doc/rdoc/files/lib/wee/renderer/html/brushes_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/renderer/html/canvas_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/renderer/html/writer_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/rendering/html/brushes_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/rendering/html/canvas_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/rendering/html/writer_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/requesthandler_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/skeleton/og/components/main_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/skeleton/og/conf/db_rb.html +0 -114
- data/doc/rdoc/files/lib/wee/skeleton/og/models/recipe_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/skeleton/og/run_rb.html +0 -115
- data/doc/rdoc/files/lib/wee/skeleton/simple/components/main_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/skeleton/simple/run_rb.html +0 -111
- data/doc/rdoc/files/lib/wee/snapshot_ext_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/snapshot_rb.html +0 -107
- data/doc/rdoc/files/lib/wee/stuff_rb.html +0 -144
- data/doc/rdoc/files/lib/wee/template_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/utils/autoreload_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/utils/cache_rb.html +0 -108
- data/doc/rdoc/files/lib/wee/utils/helper_rb.html +0 -101
- data/doc/rdoc/files/lib/wee/utils_rb.html +0 -110
- data/examples/ajax/ajax.js +0 -444
- data/examples/ajax/ajax.rb +0 -31
- data/examples/cc.rb +0 -74
- data/examples/dispatcher.rb +0 -37
- data/examples/draw.rb +0 -94
- data/examples/live-update.rb +0 -45
- data/examples/nitro/run.rb +0 -42
- data/examples/og-test.rb +0 -60
- data/examples/radio.rb +0 -44
- data/examples/test.rb +0 -39
- data/install.rb +0 -14
- data/lib/cache/cache.rb +0 -167
- data/lib/wee/abstractsession.rb +0 -96
- data/lib/wee/adaptors/fastcgi.rb +0 -76
- data/lib/wee/adaptors/nitro.rb +0 -155
- data/lib/wee/adaptors/rails.rb +0 -154
- data/lib/wee/adaptors/webrick.rb +0 -89
- data/lib/wee/components.rb +0 -7
- data/lib/wee/components/component_dispatcher.rb +0 -46
- data/lib/wee/components/form_decoration.rb +0 -7
- data/lib/wee/components/login_decoration.rb +0 -35
- data/lib/wee/components/page_decoration.rb +0 -14
- data/lib/wee/components/wrapper_decoration.rb +0 -7
- data/lib/wee/continuation.rb +0 -5
- data/lib/wee/continuation/core/component.rb +0 -56
- data/lib/wee/continuation/session.rb +0 -64
- data/lib/wee/core.rb +0 -16
- data/lib/wee/core/callback.rb +0 -121
- data/lib/wee/core/component.rb +0 -356
- data/lib/wee/core/componentrunner.rb +0 -73
- data/lib/wee/core/context.rb +0 -27
- data/lib/wee/core/decoration.rb +0 -138
- data/lib/wee/core/idgen.rb +0 -5
- data/lib/wee/core/page.rb +0 -1
- data/lib/wee/core/presenter.rb +0 -100
- data/lib/wee/core/renderer.rb +0 -23
- data/lib/wee/core/snapshot.rb +0 -21
- data/lib/wee/core/valueholder.rb +0 -19
- data/lib/wee/core_ext.rb +0 -122
- data/lib/wee/databases/og.rb +0 -4
- data/lib/wee/databases/og/application.rb +0 -3
- data/lib/wee/databases/og/old_scaffolder.rb +0 -98
- data/lib/wee/databases/og/scaffolder.rb +0 -255
- data/lib/wee/databases/og/session.rb +0 -9
- data/lib/wee/examples/calculator.rb +0 -70
- data/lib/wee/examples/counter.rb +0 -33
- data/lib/wee/idgen/md5.rb +0 -21
- data/lib/wee/idgen/sequential.rb +0 -11
- data/lib/wee/pageless.rb +0 -3
- data/lib/wee/pageless/application.rb +0 -13
- data/lib/wee/pageless/request.rb +0 -27
- data/lib/wee/pageless/session.rb +0 -74
- data/lib/wee/renderer/html/brushes.rb +0 -667
- data/lib/wee/renderer/html/canvas.rb +0 -265
- data/lib/wee/renderer/html/writer.rb +0 -80
- data/lib/wee/requesthandler.rb +0 -81
- data/lib/wee/skeleton/og/README +0 -38
- data/lib/wee/skeleton/og/components/main.rb +0 -20
- data/lib/wee/skeleton/og/conf/db.rb +0 -8
- data/lib/wee/skeleton/og/models/recipe.rb +0 -5
- data/lib/wee/skeleton/og/run.rb +0 -23
- data/lib/wee/skeleton/simple/README +0 -32
- data/lib/wee/skeleton/simple/components/main.rb +0 -25
- data/lib/wee/skeleton/simple/run.rb +0 -12
- data/lib/wee/snapshot_ext.rb +0 -41
- data/lib/wee/template.rb +0 -42
- data/lib/wee/utils.rb +0 -5
- data/lib/wee/utils/autoreload.rb +0 -56
- data/lib/wee/utils/cache.rb +0 -7
- data/lib/wee/utils/helper.rb +0 -51
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
require 'wee/presenter'
|
|
2
|
+
|
|
3
|
+
module Wee
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# Abstract base class of all decorations. Forwards the methods
|
|
7
|
+
# #process_callbacks, #render_on and #backtrack to the next decoration in
|
|
8
|
+
# the chain. Subclasses should provide special behaviour in these methods,
|
|
9
|
+
# otherwise the decoration does not make sense.
|
|
10
|
+
#
|
|
11
|
+
# For example, a HeaderFooterDecoration class could draw a header and footer
|
|
12
|
+
# around the decorations or components below itself:
|
|
13
|
+
#
|
|
14
|
+
# class HeaderFooterDecoration < Wee::Decoration
|
|
15
|
+
# alias render_on render_presenter_on
|
|
16
|
+
# def render(r)
|
|
17
|
+
# r.text "header"
|
|
18
|
+
# r.render_decoration(@next)
|
|
19
|
+
# r.text "footer"
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
class Decoration < Presenter
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Points to the next decoration in the chain. A decoration is responsible for
|
|
27
|
+
# all decorations or components "below" it (everything that follows this
|
|
28
|
+
# decoration in the chain). In other words, it's the owner of everything
|
|
29
|
+
# "below" itself.
|
|
30
|
+
#
|
|
31
|
+
attr_accessor :next
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Is this decoration a global or a local one? By default all decorations are
|
|
35
|
+
# local unless this method is overwritten.
|
|
36
|
+
#
|
|
37
|
+
# A global decoration is added in front of the decoration chain, a local
|
|
38
|
+
# decoration is added in front of all other local decorations but after all
|
|
39
|
+
# global decorations.
|
|
40
|
+
#
|
|
41
|
+
def global?() false end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# Forwards method call to the next decoration in the chain.
|
|
45
|
+
#
|
|
46
|
+
def process_callbacks(callbacks)
|
|
47
|
+
@next.process_callbacks(callbacks)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
alias render_presenter_on render_on
|
|
51
|
+
#
|
|
52
|
+
# Forwards method call to the next decoration in the chain.
|
|
53
|
+
#
|
|
54
|
+
def render_on(r)
|
|
55
|
+
@next.render_on(r)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
# We have to save the @next attribute to be able to correctly backtrack
|
|
60
|
+
# calls, as method Wee::Component#call modifies it in the call to
|
|
61
|
+
# <tt>component.remove_decoration(answer)</tt>. Removing the
|
|
62
|
+
# answer-decoration has the advantage to be able to call a component more
|
|
63
|
+
# than once!
|
|
64
|
+
#
|
|
65
|
+
def backtrack(state)
|
|
66
|
+
@next.backtrack(state)
|
|
67
|
+
state.add_ivar(self, :@next, @next)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end # class Decoration
|
|
71
|
+
|
|
72
|
+
module DecorationMixin
|
|
73
|
+
|
|
74
|
+
attr_accessor :decoration
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Iterates over all decorations (note that the component itself is excluded).
|
|
78
|
+
#
|
|
79
|
+
def each_decoration # :yields: decoration
|
|
80
|
+
d = @decoration
|
|
81
|
+
while d and d != self
|
|
82
|
+
yield d
|
|
83
|
+
d = d.next
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#
|
|
88
|
+
# Adds decoration +d+ to the decoration chain.
|
|
89
|
+
#
|
|
90
|
+
# A global decoration is added in front of the decoration chain, a local
|
|
91
|
+
# decoration is added in front of all other local decorations but after all
|
|
92
|
+
# global decorations.
|
|
93
|
+
#
|
|
94
|
+
# Returns: +self+
|
|
95
|
+
#
|
|
96
|
+
def add_decoration(d)
|
|
97
|
+
if d.global?
|
|
98
|
+
d.next = @decoration
|
|
99
|
+
@decoration = d
|
|
100
|
+
else
|
|
101
|
+
last_global = nil
|
|
102
|
+
each_decoration {|i|
|
|
103
|
+
if i.global?
|
|
104
|
+
last_global = i
|
|
105
|
+
else
|
|
106
|
+
break
|
|
107
|
+
end
|
|
108
|
+
}
|
|
109
|
+
if last_global.nil?
|
|
110
|
+
# no global decorations specified -> add in front
|
|
111
|
+
d.next = @decoration
|
|
112
|
+
@decoration = d
|
|
113
|
+
else
|
|
114
|
+
# add after last_global
|
|
115
|
+
d.next = last_global.next
|
|
116
|
+
last_global.next = d
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
return self
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# Remove decoration +d+ from the decoration chain.
|
|
125
|
+
#
|
|
126
|
+
# Returns the removed decoration or +nil+ if it did not exist in the
|
|
127
|
+
# decoration chain.
|
|
128
|
+
#
|
|
129
|
+
def remove_decoration(d)
|
|
130
|
+
if d == @decoration # 'd' is in front
|
|
131
|
+
@decoration = d.next
|
|
132
|
+
else
|
|
133
|
+
last_decoration = @decoration
|
|
134
|
+
next_decoration = nil
|
|
135
|
+
loop do
|
|
136
|
+
return nil if last_decoration == self or last_decoration.nil?
|
|
137
|
+
next_decoration = last_decoration.next
|
|
138
|
+
break if d == next_decoration
|
|
139
|
+
last_decoration = next_decoration
|
|
140
|
+
end
|
|
141
|
+
last_decoration.next = d.next
|
|
142
|
+
end
|
|
143
|
+
d.next = nil # decoration 'd' no longer is an owner of anything!
|
|
144
|
+
return d
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
# Remove all decorations that match the block condition.
|
|
149
|
+
#
|
|
150
|
+
# Example (removes all decorations of class +HaloDecoration+):
|
|
151
|
+
#
|
|
152
|
+
# remove_decoration_if {|d| d.class == HaloDecoration}
|
|
153
|
+
#
|
|
154
|
+
def remove_decoration_if # :yields: decoration
|
|
155
|
+
to_remove = []
|
|
156
|
+
each_decoration {|d| to_remove << d if yield d}
|
|
157
|
+
to_remove.each {|d| remove_decoration(d)}
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end # module DecorationMixin
|
|
161
|
+
|
|
162
|
+
#
|
|
163
|
+
# A Wee::Delegate breaks the decoration chain and forwards the methods
|
|
164
|
+
# #process_callbacks, #render_on and #backtrack to the corresponding *chain*
|
|
165
|
+
# method of it's _delegate_ component (a Wee::Component).
|
|
166
|
+
#
|
|
167
|
+
class Delegate < Decoration
|
|
168
|
+
|
|
169
|
+
def initialize(delegate)
|
|
170
|
+
@delegate = delegate
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
#
|
|
174
|
+
# Forwards method to the corresponding top-level *chain* method of the
|
|
175
|
+
# _delegate_ component.
|
|
176
|
+
#
|
|
177
|
+
def process_callbacks(callbacks)
|
|
178
|
+
@delegate.decoration.process_callbacks(callbacks)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
#
|
|
182
|
+
# Forwards method to the corresponding top-level *chain* method of the
|
|
183
|
+
# _delegate_ component.
|
|
184
|
+
#
|
|
185
|
+
def render_on(r)
|
|
186
|
+
@delegate.decoration.render_on(r)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
#
|
|
190
|
+
# Forwards method to the corresponding top-level *chain* method of the
|
|
191
|
+
# _delegate_ component. We also take snapshots of all non-visible
|
|
192
|
+
# components, thus we follow the @next decoration (via super).
|
|
193
|
+
#
|
|
194
|
+
def backtrack(state)
|
|
195
|
+
super
|
|
196
|
+
@delegate.decoration.backtrack(state)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end # class Delegate
|
|
200
|
+
|
|
201
|
+
class WrapperDecoration < Decoration
|
|
202
|
+
|
|
203
|
+
alias render_on render_presenter_on
|
|
204
|
+
|
|
205
|
+
#
|
|
206
|
+
# Overwrite this method, and call render_inner(r)
|
|
207
|
+
# where you want the inner content to be drawn.
|
|
208
|
+
#
|
|
209
|
+
def render(r)
|
|
210
|
+
render_inner(r)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def render_inner(r)
|
|
214
|
+
r.render_decoration(@next)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
end # class WrapperDecoration
|
|
218
|
+
|
|
219
|
+
class FormDecoration < WrapperDecoration
|
|
220
|
+
|
|
221
|
+
def render(r)
|
|
222
|
+
r.form { render_inner(r) }
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
end # class FormDecoration
|
|
226
|
+
|
|
227
|
+
class PageDecoration < WrapperDecoration
|
|
228
|
+
|
|
229
|
+
def initialize(title='')
|
|
230
|
+
@title = title
|
|
231
|
+
super()
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def global?() true end
|
|
235
|
+
|
|
236
|
+
def render(r)
|
|
237
|
+
r.page.title(@title).with { render_inner(r) }
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
end # class PageDecoration
|
|
241
|
+
|
|
242
|
+
end # module Wee
|
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
module Wee
|
|
2
|
+
|
|
3
|
+
class Brush
|
|
4
|
+
attr_accessor :canvas, :document
|
|
5
|
+
|
|
6
|
+
# This method is called right after #initialize. It's only here to
|
|
7
|
+
# simplify the implementation of Brushes, mainly to avoid passing all those
|
|
8
|
+
# arguments to super.
|
|
9
|
+
#
|
|
10
|
+
# There is a bit of redundancy with canvas and document here. It's there to
|
|
11
|
+
# avoid method calls.
|
|
12
|
+
#
|
|
13
|
+
# A brush is considered to be closed, when @document is nil.
|
|
14
|
+
#
|
|
15
|
+
def setup(canvas, document)
|
|
16
|
+
@canvas = canvas
|
|
17
|
+
@document = document
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def with(*args, &block)
|
|
21
|
+
@canvas.nest(&block) if block
|
|
22
|
+
@document = @canvas = nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def close
|
|
26
|
+
with if @document
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.nesting?() true end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Brush::GenericTextBrush < Brush
|
|
33
|
+
def with(text)
|
|
34
|
+
@document.text(text)
|
|
35
|
+
@document = @canvas = nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.nesting?() false end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class Brush::GenericEncodedTextBrush < Brush::GenericTextBrush
|
|
42
|
+
def with(text)
|
|
43
|
+
@document.encode_text(text)
|
|
44
|
+
@document = @canvas = nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class Brush::GenericTagBrush < Brush
|
|
49
|
+
def self.html_attr(attr, hash={})
|
|
50
|
+
name = hash[:html_name] || attr
|
|
51
|
+
if hash[:type] == :bool
|
|
52
|
+
class_eval %{
|
|
53
|
+
def #{ attr }(bool=true)
|
|
54
|
+
if bool
|
|
55
|
+
@attributes[:"#{ name }"] = nil
|
|
56
|
+
else
|
|
57
|
+
@attributes.delete(:"#{ name }")
|
|
58
|
+
end
|
|
59
|
+
self
|
|
60
|
+
end
|
|
61
|
+
}
|
|
62
|
+
else
|
|
63
|
+
class_eval %{
|
|
64
|
+
def #{ attr }(value)
|
|
65
|
+
if value == nil
|
|
66
|
+
@attributes.delete(:"#{ name }")
|
|
67
|
+
else
|
|
68
|
+
@attributes[:"#{ name }"] = value
|
|
69
|
+
end
|
|
70
|
+
self
|
|
71
|
+
end
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
(hash[:aliases] || []).each do |a|
|
|
76
|
+
class_eval "alias #{ a } #{ attr }"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
(hash[:shortcuts] || {}).each_pair do |k, v|
|
|
80
|
+
class_eval "def #{ k }() #{ attr }(#{ v.inspect }) end"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class Brush::GenericTagBrush < Brush
|
|
86
|
+
html_attr :id
|
|
87
|
+
html_attr :name # XXX
|
|
88
|
+
html_attr :css_class, :html_name => :class
|
|
89
|
+
html_attr :css_style, :html_name => :style, :aliases => [:style]
|
|
90
|
+
html_attr :onclick
|
|
91
|
+
html_attr :ondblclick
|
|
92
|
+
|
|
93
|
+
def initialize(tag)
|
|
94
|
+
super()
|
|
95
|
+
@tag = tag
|
|
96
|
+
@attributes = Hash.new
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Assigns a unique DOM id
|
|
101
|
+
#
|
|
102
|
+
def oid
|
|
103
|
+
id(get_oid())
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Returns a unique DOM id for the underlying component
|
|
108
|
+
#
|
|
109
|
+
def get_oid
|
|
110
|
+
"wee_#{@canvas.current_component.object_id}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def onclick_javascript(v)
|
|
114
|
+
onclick("javascript: #{v}")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def onclick_callback(&block)
|
|
118
|
+
url = @canvas.url_for_callback(block)
|
|
119
|
+
onclick("javascript: document.location.href='#{ url }'")
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def ondblclick_callback(&block)
|
|
123
|
+
url = @canvas.url_for_callback(block)
|
|
124
|
+
ondblclick("javascript: document.location.href='#{ url }'")
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def onclick_update_self_callback(&block)
|
|
128
|
+
raise ArgumentError unless block
|
|
129
|
+
current_component = @canvas.current_component
|
|
130
|
+
onclick_update_callback {|r|
|
|
131
|
+
block.call(r)
|
|
132
|
+
r.update(current_component)
|
|
133
|
+
}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def onclick_update_callback(&block)
|
|
137
|
+
raise ArgumentError unless block
|
|
138
|
+
url = @canvas.url_for_callback(@canvas.session.render_ajax_proc(block, @canvas.current_component))
|
|
139
|
+
onclick("javascript: wee.update('#{url}')")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def with(text=nil, &block)
|
|
143
|
+
@document.start_tag(@tag, @attributes)
|
|
144
|
+
@document.text(text) if text
|
|
145
|
+
@canvas.nest(&block) if block
|
|
146
|
+
@document.end_tag(@tag)
|
|
147
|
+
@document = @canvas = nil
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
class Brush::GenericSingleTagBrush < Brush::GenericTagBrush
|
|
153
|
+
def with
|
|
154
|
+
@document.single_tag(@tag, @attributes)
|
|
155
|
+
@document = @canvas = nil
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def self.nesting?() false end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
class Brush::ImageTag < Brush::GenericSingleTagBrush
|
|
162
|
+
HTML_TAG = 'img'.freeze
|
|
163
|
+
|
|
164
|
+
html_attr :src
|
|
165
|
+
html_attr :width
|
|
166
|
+
html_attr :height
|
|
167
|
+
html_attr :border
|
|
168
|
+
html_attr :alt
|
|
169
|
+
|
|
170
|
+
def initialize
|
|
171
|
+
super(HTML_TAG)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
class Brush::JavascriptTag < Brush::GenericTagBrush
|
|
176
|
+
HTML_TAG = 'script'.freeze
|
|
177
|
+
HTML_TYPE = 'text/javascript'.freeze
|
|
178
|
+
|
|
179
|
+
html_attr :src
|
|
180
|
+
html_attr :type
|
|
181
|
+
|
|
182
|
+
def initialize
|
|
183
|
+
super(HTML_TAG)
|
|
184
|
+
type(HTML_TYPE)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
#---------------------------------------------------------------------
|
|
189
|
+
# Table
|
|
190
|
+
#---------------------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
class Brush::TableTag < Brush::GenericTagBrush
|
|
193
|
+
HTML_TAG = 'table'.freeze
|
|
194
|
+
|
|
195
|
+
html_attr :cellspacing
|
|
196
|
+
html_attr :border
|
|
197
|
+
|
|
198
|
+
def initialize
|
|
199
|
+
super(HTML_TAG)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
class Brush::TableRowTag < Brush::GenericTagBrush
|
|
204
|
+
HTML_TAG = 'tr'.freeze
|
|
205
|
+
|
|
206
|
+
html_attr :align, :shortcuts => {
|
|
207
|
+
:align_top => :top, :align_bottom => :bottom
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
def initialize
|
|
211
|
+
super(HTML_TAG)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def columns(*cols, &block)
|
|
215
|
+
with {
|
|
216
|
+
cols.each {|col|
|
|
217
|
+
@canvas.table_data.with {
|
|
218
|
+
if block
|
|
219
|
+
block.call(col)
|
|
220
|
+
else
|
|
221
|
+
@canvas.text(col)
|
|
222
|
+
end
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def headings(*headers, &block)
|
|
229
|
+
with {
|
|
230
|
+
headers.each {|header|
|
|
231
|
+
@canvas.table_header.with {
|
|
232
|
+
if block
|
|
233
|
+
block.call(header)
|
|
234
|
+
else
|
|
235
|
+
@canvas.text(header)
|
|
236
|
+
end
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def spanning_column(str, colspan)
|
|
243
|
+
with { @canvas.table_data.col_span(colspan).with(str) }
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def spacer
|
|
247
|
+
with { @canvas.table_data { @canvas.space } }
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
class Brush::TableDataTag < Brush::GenericTagBrush
|
|
252
|
+
HTML_TAG = 'td'.freeze
|
|
253
|
+
|
|
254
|
+
html_attr :colspan
|
|
255
|
+
html_attr :align, :shortcuts => {
|
|
256
|
+
:align_top => :top,
|
|
257
|
+
:align_bottom => :bottom
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
def initialize
|
|
261
|
+
super(HTML_TAG)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
class Brush::TableHeaderTag < Brush::GenericTagBrush
|
|
266
|
+
HTML_TAG = 'th'.freeze
|
|
267
|
+
|
|
268
|
+
html_attr :colspan
|
|
269
|
+
html_attr :align, :shortcuts => {
|
|
270
|
+
:align_top => :top,
|
|
271
|
+
:align_bottom => :bottom
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
def initialize
|
|
275
|
+
super(HTML_TAG)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
#---------------------------------------------------------------------
|
|
280
|
+
# Callback Mixin
|
|
281
|
+
#---------------------------------------------------------------------
|
|
282
|
+
|
|
283
|
+
module CallbackMixin
|
|
284
|
+
|
|
285
|
+
def callback_method(id, *args)
|
|
286
|
+
@callback = self
|
|
287
|
+
@callback_object = @canvas.current_component
|
|
288
|
+
@callback_id = id
|
|
289
|
+
@callback_args = args
|
|
290
|
+
__callback()
|
|
291
|
+
return self
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def callback(&block)
|
|
295
|
+
@callback = block
|
|
296
|
+
__callback()
|
|
297
|
+
return self
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
#
|
|
301
|
+
# Is called when #callback_method was used.
|
|
302
|
+
#
|
|
303
|
+
def call(*args)
|
|
304
|
+
args.push(*@callback_args)
|
|
305
|
+
@callback_object.send(@callback_id, *args)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
#---------------------------------------------------------------------
|
|
311
|
+
# Form
|
|
312
|
+
#---------------------------------------------------------------------
|
|
313
|
+
|
|
314
|
+
class Brush::FormTag < Brush::GenericTagBrush
|
|
315
|
+
HTML_TAG = 'form'.freeze
|
|
316
|
+
HTML_METHOD_POST = 'POST'.freeze
|
|
317
|
+
|
|
318
|
+
html_attr :action
|
|
319
|
+
html_attr :enctype
|
|
320
|
+
|
|
321
|
+
#
|
|
322
|
+
# Use this enctype when you have a FileUploadTag field.
|
|
323
|
+
#
|
|
324
|
+
def enctype_multipart
|
|
325
|
+
enctype('multipart/form-data')
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def initialize
|
|
329
|
+
super(HTML_TAG)
|
|
330
|
+
@attributes[:method] = HTML_METHOD_POST
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def with(&block)
|
|
334
|
+
# If no action was specified, use a dummy one.
|
|
335
|
+
unless @attributes.has_key?(:action)
|
|
336
|
+
@attributes[:action] = @canvas.build_url
|
|
337
|
+
end
|
|
338
|
+
super
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
include CallbackMixin
|
|
342
|
+
|
|
343
|
+
def __callback; action(@canvas.url_for_callback(@callback)) end
|
|
344
|
+
|
|
345
|
+
=begin
|
|
346
|
+
def onsubmit_update(update_id, &block)
|
|
347
|
+
raise ArgumentError if symbol and block
|
|
348
|
+
url = @canvas.url_for_callback(block, :live_update)
|
|
349
|
+
onsubmit("javascript: new Ajax.Updater('#{ update_id }', '#{ url }', {method:'get', parameters: Form.serialize(this)}); return false;")
|
|
350
|
+
end
|
|
351
|
+
=end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
#---------------------------------------------------------------------
|
|
355
|
+
# Form - Input
|
|
356
|
+
#---------------------------------------------------------------------
|
|
357
|
+
|
|
358
|
+
class Brush::InputTag < Brush::GenericSingleTagBrush
|
|
359
|
+
HTML_TAG = 'input'.freeze
|
|
360
|
+
|
|
361
|
+
html_attr :type
|
|
362
|
+
html_attr :name
|
|
363
|
+
html_attr :value
|
|
364
|
+
html_attr :size
|
|
365
|
+
html_attr :maxlength
|
|
366
|
+
html_attr :src
|
|
367
|
+
html_attr :checked, :type => :bool
|
|
368
|
+
html_attr :disabled, :type => :bool
|
|
369
|
+
html_attr :readonly, :type => :bool
|
|
370
|
+
|
|
371
|
+
def initialize(_type)
|
|
372
|
+
super(HTML_TAG)
|
|
373
|
+
type(_type)
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
include CallbackMixin
|
|
377
|
+
|
|
378
|
+
def __callback; name(@canvas.register_callback(:input, @callback)) end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
class Brush::TextInputTag < Brush::InputTag
|
|
382
|
+
HTML_TYPE = 'text'.freeze
|
|
383
|
+
|
|
384
|
+
def initialize
|
|
385
|
+
super(HTML_TYPE)
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
class Brush::HiddenInputTag < Brush::InputTag
|
|
390
|
+
HTML_TYPE = 'hidden'.freeze
|
|
391
|
+
|
|
392
|
+
def initialize
|
|
393
|
+
super(HTML_TYPE)
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
class Brush::PasswordInputTag < Brush::InputTag
|
|
398
|
+
HTML_TYPE = 'password'.freeze
|
|
399
|
+
|
|
400
|
+
def initialize
|
|
401
|
+
super(HTML_TYPE)
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
class Brush::CheckboxTag < Brush::InputTag
|
|
406
|
+
HTML_TYPE = 'checkbox'.freeze
|
|
407
|
+
|
|
408
|
+
def initialize
|
|
409
|
+
super(HTML_TYPE)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def __callback; end # do nothing
|
|
413
|
+
|
|
414
|
+
def with
|
|
415
|
+
if @callback
|
|
416
|
+
n = @canvas.register_callback(:input, proc {|input|
|
|
417
|
+
@callback.call(input.send(input.kind_of?(Array) ? :include? : :==, '1'))
|
|
418
|
+
})
|
|
419
|
+
@document.single_tag('input', :type => 'hidden', :name => n, :value => '0')
|
|
420
|
+
name(n)
|
|
421
|
+
value('1')
|
|
422
|
+
end
|
|
423
|
+
super
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
#
|
|
428
|
+
# Use a <form> tag with enctype_multipart!
|
|
429
|
+
#
|
|
430
|
+
class Brush::FileUploadTag < Brush::InputTag
|
|
431
|
+
HTML_TYPE = 'file'.freeze
|
|
432
|
+
|
|
433
|
+
def initialize
|
|
434
|
+
super(HTML_TYPE)
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
#---------------------------------------------------------------------
|
|
439
|
+
# Form - Buttons
|
|
440
|
+
#---------------------------------------------------------------------
|
|
441
|
+
|
|
442
|
+
class Brush::ActionInputTag < Brush::InputTag
|
|
443
|
+
include CallbackMixin
|
|
444
|
+
|
|
445
|
+
def __callback; name(@canvas.register_callback(:action, @callback)) end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
class Brush::SubmitButtonTag < Brush::ActionInputTag
|
|
449
|
+
HTML_TYPE = 'submit'.freeze
|
|
450
|
+
|
|
451
|
+
def initialize
|
|
452
|
+
super(HTML_TYPE)
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
#
|
|
457
|
+
# NOTE: The form-fields returned by a image-button-tag is browser-specific.
|
|
458
|
+
# Most browsers do not send the "name" key together with the value specified
|
|
459
|
+
# by "value", only "name.x" and "name.y". This conforms to the standard. But
|
|
460
|
+
# Firefox also sends "name"="value". This is why I raise an exception from
|
|
461
|
+
# the #value method. Note that it's neccessary to parse the passed
|
|
462
|
+
# form-fields and generate a "name" fields in the request, to make this
|
|
463
|
+
# image-button work.
|
|
464
|
+
#
|
|
465
|
+
class Brush::ImageButtonTag < Brush::ActionInputTag
|
|
466
|
+
HTML_TYPE = 'image'.freeze
|
|
467
|
+
|
|
468
|
+
def initialize
|
|
469
|
+
super(HTML_TYPE)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
undef :value
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
#---------------------------------------------------------------------
|
|
476
|
+
# Form - Textarea
|
|
477
|
+
#---------------------------------------------------------------------
|
|
478
|
+
|
|
479
|
+
class Brush::TextAreaTag < Brush::GenericTagBrush
|
|
480
|
+
HTML_TAG = 'textarea'.freeze
|
|
481
|
+
|
|
482
|
+
html_attr :name
|
|
483
|
+
html_attr :rows
|
|
484
|
+
html_attr :cols
|
|
485
|
+
html_attr :tabindex
|
|
486
|
+
html_attr :accesskey
|
|
487
|
+
html_attr :onfocus
|
|
488
|
+
html_attr :onblur
|
|
489
|
+
html_attr :onselect
|
|
490
|
+
html_attr :onchange
|
|
491
|
+
html_attr :disabled, :type => :bool
|
|
492
|
+
html_attr :readonly, :type => :bool
|
|
493
|
+
|
|
494
|
+
def initialize
|
|
495
|
+
super(HTML_TAG)
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def value(val)
|
|
499
|
+
@value = val
|
|
500
|
+
self
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def with(value=nil)
|
|
504
|
+
super(value || @value)
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
include CallbackMixin
|
|
508
|
+
|
|
509
|
+
def __callback; name(@canvas.register_callback(:input, @callback)) end
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
#---------------------------------------------------------------------
|
|
513
|
+
# Form - Select
|
|
514
|
+
#---------------------------------------------------------------------
|
|
515
|
+
|
|
516
|
+
class Brush::SelectListTag < Brush::GenericTagBrush
|
|
517
|
+
HTML_TAG = 'select'.freeze
|
|
518
|
+
|
|
519
|
+
html_attr :size
|
|
520
|
+
html_attr :disabled, :type => :bool
|
|
521
|
+
html_attr :readonly, :type => :bool
|
|
522
|
+
html_attr :multiple, :type => :bool, :aliases => [:multi]
|
|
523
|
+
|
|
524
|
+
def initialize(items)
|
|
525
|
+
super(HTML_TAG)
|
|
526
|
+
@items = items
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def items(items)
|
|
530
|
+
@items = items
|
|
531
|
+
self
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def selected(arg=nil, &block)
|
|
535
|
+
raise ArgumentError if arg and block
|
|
536
|
+
@selected = block || arg
|
|
537
|
+
self
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def labels(arg=nil, &block)
|
|
541
|
+
raise ArgumentError if arg and block
|
|
542
|
+
if block
|
|
543
|
+
@labels = proc {|i| block.call(@items[i])}
|
|
544
|
+
else
|
|
545
|
+
@labels = arg
|
|
546
|
+
end
|
|
547
|
+
self
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
include CallbackMixin
|
|
551
|
+
|
|
552
|
+
def __callback
|
|
553
|
+
#
|
|
554
|
+
# A callback was specified. We have to wrap it inside another
|
|
555
|
+
# callback, as we want to perform some additional actions.
|
|
556
|
+
#
|
|
557
|
+
name(@canvas.register_callback(:input, proc {|input|
|
|
558
|
+
input = [input] unless input.kind_of?(Array)
|
|
559
|
+
choosen = input.map {|idx| get_item(idx) }
|
|
560
|
+
|
|
561
|
+
if @attributes.has_key?(:multiple)
|
|
562
|
+
@callback.call(choosen)
|
|
563
|
+
elsif choosen.size > 1
|
|
564
|
+
raise "more than one element was choosen from a not-multiple SelectListTag"
|
|
565
|
+
else
|
|
566
|
+
@callback.call(choosen.first)
|
|
567
|
+
end
|
|
568
|
+
}))
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
def get_item(idx)
|
|
572
|
+
idx = Integer(idx)
|
|
573
|
+
raise IndexError if idx < 0 or idx > @items.size
|
|
574
|
+
@items[idx]
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
protected :get_item
|
|
578
|
+
|
|
579
|
+
def with
|
|
580
|
+
@labels ||= @items.collect {|i| i.to_s}
|
|
581
|
+
|
|
582
|
+
if @attributes.has_key?(:multiple)
|
|
583
|
+
@selected ||= Array.new
|
|
584
|
+
meth = @selected.kind_of?(Proc) ? (:call) : (:include?)
|
|
585
|
+
else
|
|
586
|
+
meth = @selected.kind_of?(Proc) ? (:call) : (:==)
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
super {
|
|
590
|
+
@items.each_index do |i|
|
|
591
|
+
@canvas.option.value(i).selected(@selected.send(meth, @items[i])).with(@labels[i])
|
|
592
|
+
end
|
|
593
|
+
}
|
|
594
|
+
end
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
class Brush::SelectOptionTag < Brush::GenericTagBrush
|
|
598
|
+
HTML_TAG = 'option'.freeze
|
|
599
|
+
|
|
600
|
+
html_attr :value
|
|
601
|
+
html_attr :selected, :type => :bool
|
|
602
|
+
|
|
603
|
+
def initialize
|
|
604
|
+
super(HTML_TAG)
|
|
605
|
+
end
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
#---------------------------------------------------------------------
|
|
609
|
+
# Form - Radio
|
|
610
|
+
#---------------------------------------------------------------------
|
|
611
|
+
|
|
612
|
+
class Brush::RadioGroup
|
|
613
|
+
def initialize(canvas)
|
|
614
|
+
@name = canvas.register_callback(:input, self)
|
|
615
|
+
@callbacks = {}
|
|
616
|
+
@ids = Wee::IdGenerator::Sequential.new
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
def add_callback(callback)
|
|
620
|
+
value = @ids.next.to_s
|
|
621
|
+
@callbacks[value] = callback
|
|
622
|
+
return [@name, value]
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
def call(value)
|
|
626
|
+
if @callbacks.has_key?(value)
|
|
627
|
+
cb = @callbacks[value]
|
|
628
|
+
cb.call(value) if cb
|
|
629
|
+
else
|
|
630
|
+
raise "invalid radio button/group value"
|
|
631
|
+
end
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
class Brush::RadioButtonTag < Brush::InputTag
|
|
636
|
+
HTML_TYPE = 'radio'.freeze
|
|
637
|
+
|
|
638
|
+
def initialize
|
|
639
|
+
super(HTML_TYPE)
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
def group(radio_group)
|
|
643
|
+
@group = radio_group
|
|
644
|
+
self
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
include CallbackMixin
|
|
648
|
+
|
|
649
|
+
def __callback; end # do nothing
|
|
650
|
+
|
|
651
|
+
def with
|
|
652
|
+
if @group
|
|
653
|
+
n, v = @group.add_callback(@callback)
|
|
654
|
+
name(n)
|
|
655
|
+
value(v)
|
|
656
|
+
end
|
|
657
|
+
super
|
|
658
|
+
end
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
#---------------------------------------------------------------------
|
|
662
|
+
# Misc
|
|
663
|
+
#---------------------------------------------------------------------
|
|
664
|
+
|
|
665
|
+
class Brush::AnchorTag < Brush::GenericTagBrush
|
|
666
|
+
HTML_TAG = 'a'.freeze
|
|
667
|
+
|
|
668
|
+
html_attr :href, :aliases => [:url]
|
|
669
|
+
html_attr :title, :aliases => [:tooltip]
|
|
670
|
+
|
|
671
|
+
def initialize
|
|
672
|
+
super(HTML_TAG)
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
def info(info=nil)
|
|
676
|
+
@info = info
|
|
677
|
+
self
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
include CallbackMixin
|
|
681
|
+
|
|
682
|
+
def __callback
|
|
683
|
+
url(@canvas.url_for_callback(@callback, :action, @info ? {:info => @info} : {}))
|
|
684
|
+
end
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
class Brush::Page < Brush
|
|
688
|
+
HTML_HTML = 'html'.freeze
|
|
689
|
+
HTML_HEAD = 'head'.freeze
|
|
690
|
+
HTML_TITLE = 'title'.freeze
|
|
691
|
+
HTML_BODY = 'body'.freeze
|
|
692
|
+
|
|
693
|
+
def with(text=nil, &block)
|
|
694
|
+
@document.start_tag(HTML_HTML)
|
|
695
|
+
@document.start_tag(HTML_HEAD)
|
|
696
|
+
|
|
697
|
+
if @title
|
|
698
|
+
@document.start_tag(HTML_TITLE)
|
|
699
|
+
@document.text(@title)
|
|
700
|
+
@document.end_tag(HTML_TITLE)
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
@document.end_tag(HTML_HEAD)
|
|
704
|
+
@document.start_tag(HTML_BODY)
|
|
705
|
+
|
|
706
|
+
if text
|
|
707
|
+
raise ArgumentError if block
|
|
708
|
+
@document.text(text)
|
|
709
|
+
else
|
|
710
|
+
@canvas.nest(&block) if block
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
@document.end_tag(HTML_BODY)
|
|
714
|
+
@document.end_tag(HTML_HTML)
|
|
715
|
+
|
|
716
|
+
@document = @canvas = nil
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
def title(t)
|
|
720
|
+
@title = t
|
|
721
|
+
self
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
end # module Wee
|