glimmer-dsl-opal 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +95 -20
  3. data/VERSION +1 -1
  4. data/lib/glimmer-dsl-opal.rb +10 -8
  5. data/lib/glimmer/data_binding/element_binding.rb +35 -0
  6. data/lib/glimmer/data_binding/observable_element.rb +14 -0
  7. data/lib/glimmer/dsl/opal/bind_expression.rb +37 -0
  8. data/lib/glimmer/dsl/opal/button_expression.rb +17 -0
  9. data/lib/glimmer/dsl/opal/combo_expression.rb +17 -0
  10. data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +40 -0
  11. data/lib/glimmer/dsl/opal/composite_expression.rb +17 -0
  12. data/lib/glimmer/dsl/opal/data_binding_expression.rb +34 -0
  13. data/lib/glimmer/dsl/opal/dsl.rb +9 -0
  14. data/lib/glimmer/dsl/opal/label_expression.rb +2 -2
  15. data/lib/glimmer/dsl/opal/property_expression.rb +1 -1
  16. data/lib/glimmer/dsl/opal/shell_expression.rb +2 -2
  17. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +18 -0
  18. data/lib/glimmer/opal/div_proxy.rb +14 -0
  19. data/lib/glimmer/opal/{shell.rb → document_proxy.rb} +19 -5
  20. data/lib/glimmer/opal/element_proxy.rb +52 -0
  21. data/lib/glimmer/opal/event_listener_proxy.rb +18 -0
  22. data/lib/glimmer/opal/input_proxy.rb +30 -0
  23. data/lib/glimmer/opal/label_proxy.rb +24 -0
  24. data/lib/glimmer/opal/select_proxy.rb +58 -0
  25. data/lib/samples/elaborate/contact_manager.rb +95 -0
  26. data/lib/samples/elaborate/contact_manager/contact.rb +11 -0
  27. data/lib/samples/elaborate/contact_manager/contact_manager_presenter.rb +36 -0
  28. data/lib/samples/elaborate/contact_manager/contact_repository.rb +244 -0
  29. data/lib/samples/elaborate/launch +6 -0
  30. data/lib/samples/elaborate/login.rb +88 -0
  31. data/lib/samples/elaborate/tic_tac_toe.rb +53 -0
  32. data/lib/samples/elaborate/tic_tac_toe/board.rb +124 -0
  33. data/lib/samples/elaborate/tic_tac_toe/cell.rb +27 -0
  34. data/lib/samples/hello/hello_browser.rb +8 -0
  35. data/lib/samples/hello/hello_combo.rb +34 -0
  36. data/lib/samples/hello/hello_computed.rb +69 -0
  37. data/lib/samples/hello/hello_computed/contact.rb +21 -0
  38. data/lib/samples/hello/hello_list_multi_selection.rb +44 -0
  39. data/lib/samples/hello/hello_list_single_selection.rb +34 -0
  40. data/lib/samples/hello/hello_tab.rb +24 -0
  41. data/lib/samples/hello/hello_world.rb +8 -0
  42. data/lib/samples/hello/launch +10 -0
  43. data/lib/samples/launch +4 -0
  44. metadata +39 -6
  45. data/lib/glimmer/opal/label.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67893f26592de179a00e15688b7814762edd60ff1c036b1389d177437ffaae5d
4
- data.tar.gz: 2a6362729a7ecbe86231f2bcab62e25a46caadee1dc82c7f8abd84180d437ea2
3
+ metadata.gz: 43ffbba379c5bade234cf2a2263be49565bff77120e7449e17ea7095461520c5
4
+ data.tar.gz: 990340e899f8bf37a98ea0ea4e78941ccb48e4e55e0faddbb2b4ea7d010c8c0c
5
5
  SHA512:
6
- metadata.gz: f8ac369bb79fcd6b8b5c46ba357f807d393e99e49303f4d983efb9a1b54551a51a2b80536b2da1111097ce9ed912ae7f7ae6d7968778ade6cd0ec13f1b45e3f3
7
- data.tar.gz: 517dbe5aa02c3c6027e9aca9be18c88a60c99c19c362dab098aa0ddb18c42faed884d0e6815a5cb7889fbec1f55c0e19543c843773f1e8720489baad07a7af73
6
+ metadata.gz: 49e2e4d81cf84643f7e645ce30c474a0262c11bebd7f708db25068fc4fd6acb53d7e98779c028b2d459165749523444ecf7a0fb4de653bc2a6c6409b05f606d9
7
+ data.tar.gz: 68179f29cc621c861c6243ef2dc54dff6558be4f394c0ab7bb47c0cffe683fe77cf1e3fdbc5f00b7c8646bdfb6cd7580bed4162e88353149be003bad32ce34ea
data/README.md CHANGED
@@ -1,20 +1,23 @@
1
- # Glimmer DSL for Opal 0.0.1 Beta (Web GUI for Desktop Apps)
1
+
2
+ # Glimmer DSL for Opal 0.0.2 Alpha (Web GUI for Desktop Apps)
2
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
4
+ [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
5
 
4
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Opal is a web GUI adaptor for desktop apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
6
+ [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Opal is a web GUI adaptor for desktop apps built with [Glimmer](https://github.com/AndyObtiva/glimmer) & [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
5
7
 
6
8
  It enables running [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps on the web via [Rails](https://rubyonrails.org/) 5 and [Opal](https://opalrb.com/) 1.
7
9
 
8
- NOTE: Version 0.0.1 only supports Hello, World! capabilities.
10
+ NOTE: Alpha Version 0.0.2 only supports Hello, World! and Hello, Combo! capabilities.
9
11
 
10
- ## Examples
12
+ Other Glimmer DSL gems:
13
+ - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
14
+ - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
15
+ - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
11
16
 
12
- ### Hello, World!
17
+ ## Hello, World!
13
18
 
14
- Glimmer code (from `samples/hello/hello_world.rb`):
19
+ Glimmer code (from SWT desktop app sample [`samples/hello/hello_world.rb`](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
15
20
  ```ruby
16
- require 'glimmer-dsl-opal'
17
-
18
21
  include Glimmer
19
22
 
20
23
  shell {
@@ -25,18 +28,23 @@ shell {
25
28
  }.open
26
29
  ```
27
30
 
28
- Run:
29
- ```
30
- glimmer samples/hello/hello_world.rb
31
- ```
31
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
32
+
33
+ ![Glimmer DSL for Opal Hello World](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-world.png)
32
34
 
33
- Glimmer app:
35
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
34
36
 
35
37
  ![Glimmer DSL for Opal Hello World](images/glimmer-dsl-opal-hello-world.png)
36
38
 
37
- ## Background
39
+ ## Supported Widgets
38
40
 
39
- Ruby is a dynamically-typed object-oriented language, which provides great productivity gains due to its powerful expressive syntax and dynamic nature. While it is proven by the Ruby on Rails framework for web development, it currently lacks a robust platform-independent framework for building desktop applications. Given that Java libraries can now be utilized in Ruby code through JRuby, Eclipse technologies, such as SWT, JFace, and RCP can help fill the gap of desktop application development with Ruby.
41
+ The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) have partial support in Opal:
42
+
43
+ - `shell`
44
+ - `label`
45
+ - `combo`
46
+ - `button`
47
+ - `composite` (single-column `grid_layout` only)
40
48
 
41
49
  ## Pre-requisites
42
50
 
@@ -59,7 +67,7 @@ Add the following to `Gemfile`:
59
67
  ```
60
68
  gem 'opal-rails'
61
69
  gem 'opal-browser'
62
- gem 'glimmer-dsl-opal', '~> 0.0.1', require: false
70
+ gem 'glimmer-dsl-opal', '~> 0.0.2', require: false
63
71
  ```
64
72
 
65
73
  Edit `config/initializers/assets.rb` and add:
@@ -67,6 +75,10 @@ Edit `config/initializers/assets.rb` and add:
67
75
  Opal.use_gem 'glimmer-dsl-opal'
68
76
  ```
69
77
 
78
+ ## Examples
79
+
80
+ ### Hello, World!
81
+
70
82
  Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
71
83
 
72
84
  ```ruby
@@ -82,6 +94,12 @@ shell {
82
94
  }
83
95
  ```
84
96
 
97
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
98
+
99
+ ![Glimmer DSL for Opal Hello World](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-world.png)
100
+
101
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
102
+
85
103
  Start the Rails server:
86
104
  ```
87
105
  rails s
@@ -93,6 +111,65 @@ You should see "Hello, World!"
93
111
 
94
112
  ![Glimmer DSL for Opal Hello World](images/glimmer-dsl-opal-hello-world.png)
95
113
 
114
+ ### Hello, Combo!
115
+
116
+ Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
117
+
118
+ ```ruby
119
+ require 'glimmer-dsl-opal' # brings opal and opal browser too
120
+
121
+ class Person
122
+ attr_accessor :country, :country_options
123
+
124
+ def initialize
125
+ self.country_options=["", "Canada", "US", "Mexico"]
126
+ self.country = "Canada"
127
+ end
128
+
129
+ def reset_country
130
+ self.country = "Canada"
131
+ end
132
+ end
133
+
134
+ class HelloCombo
135
+ include Glimmer
136
+ def launch
137
+ person = Person.new
138
+ shell {
139
+ composite {
140
+ combo(:read_only) {
141
+ selection bind(person, :country)
142
+ }
143
+ button {
144
+ text "Reset"
145
+ on_widget_selected do
146
+ person.reset_country
147
+ end
148
+ }
149
+ }
150
+ }.open
151
+ end
152
+ end
153
+
154
+ HelloCombo.new.launch
155
+ ```
156
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
157
+
158
+ ![Glimmer DSL for Opal Hello Combo](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-combo.png)
159
+
160
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
161
+
162
+ Start the Rails server:
163
+ ```
164
+ rails s
165
+ ```
166
+
167
+ Visit `http://localhost:3000`
168
+
169
+ You should see "Hello, Combo!"
170
+
171
+ ![Glimmer DSL for Opal Hello Combo](images/glimmer-dsl-opal-hello-combo.png)
172
+
96
173
  ## Help
97
174
 
98
175
  ### Issues
@@ -101,11 +178,9 @@ You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub
101
178
 
102
179
  [Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
103
180
 
104
- ### IRC Channel
105
-
106
- If you need live help, try the [#glimmer](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer) IRC channel on [irc.mibbit.net](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer). If no one was available, you may [leave a GitHub issue](https://github.com/AndyObtiva/glimmer/issues) to schedule a meetup on IRC.
181
+ ### Chat
107
182
 
108
- [Click here to connect to #glimmer IRC channel immediately via a web interface.](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer)
183
+ If you need live help, try to [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
109
184
 
110
185
  ## Feature Suggestions
111
186
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -1,8 +1,10 @@
1
- # if RUBY_ENGINE == 'opal' # or test if env is test
2
- $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
3
-
4
- require 'opal'
5
- require 'glimmer'
6
-
7
- require 'glimmer/dsl/opal/dsl'
8
- # end
1
+ require 'opal'
2
+ require 'opal-parser'
3
+ require 'glimmer'
4
+
5
+ GLIMMER_DSL_OPAL_ROOT = File.expand_path('../..', __FILE__)
6
+ GLIMMER_DSL_OPAL_LIB = File.join(GLIMMER_DSL_OPAL_ROOT, 'lib')
7
+
8
+ $LOAD_PATH.unshift(GLIMMER_DSL_OPAL_LIB)
9
+
10
+ require 'glimmer/dsl/opal/dsl'
@@ -0,0 +1,35 @@
1
+ require 'glimmer/data_binding/observable'
2
+ require 'glimmer/data_binding/observer'
3
+
4
+ module Glimmer
5
+ module DataBinding
6
+ class ElementBinding
7
+ include Glimmer
8
+ include Observable
9
+ include Observer
10
+
11
+ attr_reader :element, :property
12
+ def initialize(element, property, translator = nil)
13
+ @element = element
14
+ @property = property
15
+ @translator = translator || proc {|value| value}
16
+
17
+ # TODO see if this is needed in Opal
18
+ # if @element.respond_to?(:dispose)
19
+ # @element.on_widget_disposed do |dispose_event|
20
+ # unregister_all_observables
21
+ # end
22
+ # end
23
+ end
24
+
25
+ def call(value)
26
+ converted_value = translated_value = @translator.call(value)
27
+ @element.send(@property + '=', converted_value) unless evaluate_property == converted_value
28
+ end
29
+
30
+ def evaluate_property
31
+ @element.send(@property)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Glimmer
2
+ module DataBinding
3
+ module ObservableElement
4
+ def method_missing(method, *args, &block)
5
+ method_name = method.to_s
6
+ if method_name.start_with?('on_')
7
+ handle_observation_request(method_name, &block)
8
+ else
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,37 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/data_binding/model_binding'
3
+
4
+ module Glimmer
5
+ module DSL
6
+ module Opal
7
+ # Responsible for setting up the return value of the bind keyword (command symbol)
8
+ # as a ModelBinding. It is then used by another command handler like
9
+ # DataBindingCommandHandler for text and selection properties on Text and Spinner
10
+ # or TableItemsDataBindingCommandHandler for items in a Table
11
+ class BindExpression < StaticExpression
12
+ def can_interpret?(parent, keyword, *args, &block)
13
+ (
14
+ keyword == 'bind' and
15
+ (
16
+ (
17
+ (args.size == 2) and
18
+ textual?(args[1])
19
+ ) ||
20
+ (
21
+ (args.size == 3) and
22
+ textual?(args[1]) and
23
+ (args[2].is_a?(Hash))
24
+ )
25
+ )
26
+ )
27
+ end
28
+
29
+ def interpret(parent, keyword, *args, &block)
30
+ binding_options = args[2] || {}
31
+ binding_options[:on_read] = binding_options.delete(:on_read) || binding_options.delete('on_read') || block
32
+ DataBinding::ModelBinding.new(args[0], args[1].to_s, binding_options)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/parent_expression'
3
+ require 'glimmer/opal/input_proxy'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module Opal
8
+ class ButtonExpression < StaticExpression
9
+ include ParentExpression
10
+
11
+ def interpret(parent, keyword, *args, &block)
12
+ Glimmer::Opal::InputProxy.new(parent, args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/parent_expression'
3
+ require 'glimmer/opal/select_proxy'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module Opal
8
+ class ComboExpression < StaticExpression
9
+ include ParentExpression
10
+
11
+ def interpret(parent, keyword, *args, &block)
12
+ Glimmer::Opal::SelectProxy.new(parent, args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ require 'glimmer/dsl/expression'
2
+ require 'glimmer/data_binding/model_binding'
3
+ require 'glimmer/data_binding/element_binding'
4
+ require 'glimmer/opal/select_proxy'
5
+
6
+ module Glimmer
7
+ module DSL
8
+ module Opal
9
+ class ComboSelectionDataBindingExpression < Expression
10
+ def can_interpret?(parent, keyword, *args, &block)
11
+ keyword == 'selection' and
12
+ block.nil? and
13
+ parent.is_a?(Glimmer::Opal::SelectProxy) and
14
+ args.size == 1 and
15
+ args[0].is_a?(DataBinding::ModelBinding) and
16
+ args[0].evaluate_options_property.is_a?(Array)
17
+ end
18
+
19
+ def interpret(parent, keyword, *args, &block)
20
+ model_binding = args[0]
21
+
22
+ #TODO make this options observer dependent and all similar observers in element specific data binding handlers
23
+ # TODO consider delegating some of this work
24
+ element_binding = DataBinding::ElementBinding.new(parent, 'items')
25
+ element_binding.call(model_binding.evaluate_options_property)
26
+ model = model_binding.base_model
27
+ element_binding.observe(model, model_binding.options_property_name)
28
+
29
+ element_binding = DataBinding::ElementBinding.new(parent, 'text')
30
+ element_binding.call(model_binding.evaluate_property)
31
+ element_binding.observe(model, model_binding.property_name_expression)
32
+
33
+ parent.on_widget_selected do
34
+ model_binding.call(element_binding.evaluate_property)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/parent_expression'
3
+ require 'glimmer/opal/div_proxy'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module Opal
8
+ class CompositeExpression < StaticExpression
9
+ include ParentExpression
10
+
11
+ def interpret(parent, keyword, *args, &block)
12
+ Glimmer::Opal::DivProxy.new(parent, args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ require 'glimmer/dsl/expression'
2
+ require 'glimmer/data_binding/model_binding'
3
+ require 'glimmer/data_binding/element_binding'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module Opal
8
+ # Responsible for wiring two-way data-binding for text and selection properties
9
+ # on Text, Button, and Spinner elements.
10
+ # Does so by using the output of the bind(model, property) command in the form
11
+ # of a ModelBinding, which is then connected to an anonymous element observer
12
+ # (aka element_data_binder as per element_data_binders array)
13
+ #
14
+ # Depends on BindCommandHandler
15
+ class DataBindingExpression < Expression
16
+ def can_interpret?(parent, keyword, *args, &block)
17
+ args.size == 1 and
18
+ args[0].is_a?(DataBinding::ModelBinding)
19
+ end
20
+
21
+ def interpret(parent, keyword, *args, &block)
22
+ model_binding = args[0]
23
+ element_binding_parameters = [parent, keyword]
24
+ element_binding = DataBinding::ElementBinding.new(*element_binding_parameters)
25
+ element_binding.call(model_binding.evaluate_property)
26
+ #TODO make this options observer dependent and all similar observers in element specific data binding handlers
27
+ element_binding.observe(model_binding)
28
+ # TODO simplify this logic and put it where it belongs
29
+ parent.add_observer(model_binding, keyword) if parent.respond_to?(:add_observer, [model_binding, keyword])
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -6,6 +6,13 @@ require 'glimmer/dsl/engine'
6
6
  require 'glimmer/dsl/opal/shell_expression'
7
7
  require 'glimmer/dsl/opal/label_expression'
8
8
  require 'glimmer/dsl/opal/property_expression'
9
+ require 'glimmer/dsl/opal/combo_expression'
10
+ require 'glimmer/dsl/opal/composite_expression'
11
+ require 'glimmer/dsl/opal/button_expression'
12
+ require 'glimmer/dsl/opal/bind_expression'
13
+ # require 'glimmer/dsl/opal/data_binding_expression'
14
+ require 'glimmer/dsl/opal/combo_selection_data_binding_expression'
15
+ require 'glimmer/dsl/opal/widget_listener_expression'
9
16
 
10
17
  module Glimmer
11
18
  module DSL
@@ -13,6 +20,8 @@ module Glimmer
13
20
  Engine.add_dynamic_expressions(
14
21
  Opal,
15
22
  %w[
23
+ widget_listener
24
+ combo_selection_data_binding
16
25
  property
17
26
  ]
18
27
  )