glimmer-dsl-opal 0.0.5 → 0.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +1003 -58
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +26 -8
  6. data/lib/glimmer/data_binding/element_binding.rb +1 -1
  7. data/lib/glimmer/data_binding/ext/observable_model.rb +40 -0
  8. data/lib/glimmer/data_binding/list_selection_binding.rb +1 -1
  9. data/lib/glimmer/data_binding/table_items_binding.rb +70 -0
  10. data/lib/glimmer/dsl/opal/async_exec_expression.rb +17 -0
  11. data/lib/glimmer/dsl/opal/column_properties_expression.rb +22 -0
  12. data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +2 -2
  13. data/lib/glimmer/dsl/opal/dsl.rb +10 -12
  14. data/lib/glimmer/dsl/opal/layout_data_expression.rb +2 -2
  15. data/lib/glimmer/dsl/opal/{text_expression.rb → layout_expression.rb} +5 -5
  16. data/lib/glimmer/dsl/opal/list_selection_data_binding_expression.rb +2 -3
  17. data/lib/glimmer/dsl/opal/message_box_expression.rb +20 -0
  18. data/lib/glimmer/dsl/opal/observe_expression.rb +32 -0
  19. data/lib/glimmer/dsl/opal/shell_expression.rb +2 -2
  20. data/lib/glimmer/dsl/opal/{composite_expression.rb → table_column_expression.rb} +3 -3
  21. data/lib/glimmer/dsl/opal/{list_expression.rb → table_expression.rb} +3 -3
  22. data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +29 -0
  23. data/lib/glimmer/dsl/opal/widget_expression.rb +23 -0
  24. data/lib/glimmer/opal/display_proxy.rb +23 -0
  25. data/lib/glimmer/opal/element_proxy.rb +48 -13
  26. data/lib/glimmer/swt/browser_proxy.rb +27 -0
  27. data/lib/glimmer/swt/button_proxy.rb +40 -0
  28. data/lib/glimmer/{opal/select_proxy.rb → swt/combo_proxy.rb} +15 -11
  29. data/lib/glimmer/swt/composite_proxy.rb +31 -0
  30. data/lib/glimmer/{opal → swt}/event_listener_proxy.rb +1 -1
  31. data/lib/glimmer/{opal → swt}/grid_layout_proxy.rb +7 -18
  32. data/lib/glimmer/swt/label_proxy.rb +30 -0
  33. data/lib/glimmer/swt/layout_data_proxy.rb +52 -0
  34. data/lib/glimmer/swt/layout_proxy.rb +60 -0
  35. data/lib/glimmer/{opal → swt}/list_proxy.rb +18 -15
  36. data/lib/glimmer/swt/message_box_proxy.rb +146 -0
  37. data/lib/glimmer/{opal → swt}/point.rb +1 -1
  38. data/lib/glimmer/{opal → swt}/property_owner.rb +1 -1
  39. data/lib/glimmer/swt/shell_proxy.rb +235 -0
  40. data/lib/glimmer/swt/tab_folder_proxy.rb +52 -0
  41. data/lib/glimmer/swt/tab_item_proxy.rb +101 -0
  42. data/lib/glimmer/swt/table_column_proxy.rb +56 -0
  43. data/lib/glimmer/swt/table_item_proxy.rb +147 -0
  44. data/lib/glimmer/swt/table_proxy.rb +177 -0
  45. data/lib/glimmer/swt/text_proxy.rb +46 -0
  46. data/lib/glimmer/swt/widget_proxy.rb +389 -0
  47. data/lib/jquery.js +2 -0
  48. data/lib/samples/elaborate/contact_manager.rb +2 -3
  49. data/lib/samples/elaborate/login.rb +0 -1
  50. data/lib/samples/elaborate/tic_tac_toe.rb +5 -5
  51. data/lib/samples/hello/hello_computed.rb +19 -19
  52. data/lib/samples/hello/hello_tab.rb +2 -2
  53. metadata +92 -59
  54. data/lib/glimmer/config.rb +0 -22
  55. data/lib/glimmer/dsl/engine.rb +0 -193
  56. data/lib/glimmer/dsl/expression.rb +0 -42
  57. data/lib/glimmer/dsl/expression_handler.rb +0 -48
  58. data/lib/glimmer/dsl/opal/browser_expression.rb +0 -17
  59. data/lib/glimmer/dsl/opal/button_expression.rb +0 -18
  60. data/lib/glimmer/dsl/opal/combo_expression.rb +0 -17
  61. data/lib/glimmer/dsl/opal/grid_layout_expression.rb +0 -17
  62. data/lib/glimmer/dsl/opal/label_expression.rb +0 -17
  63. data/lib/glimmer/dsl/parent_expression.rb +0 -12
  64. data/lib/glimmer/dsl/static_expression.rb +0 -36
  65. data/lib/glimmer/dsl/top_level_expression.rb +0 -7
  66. data/lib/glimmer/error.rb +0 -6
  67. data/lib/glimmer/invalid_keyword_error.rb +0 -6
  68. data/lib/glimmer/opal/div_proxy.rb +0 -20
  69. data/lib/glimmer/opal/document_proxy.rb +0 -90
  70. data/lib/glimmer/opal/iframe_proxy.rb +0 -23
  71. data/lib/glimmer/opal/input_proxy.rb +0 -41
  72. data/lib/glimmer/opal/label_proxy.rb +0 -25
  73. data/lib/glimmer/opal/layout_data_proxy.rb +0 -31
@@ -0,0 +1,60 @@
1
+ require 'glimmer/swt/property_owner'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class LayoutProxy
6
+ include Glimmer::SWT::PropertyOwner
7
+
8
+ class << self
9
+ # Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
10
+ def for(keyword, parent, args)
11
+ the_layout_class = layout_class(keyword) || Glimmer::SWT::GridLayoutProxy
12
+ the_layout_class.new(parent, args)
13
+ end
14
+
15
+ def layout_class(keyword)
16
+ class_name_alternative = keyword.camelcase(:upper)
17
+ class_name_main = "#{class_name_alternative}Proxy"
18
+ a_layout_class = Glimmer::SWT.const_get(class_name_main.to_sym) rescue Glimmer::SWT.const_get(class_name_alternative.to_sym)
19
+ a_layout_class if a_layout_class.ancestors.include?(Glimmer::SWT::LayoutProxy)
20
+ rescue => e
21
+ puts "Layout #{keyword} was not found!"
22
+ nil
23
+ end
24
+
25
+ def layout_exists?(keyword)
26
+ !!layout_class(keyword)
27
+ end
28
+ end
29
+
30
+ attr_reader :parent, :args
31
+
32
+ def initialize(parent, args)
33
+ @parent = parent
34
+ @args = args
35
+ @parent.add_css_class(css_class)
36
+ end
37
+
38
+ def css_class
39
+ self.class.name.split('::').last.underscore.sub(/_proxy$/, '').gsub('_', '-')
40
+ end
41
+
42
+ def reapply
43
+ layout_css = <<~CSS
44
+ display: grid;
45
+ grid-template-columns: #{'auto ' * @num_columns.to_i};
46
+ grid-row-gap: #{@vertical_spacing}px;
47
+ grid-column-gap: #{@horizontal_spacing}px;
48
+ justify-content: start;
49
+ CSS
50
+ layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
51
+ unless key.nil?
52
+ @parent.dom_element.css(key, value)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ require 'glimmer/swt/grid_layout_proxy'
@@ -1,19 +1,19 @@
1
- require 'glimmer/opal/element_proxy'
1
+ require 'glimmer/swt/widget_proxy'
2
2
 
3
3
  module Glimmer
4
- module Opal
5
- class ListProxy < ElementProxy
4
+ module SWT
5
+ class ListProxy < WidgetProxy
6
6
  ITEM_EMPTY = '_____'
7
7
  attr_reader :items, :selection
8
8
 
9
- def initialize(parent, args)
9
+ def initialize(parent, args)
10
10
  super(parent, args)
11
11
  @selection = []
12
12
  end
13
13
 
14
14
  def items=(items)
15
15
  @items = items.map {|item| item.strip == '' ? ITEM_EMPTY : item}
16
- redraw
16
+ redraw # consider repopulating li's instead of redrawing when li's are available.
17
17
  end
18
18
 
19
19
  def index_of(item)
@@ -43,37 +43,40 @@ module Glimmer
43
43
  'on_widget_selected' => {
44
44
  event: 'click',
45
45
  event_handler: -> (event_listener) {
46
- -> (event) {
47
- selected_item = event.target.text
48
- select(index_of(selected_item), event.meta?)
49
- event_listener.call(event)
46
+ -> (event) {
47
+ if event.target.prop('nodeName') == 'LI'
48
+ selected_item = event.target.text
49
+ select(index_of(selected_item), event.meta_key)
50
+ event_listener.call(event)
51
+ end
50
52
  }
51
53
  }
52
54
  }
53
55
  }
54
56
  end
55
57
 
56
- def name
58
+ def element
57
59
  'ul'
58
60
  end
59
61
 
60
62
  def dom
61
63
  list_items = @items
62
64
  list_id = id
63
- list_style = style
65
+ list_style = css
64
66
  list_selection = selection
65
- @dom ||= DOM {
66
- ul(id: list_id, style: list_style) {
67
+ @dom ||= html {
68
+ ul(id: list_id, class: name, style: list_style) {
67
69
  list_items.to_a.each_with_index do |item, index|
68
70
  li_class = ''
69
- li_class += ' selected-list-item' if list_selection.include?(item)
71
+ li_class += ' selected' if list_selection.include?(item)
70
72
  li_class += ' empty-list-item' if item == ITEM_EMPTY
71
73
  li(class: li_class) {
72
74
  item
73
75
  }
74
76
  end
77
+ nil #TODO look into glimmer-dsl-xml and why it doesn't ignore collections like each_with_index
75
78
  }
76
- }
79
+ }.to_s
77
80
  end
78
81
  end
79
82
  end
@@ -0,0 +1,146 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class MessageBoxProxy < WidgetProxy
6
+ attr_reader :text, :message
7
+
8
+ def initialize(parent, args)
9
+ i = 0
10
+ @parent = parent
11
+ @args = args
12
+ @children = Set.new
13
+ @css_classes = Set.new(['modal', name])
14
+ @css = ''
15
+ @enabled = true
16
+ content do
17
+ on_widget_selected {
18
+ hide
19
+ }
20
+ end
21
+ end
22
+
23
+ def text=(txt)
24
+ @text = txt
25
+ redraw if @dom
26
+ end
27
+
28
+ def message=(msg)
29
+ @message = msg
30
+ redraw if @dom
31
+ end
32
+
33
+ def document
34
+ element = self
35
+ begin
36
+ element = element.parent
37
+ end while(element.parent)
38
+ element
39
+ end
40
+
41
+ def open
42
+ document.add_child(self)
43
+ end
44
+
45
+ def hide
46
+ dom_element.remove
47
+ end
48
+
49
+ def content(&block)
50
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::MessageBoxExpression.new, &block)
51
+ end
52
+
53
+ def name
54
+ 'div'
55
+ end
56
+
57
+ def selector
58
+ super + ' .close'
59
+ end
60
+
61
+ def listener_path
62
+ path + ' .close'
63
+ end
64
+
65
+ def observation_request_to_event_mapping
66
+ {
67
+ 'on_widget_selected' => {
68
+ event: 'click'
69
+ },
70
+ }
71
+ end
72
+
73
+ def style_dom_modal_css
74
+ <<~CSS
75
+ .modal {
76
+ position: fixed;
77
+ z-index: 1;
78
+ padding-top: 100px;
79
+ left: 0;
80
+ top: 0;
81
+ width: 100%;
82
+ height: 100%;
83
+ overflow: auto;
84
+ background-color: rgb(0,0,0);
85
+ background-color: rgba(0,0,0,0.4);
86
+ text-align: center;
87
+ }
88
+ .modal-content .text {
89
+ background: rgb(80, 116, 211);
90
+ color: white;
91
+ padding: 5px;
92
+ }
93
+ .modal-content .message {
94
+ padding: 20px;
95
+ }
96
+ .modal-content {
97
+ background-color: #fefefe;
98
+ margin: auto;
99
+ border: 1px solid #888;
100
+ display: inline-block;
101
+ min-width: 200px;
102
+ }
103
+ CSS
104
+ # .close {
105
+ # color: #aaaaaa;
106
+ # float: right;
107
+ # font-weight: bold;
108
+ # margin: 5px;
109
+ # }
110
+ # .close:hover,
111
+ # .close:focus {
112
+ # color: #000;
113
+ # text-decoration: none;
114
+ # cursor: pointer;
115
+ # }
116
+ end
117
+
118
+ def dom
119
+ modal_id = id
120
+ modal_style = css
121
+ modal_text = text
122
+ modal_message = message
123
+ modal_css_classes = css_classes
124
+ modal_class = modal_css_classes.to_a.join(' ')
125
+ @dom ||= html {
126
+ div(id: modal_id, style: modal_style, class: modal_class) {
127
+ style(class: 'modal-style') {
128
+ style_dom_modal_css #.split("\n").map(&:strip).join(' ')
129
+ }
130
+ div(class: 'modal-content') {
131
+ header(class: 'text') {
132
+ modal_text
133
+ }
134
+ tag(_name: 'p', id: 'message') {
135
+ modal_message
136
+ }
137
+ input(type: 'button', class: 'close', autofocus: 'autofocus', value: 'OK')
138
+ }
139
+ }
140
+ }.to_s
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ require 'glimmer/dsl/opal/message_box_expression'
@@ -1,5 +1,5 @@
1
1
  module Glimmer
2
- module Opal
2
+ module SWT
3
3
  Point = Struct.new(:x, :y)
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Glimmer
2
- module Opal
2
+ module SWT
3
3
  # Adapts Glimmer UI classes to SWT JavaBean property owner classes (which are now adapted to Opal)
4
4
  module PropertyOwner
5
5
  def get_attribute(attribute_name)
@@ -0,0 +1,235 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+ require 'glimmer/swt/point'
3
+
4
+ module Glimmer
5
+ module SWT
6
+ class ShellProxy < WidgetProxy
7
+ # TODO consider renaming to ShellProxy to match SWT API
8
+ attr_reader :minimum_size
9
+
10
+ def initialize(args)
11
+ @args = args
12
+ @children = []
13
+ # Document.ready? do
14
+ Document.find('body').empty unless ENV['RUBY_ENV'] == 'test'
15
+ redraw
16
+ # end
17
+ end
18
+
19
+ def element
20
+ 'div'
21
+ end
22
+
23
+ def parent_path
24
+ 'body'
25
+ end
26
+
27
+ def text
28
+ $document.title
29
+ end
30
+
31
+ def text=(value)
32
+ # Document.ready? do
33
+ Document.title = value
34
+ # end
35
+ end
36
+
37
+ def minimum_size=(width_or_minimum_size, height = nil)
38
+ @minimum_size = height.nil? ? width_or_minimum_size : Point.new(width_or_minimum_size, height)
39
+ redraw
40
+ end
41
+
42
+ def style_dom_css
43
+ <<~CSS
44
+ .hide {
45
+ display: none !important;
46
+ }
47
+ .selected, .tabs .tab.selected {
48
+ background: rgb(80, 116, 211);
49
+ color: white;
50
+ }
51
+ CSS
52
+ end
53
+
54
+ def style_dom_shell_css
55
+ <<~CSS
56
+ html {
57
+ width: 100%;
58
+ height: 100%;
59
+ }
60
+ body, .shell {
61
+ width: 100%;
62
+ height: 100%;
63
+ margin: 0;
64
+ }
65
+ .shell iframe {
66
+ width: 100%;
67
+ height: 100%;
68
+ }
69
+ CSS
70
+ end
71
+
72
+ def style_dom_list_css
73
+ <<~CSS
74
+ ul {
75
+ list-style: none;
76
+ padding: 0;
77
+ }
78
+ li {
79
+ cursor: default;
80
+ padding-left: 10px;
81
+ padding-right: 10px;
82
+ }
83
+ li.empty-list-item {
84
+ color: transparent;
85
+ }
86
+ CSS
87
+ end
88
+
89
+ def style_dom_tab_css
90
+ <<~CSS
91
+ .tabs .tab {
92
+ background-color: inherit;
93
+ float: left;
94
+ border: none;
95
+ outline: none;
96
+ cursor: pointer;
97
+ padding: 14px 16px;
98
+ transition: 0.3s;
99
+ font-size: 17px;
100
+ }
101
+ .tabs {
102
+ overflow: hidden;
103
+ border: 1px solid #ccc;
104
+ background-color: #f1f1f1;
105
+ }
106
+ CSS
107
+ end
108
+
109
+ def style_dom_tab_item_css
110
+ <<~CSS
111
+ /* Create an selected/current tablink class */
112
+ .tabs .tab.selected {
113
+ background-color: #ccc;
114
+ }
115
+ /* Change background color of buttons on hover */
116
+ .tabs .tab:hover {
117
+ background-color: #ddd;
118
+ }
119
+ /* Style the tab content */
120
+ .tab-item {
121
+ padding: 6px 12px;
122
+ border: 1px solid #ccc;
123
+ border-top: none;
124
+ }
125
+ CSS
126
+ end
127
+
128
+ def style_dom_modal_css
129
+ <<~CSS
130
+ /* The Modal (background) */
131
+ .modal {
132
+ position: fixed; /* Stay in place */
133
+ z-index: 1; /* Sit on top */
134
+ padding-top: 100px; /* Location of the box */
135
+ left: 0;
136
+ top: 0;
137
+ width: 100%; /* Full width */
138
+ height: 100%; /* Full height */
139
+ overflow: auto; /* Enable scroll if needed */
140
+ background-color: rgb(0,0,0); /* Fallback color */
141
+ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
142
+ text-align: center;
143
+ }
144
+
145
+ /* Modal Content */
146
+ .modal-content {
147
+ background-color: #fefefe;
148
+ margin: auto;
149
+ border: 1px solid #888;
150
+ display: inline-block;
151
+ min-width: 200px;
152
+ }
153
+
154
+ .modal-content .text {
155
+ background: rgb(80, 116, 211);
156
+ color: white;
157
+ padding: 5px;
158
+ }
159
+
160
+ .modal-content .message {
161
+ padding: 20px;
162
+ }
163
+
164
+ /* The Close Button */
165
+ .close {
166
+ color: #aaaaaa;
167
+ float: right;
168
+ font-weight: bold;
169
+ margin: 5px;
170
+ }
171
+
172
+ .close:hover,
173
+ .close:focus {
174
+ color: #000;
175
+ text-decoration: none;
176
+ cursor: pointer;
177
+ }
178
+ CSS
179
+ end
180
+
181
+ def style_dom_table_css
182
+ <<~CSS
183
+ table {
184
+ border-spacing: 0;
185
+ }
186
+
187
+ table tr th,td {
188
+ cursor: default;
189
+ }
190
+ CSS
191
+ end
192
+
193
+ def dom
194
+ i = 0
195
+ body_id = id
196
+ body_class = name
197
+ body_style = '' # a start for more styling further along
198
+ if @minimum_size
199
+ body_style += "min-width: #{@minimum_size.x}px; min-height: #{@minimum_size.y}px;" if @minimum_size
200
+ Document.find('body').css('min-width', "#{@minimum_size.x}px")
201
+ Document.find('body').css('min-height', "#{@minimum_size.y}px")
202
+ end
203
+ @dom ||= html {
204
+ div(id: body_id, class: body_class, style: body_style) {
205
+ style(class: 'common-style') {
206
+ style_dom_css
207
+ }
208
+ style(class: 'shell-style') {
209
+ style_dom_shell_css
210
+ }
211
+ style(class: 'list-style') {
212
+ style_dom_list_css
213
+ }
214
+ style(class: 'tab-style') {
215
+ style_dom_tab_css
216
+ }
217
+ # style(class: 'tab-item-style') {
218
+ # style_dom_tab_item_css
219
+ # }
220
+ # style(class: 'modal-style') {
221
+ # style_dom_modal_css
222
+ # }
223
+ style(class: 'table-style') {
224
+ style_dom_table_css
225
+ }
226
+ }
227
+ }.to_s
228
+ end
229
+
230
+ def open
231
+ # TODO make it start as hidden and show shell upon open
232
+ end
233
+ end
234
+ end
235
+ end