glimmer-dsl-opal 0.7.1 → 0.8.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/README.md +453 -48
- data/VERSION +1 -1
- data/lib/display.rb +31 -0
- data/lib/glimmer-dsl-opal.rb +15 -36
- data/lib/glimmer-dsl-opal/ext/class.rb +10 -0
- data/lib/glimmer-dsl-opal/ext/file.rb +29 -0
- data/lib/glimmer-dsl-opal/ext/struct.rb +37 -0
- data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +50 -23
- data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +22 -5
- data/lib/glimmer-dsl-opal/samples/hello/hello_browser.rb +24 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +46 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +7 -7
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +62 -32
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +47 -22
- data/lib/glimmer-dsl-opal/samples/hello/hello_message_box.rb +37 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_pop_up_context_menu.rb +84 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +2 -2
- data/lib/glimmer/data_binding/observable_element.rb +1 -1
- data/lib/glimmer/data_binding/table_items_binding.rb +3 -3
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +6 -0
- data/lib/glimmer/dsl/opal/dsl.rb +2 -0
- data/lib/glimmer/dsl/opal/menu_bar_expression.rb +54 -0
- data/lib/glimmer/dsl/opal/menu_expression.rb +61 -0
- data/lib/glimmer/dsl/opal/widget_expression.rb +3 -2
- data/lib/glimmer/dsl/opal/widget_listener_expression.rb +2 -2
- data/lib/glimmer/swt/combo_proxy.rb +40 -1
- data/lib/glimmer/swt/control_editor.rb +2 -1
- data/lib/glimmer/swt/custom/checkbox_group.rb +2 -2
- data/lib/glimmer/swt/custom/radio_group.rb +2 -2
- data/lib/glimmer/swt/date_time_proxy.rb +66 -1
- data/lib/glimmer/swt/event_listener_proxy.rb +14 -4
- data/lib/glimmer/swt/font_proxy.rb +4 -4
- data/lib/glimmer/swt/grid_layout_proxy.rb +21 -12
- data/lib/glimmer/swt/label_proxy.rb +17 -6
- data/lib/glimmer/swt/layout_data_proxy.rb +10 -7
- data/lib/glimmer/swt/list_proxy.rb +33 -0
- data/lib/glimmer/swt/menu_item_proxy.rb +87 -0
- data/lib/glimmer/swt/menu_proxy.rb +162 -0
- data/lib/glimmer/swt/message_box_proxy.rb +53 -67
- data/lib/glimmer/swt/property_owner.rb +2 -0
- data/lib/glimmer/swt/radio_proxy.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +32 -187
- data/lib/glimmer/swt/tab_folder_proxy.rb +43 -0
- data/lib/glimmer/swt/table_column_proxy.rb +4 -3
- data/lib/glimmer/swt/table_editor.rb +2 -2
- data/lib/glimmer/swt/table_item_proxy.rb +15 -5
- data/lib/glimmer/swt/table_proxy.rb +34 -12
- data/lib/glimmer/swt/text_proxy.rb +1 -1
- data/lib/glimmer/swt/widget_proxy.rb +335 -38
- data/lib/glimmer/ui/custom_shell.rb +9 -7
- data/lib/glimmer/ui/custom_widget.rb +3 -3
- data/lib/os.rb +36 -0
- metadata +36 -3
@@ -23,16 +23,20 @@ require 'glimmer/swt/event_listener_proxy'
|
|
23
23
|
require 'glimmer/swt/property_owner'
|
24
24
|
require 'glimmer/swt/swt_proxy'
|
25
25
|
|
26
|
+
# TODO implement menu (which delays building it till render using add_content_on_render)
|
27
|
+
|
26
28
|
module Glimmer
|
27
29
|
module SWT
|
28
30
|
class WidgetProxy
|
29
31
|
include Glimmer
|
30
32
|
include PropertyOwner
|
31
33
|
|
32
|
-
attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered
|
34
|
+
attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered, :menu_requested
|
35
|
+
attr_accessor :menu
|
33
36
|
alias isDisposed disposed?
|
34
37
|
alias is_disposed disposed?
|
35
38
|
alias rendered? rendered
|
39
|
+
alias menu_requested? menu_requested
|
36
40
|
|
37
41
|
class << self
|
38
42
|
# Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
|
@@ -76,7 +80,7 @@ module Glimmer
|
|
76
80
|
end
|
77
81
|
|
78
82
|
DEFAULT_INITIALIZERS = {
|
79
|
-
|
83
|
+
composite: lambda do |composite_proxy|
|
80
84
|
if composite_proxy.layout.nil?
|
81
85
|
layout = GridLayoutProxy.new(composite_proxy, [])
|
82
86
|
composite_proxy.layout = layout
|
@@ -84,18 +88,18 @@ module Glimmer
|
|
84
88
|
layout.margin_height = 15
|
85
89
|
end
|
86
90
|
end,
|
87
|
-
#
|
91
|
+
# scrolled_composite: lambda do |scrolled_composite|
|
88
92
|
# scrolled_composite.expand_horizontal = true
|
89
93
|
# scrolled_composite.expand_vertical = true
|
90
94
|
# end,
|
91
|
-
#
|
95
|
+
# table: lambda do |table|
|
92
96
|
# table.setHeaderVisible(true)
|
93
97
|
# table.setLinesVisible(true)
|
94
98
|
# end,
|
95
|
-
|
99
|
+
table_column: lambda do |table_column_proxy|
|
96
100
|
table_column_proxy.width = 80
|
97
101
|
end,
|
98
|
-
#
|
102
|
+
# group: lambda do |group_proxy|
|
99
103
|
# group_proxy.layout = GridLayoutProxy.new(group_proxy, []) if group.layout.nil?
|
100
104
|
# end,
|
101
105
|
}
|
@@ -107,7 +111,7 @@ module Glimmer
|
|
107
111
|
@children = Set.new # TODO consider moving to composite
|
108
112
|
@enabled = true
|
109
113
|
@data = {}
|
110
|
-
DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self)]&.call(self)
|
114
|
+
DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self).to_s.to_sym]&.call(self)
|
111
115
|
@parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
|
112
116
|
end
|
113
117
|
|
@@ -124,7 +128,19 @@ module Glimmer
|
|
124
128
|
|
125
129
|
# Executes at the closing of a parent widget curly braces after all children/properties have been added/set
|
126
130
|
def post_add_content
|
127
|
-
|
131
|
+
if !menu.nil? && !is_a?(MenuProxy) && !is_a?(MenuItemProxy)
|
132
|
+
on_mouse_down { |mouse_event|
|
133
|
+
if mouse_event.button == 3 # right-click
|
134
|
+
@menu_requested = true
|
135
|
+
dom_element.css('position', 'relative')
|
136
|
+
menu&.render
|
137
|
+
menu.dom_element.css('position', 'absolute')
|
138
|
+
menu.dom_element.css('left', mouse_event.x - parent.layout&.margin_width.to_i) # TODO - parent.layout&.margin_left.to_i)
|
139
|
+
menu.dom_element.css('top', mouse_event.y - parent.layout&.margin_height.to_i - 5) # TODO - parent.layout&.margin_top.to_i)
|
140
|
+
@menu_requested = false
|
141
|
+
end
|
142
|
+
}
|
143
|
+
end
|
128
144
|
end
|
129
145
|
|
130
146
|
def set_data(key=nil, value)
|
@@ -148,18 +164,20 @@ module Glimmer
|
|
148
164
|
Document.find(path).remove
|
149
165
|
parent&.post_dispose_child(self)
|
150
166
|
# TODO fire on_widget_disposed listener
|
167
|
+
# children.each(:dispose) # TODO enable this safely
|
151
168
|
@disposed = true
|
152
169
|
end
|
153
170
|
|
154
171
|
def remove_all_listeners
|
155
|
-
|
156
|
-
[
|
157
|
-
|
172
|
+
effective_observation_request_to_event_mapping.keys.each do |keyword|
|
173
|
+
effective_observation_request_to_event_mapping[keyword].to_collection.each do |mapping|
|
174
|
+
observation_requests[keyword].to_a.each do |event_listener|
|
158
175
|
event = mapping[:event]
|
159
176
|
event_handler = mapping[:event_handler]
|
160
177
|
event_element_css_selector = mapping[:event_element_css_selector]
|
161
178
|
the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
|
162
179
|
the_listener_dom_element.off(event)
|
180
|
+
# TODO improve to precisely remove the listeners that were added, no more no less. (or use the event_listener_proxies method instead or in collaboration)
|
163
181
|
end
|
164
182
|
end
|
165
183
|
end
|
@@ -215,27 +233,26 @@ module Glimmer
|
|
215
233
|
Document.find(parent_path)
|
216
234
|
end
|
217
235
|
|
218
|
-
def render(custom_parent_dom_element
|
236
|
+
def render(custom_parent_dom_element: nil, brand_new: false)
|
219
237
|
the_parent_dom_element = custom_parent_dom_element || parent_dom_element
|
220
238
|
old_element = dom_element
|
221
|
-
brand_new = @dom.nil? || old_element.empty?
|
222
|
-
build_dom(!custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
|
239
|
+
brand_new = @dom.nil? || old_element.empty? || brand_new
|
240
|
+
build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
|
223
241
|
if brand_new
|
224
242
|
the_parent_dom_element.append(@dom)
|
225
243
|
else
|
226
244
|
old_element.replace_with(@dom)
|
227
245
|
end
|
228
|
-
|
246
|
+
observation_requests&.each do |keyword, event_listener_set|
|
229
247
|
event_listener_set.each do |event_listener|
|
230
|
-
|
231
|
-
handle_observation_request(keyword, &event_listener)
|
248
|
+
handle_observation_request(keyword, event_listener)
|
232
249
|
end
|
233
250
|
end
|
234
251
|
children.each do |child|
|
235
252
|
child.render
|
236
253
|
end
|
237
254
|
@rendered = true
|
238
|
-
content_on_render_blocks.each { |content_block| content(&content_block) }
|
255
|
+
content_on_render_blocks.each { |content_block| content(&content_block) } unless skip_content_on_render_blocks?
|
239
256
|
end
|
240
257
|
alias redraw render
|
241
258
|
|
@@ -243,6 +260,10 @@ module Glimmer
|
|
243
260
|
@content_on_render_blocks ||= []
|
244
261
|
end
|
245
262
|
|
263
|
+
def skip_content_on_render_blocks?
|
264
|
+
false
|
265
|
+
end
|
266
|
+
|
246
267
|
def add_content_on_render(&content_block)
|
247
268
|
if rendered?
|
248
269
|
content_block.call
|
@@ -251,7 +272,7 @@ module Glimmer
|
|
251
272
|
end
|
252
273
|
end
|
253
274
|
|
254
|
-
def build_dom(layout
|
275
|
+
def build_dom(layout: true)
|
255
276
|
# TODO consider passing parent element instead and having table item include a table cell widget only for opal
|
256
277
|
@dom = nil
|
257
278
|
@dom = dom
|
@@ -268,6 +289,260 @@ module Glimmer
|
|
268
289
|
{}
|
269
290
|
end
|
270
291
|
|
292
|
+
def effective_observation_request_to_event_mapping
|
293
|
+
default_observation_request_to_event_mapping.merge(observation_request_to_event_mapping)
|
294
|
+
end
|
295
|
+
|
296
|
+
def default_observation_request_to_event_mapping
|
297
|
+
mouse_event_handler = -> (event_listener) {
|
298
|
+
-> (event) {
|
299
|
+
# TODO generalize this solution to all widgets that support key presses
|
300
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
301
|
+
event.define_singleton_method(:button, &event.method(:which))
|
302
|
+
event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
|
303
|
+
event.define_singleton_method(:x, &event.method(:page_x))
|
304
|
+
event.define_singleton_method(:y, &event.method(:page_y))
|
305
|
+
doit = true
|
306
|
+
event.define_singleton_method(:doit=) do |value|
|
307
|
+
doit = value
|
308
|
+
end
|
309
|
+
event.define_singleton_method(:doit) { doit }
|
310
|
+
|
311
|
+
if event.which == 1
|
312
|
+
# event.prevent # TODO consider if this is needed
|
313
|
+
event_listener.call(event)
|
314
|
+
end
|
315
|
+
|
316
|
+
# TODO Imlement doit properly for all different kinds of events
|
317
|
+
# unless doit
|
318
|
+
# event.prevent
|
319
|
+
# event.stop
|
320
|
+
# event.stop_immediate
|
321
|
+
# end
|
322
|
+
}
|
323
|
+
}
|
324
|
+
context_menu_handler = -> (event_listener) {
|
325
|
+
-> (event) {
|
326
|
+
# TODO generalize this solution to all widgets that support key presses
|
327
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
328
|
+
event.define_singleton_method(:button, &event.method(:which))
|
329
|
+
event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
|
330
|
+
event.define_singleton_method(:x, &event.method(:page_x))
|
331
|
+
event.define_singleton_method(:y, &event.method(:page_y))
|
332
|
+
doit = true
|
333
|
+
event.define_singleton_method(:doit=) do |value|
|
334
|
+
doit = value
|
335
|
+
end
|
336
|
+
event.define_singleton_method(:doit) { doit }
|
337
|
+
|
338
|
+
if event.which == 3
|
339
|
+
event.prevent
|
340
|
+
event_listener.call(event)
|
341
|
+
end
|
342
|
+
|
343
|
+
# TODO Imlement doit properly for all different kinds of events
|
344
|
+
# unless doit
|
345
|
+
# event.prevent
|
346
|
+
# event.stop
|
347
|
+
# event.stop_immediate
|
348
|
+
# end
|
349
|
+
}
|
350
|
+
}
|
351
|
+
{
|
352
|
+
'on_focus_gained' => {
|
353
|
+
event: 'focus',
|
354
|
+
},
|
355
|
+
'on_focus_lost' => {
|
356
|
+
event: 'blur',
|
357
|
+
},
|
358
|
+
'on_mouse_up' => [
|
359
|
+
{
|
360
|
+
event: 'mouseup',
|
361
|
+
event_handler: mouse_event_handler,
|
362
|
+
},
|
363
|
+
{
|
364
|
+
event: 'contextmenu',
|
365
|
+
event_handler: context_menu_handler,
|
366
|
+
},
|
367
|
+
],
|
368
|
+
'on_mouse_down' => [
|
369
|
+
{
|
370
|
+
event: 'mousedown',
|
371
|
+
event_handler: mouse_event_handler,
|
372
|
+
},
|
373
|
+
{
|
374
|
+
event: 'contextmenu',
|
375
|
+
event_handler: context_menu_handler,
|
376
|
+
},
|
377
|
+
],
|
378
|
+
'on_swt_mouseup' => [
|
379
|
+
{
|
380
|
+
event: 'mouseup',
|
381
|
+
event_handler: mouse_event_handler,
|
382
|
+
},
|
383
|
+
{
|
384
|
+
event: 'contextmenu',
|
385
|
+
event_handler: context_menu_handler,
|
386
|
+
},
|
387
|
+
],
|
388
|
+
'on_swt_mousedown' => [
|
389
|
+
{
|
390
|
+
event: 'mousedown',
|
391
|
+
event_handler: mouse_event_handler,
|
392
|
+
},
|
393
|
+
{
|
394
|
+
event: 'contextmenu',
|
395
|
+
event_handler: context_menu_handler,
|
396
|
+
},
|
397
|
+
],
|
398
|
+
'on_key_pressed' => {
|
399
|
+
event: 'keypress',
|
400
|
+
event_handler: -> (event_listener) {
|
401
|
+
-> (event) {
|
402
|
+
# TODO generalize this solution to all widgets that support key presses
|
403
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
404
|
+
event.define_singleton_method(:keyCode) {event.which}
|
405
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
406
|
+
event.define_singleton_method(:character) {event.which.chr}
|
407
|
+
event.define_singleton_method(:stateMask) do
|
408
|
+
state_mask = 0
|
409
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
410
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
411
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
412
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
413
|
+
state_mask
|
414
|
+
end
|
415
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
416
|
+
doit = true
|
417
|
+
event.define_singleton_method(:doit=) do |value|
|
418
|
+
doit = value
|
419
|
+
end
|
420
|
+
event.define_singleton_method(:doit) { doit }
|
421
|
+
event_listener.call(event)
|
422
|
+
|
423
|
+
# TODO Fix doit false, it's not stopping input
|
424
|
+
unless doit
|
425
|
+
event.prevent
|
426
|
+
event.prevent_default
|
427
|
+
event.stop_propagation
|
428
|
+
event.stop_immediate_propagation
|
429
|
+
end
|
430
|
+
|
431
|
+
doit
|
432
|
+
}
|
433
|
+
} },
|
434
|
+
'on_key_released' => {
|
435
|
+
event: 'keydown',
|
436
|
+
event_handler: -> (event_listener) {
|
437
|
+
-> (event) {
|
438
|
+
# TODO generalize this solution to all widgets that support key presses
|
439
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
440
|
+
event.define_singleton_method(:keyCode) {event.which}
|
441
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
442
|
+
event.define_singleton_method(:character) {event.which.chr}
|
443
|
+
event.define_singleton_method(:stateMask) do
|
444
|
+
state_mask = 0
|
445
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
446
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
447
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
448
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
449
|
+
state_mask
|
450
|
+
end
|
451
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
452
|
+
doit = true
|
453
|
+
event.define_singleton_method(:doit=) do |value|
|
454
|
+
doit = value
|
455
|
+
end
|
456
|
+
event.define_singleton_method(:doit) { doit }
|
457
|
+
event_listener.call(event)
|
458
|
+
|
459
|
+
# TODO Fix doit false, it's not stopping input
|
460
|
+
unless doit
|
461
|
+
event.prevent
|
462
|
+
event.prevent_default
|
463
|
+
event.stop_propagation
|
464
|
+
event.stop_immediate_propagation
|
465
|
+
end
|
466
|
+
|
467
|
+
doit
|
468
|
+
}
|
469
|
+
} },
|
470
|
+
'on_swt_keydown' => {
|
471
|
+
event: 'keypress',
|
472
|
+
event_handler: -> (event_listener) {
|
473
|
+
-> (event) {
|
474
|
+
# TODO generalize this solution to all widgets that support key presses
|
475
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
476
|
+
event.define_singleton_method(:keyCode) {event.which}
|
477
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
478
|
+
event.define_singleton_method(:character) {event.which.chr}
|
479
|
+
event.define_singleton_method(:stateMask) do
|
480
|
+
state_mask = 0
|
481
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
482
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
483
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
484
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
485
|
+
state_mask
|
486
|
+
end
|
487
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
488
|
+
doit = true
|
489
|
+
event.define_singleton_method(:doit=) do |value|
|
490
|
+
doit = value
|
491
|
+
end
|
492
|
+
event.define_singleton_method(:doit) { doit }
|
493
|
+
event_listener.call(event)
|
494
|
+
|
495
|
+
# TODO Fix doit false, it's not stopping input
|
496
|
+
unless doit
|
497
|
+
event.prevent
|
498
|
+
event.prevent_default
|
499
|
+
event.stop_propagation
|
500
|
+
event.stop_immediate_propagation
|
501
|
+
end
|
502
|
+
|
503
|
+
doit
|
504
|
+
}
|
505
|
+
} },
|
506
|
+
'on_swt_keyup' => {
|
507
|
+
event: 'keydown',
|
508
|
+
event_handler: -> (event_listener) {
|
509
|
+
-> (event) {
|
510
|
+
# TODO generalize this solution to all widgets that support key presses
|
511
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
512
|
+
event.define_singleton_method(:keyCode) {event.which}
|
513
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
514
|
+
event.define_singleton_method(:character) {event.which.chr}
|
515
|
+
event.define_singleton_method(:stateMask) do
|
516
|
+
state_mask = 0
|
517
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
518
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
519
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
520
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
521
|
+
state_mask
|
522
|
+
end
|
523
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
524
|
+
doit = true
|
525
|
+
event.define_singleton_method(:doit=) do |value|
|
526
|
+
doit = value
|
527
|
+
end
|
528
|
+
event.define_singleton_method(:doit) { doit }
|
529
|
+
event_listener.call(event)
|
530
|
+
|
531
|
+
# TODO Fix doit false, it's not stopping input
|
532
|
+
unless doit
|
533
|
+
event.prevent
|
534
|
+
event.prevent_default
|
535
|
+
event.stop_propagation
|
536
|
+
event.stop_immediate_propagation
|
537
|
+
end
|
538
|
+
|
539
|
+
doit
|
540
|
+
}
|
541
|
+
}
|
542
|
+
},
|
543
|
+
}
|
544
|
+
end
|
545
|
+
|
271
546
|
def name
|
272
547
|
self.class.name.split('::').last.underscore.sub(/_proxy$/, '').gsub('_', '-')
|
273
548
|
end
|
@@ -339,6 +614,14 @@ module Glimmer
|
|
339
614
|
Document.find(listener_path)
|
340
615
|
end
|
341
616
|
|
617
|
+
def observation_requests
|
618
|
+
@observation_requests ||= {}
|
619
|
+
end
|
620
|
+
|
621
|
+
def event_listener_proxies
|
622
|
+
@event_listener_proxies ||= []
|
623
|
+
end
|
624
|
+
|
342
625
|
def can_handle_observation_request?(observation_request)
|
343
626
|
# TODO sort this out for Opal
|
344
627
|
observation_request = observation_request.to_s
|
@@ -352,29 +635,40 @@ module Glimmer
|
|
352
635
|
end
|
353
636
|
end
|
354
637
|
|
355
|
-
def handle_observation_request(keyword,
|
356
|
-
return unless
|
357
|
-
@observation_requests ||= {}
|
358
|
-
@observation_requests[keyword] ||= Set.new
|
638
|
+
def handle_observation_request(keyword, original_event_listener)
|
639
|
+
return unless effective_observation_request_to_event_mapping.keys.include?(keyword)
|
359
640
|
event = nil
|
360
641
|
delegate = nil
|
361
|
-
[
|
362
|
-
|
642
|
+
effective_observation_request_to_event_mapping[keyword].to_collection.each do |mapping|
|
643
|
+
observation_requests[keyword] ||= Set.new
|
644
|
+
observation_requests[keyword] << original_event_listener
|
363
645
|
event = mapping[:event]
|
364
646
|
event_handler = mapping[:event_handler]
|
365
647
|
event_element_css_selector = mapping[:event_element_css_selector]
|
366
|
-
potential_event_listener = event_handler&.call(
|
367
|
-
event_listener = potential_event_listener ||
|
648
|
+
potential_event_listener = event_handler&.call(original_event_listener)
|
649
|
+
event_listener = potential_event_listener || original_event_listener
|
368
650
|
async_event_listener = lambda do |event|
|
369
|
-
|
651
|
+
# TODO look into the issue with using async::task.new here. maybe put it in event listener (like not being able to call preventDefault or return false successfully )
|
652
|
+
# maybe consider pushing inside the widget classes instead where needed only or implement universal doit support correctly to bypass this issue
|
653
|
+
# Async::Task.new do
|
370
654
|
event_listener.call(event)
|
371
|
-
|
655
|
+
# end
|
372
656
|
end
|
373
657
|
the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
|
374
|
-
|
658
|
+
unless the_listener_dom_element.empty?
|
659
|
+
the_listener_dom_element.on(event, &async_event_listener)
|
660
|
+
# TODO ensure uniqueness of insertion (perhaps adding equals/hash method to event listener proxy)
|
661
|
+
|
662
|
+
event_listener_proxies << EventListenerProxy.new(element_proxy: self, selector: selector, dom_element: the_listener_dom_element, event: event, listener: async_event_listener, original_event_listener: original_event_listener)
|
663
|
+
end
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
def remove_event_listener_proxies
|
668
|
+
event_listener_proxies.each do |event_listener_proxy|
|
669
|
+
event_listener_proxy.unregister
|
375
670
|
end
|
376
|
-
|
377
|
-
EventListenerProxy.new(element_proxy: self, event: event, selector: selector, delegate: delegate)
|
671
|
+
event_listener_proxies.clear
|
378
672
|
end
|
379
673
|
|
380
674
|
def add_observer(observer, property_name)
|
@@ -392,12 +686,17 @@ module Glimmer
|
|
392
686
|
|
393
687
|
def method_missing(method, *args, &block)
|
394
688
|
if method.to_s.start_with?('on_')
|
395
|
-
handle_observation_request(method,
|
689
|
+
handle_observation_request(method, block)
|
396
690
|
else
|
397
691
|
super(method, *args, &block)
|
398
692
|
end
|
399
693
|
end
|
400
694
|
|
695
|
+
def swt_widget
|
696
|
+
# only added for compatibility/adaptibility with Glimmer DSL for SWT
|
697
|
+
self
|
698
|
+
end
|
699
|
+
|
401
700
|
def apply_property_type_converters(attribute_name, args)
|
402
701
|
if args.count == 1
|
403
702
|
value = args.first
|
@@ -555,11 +854,7 @@ module Glimmer
|
|
555
854
|
TableProxy => {
|
556
855
|
:selection => lambda do |observer|
|
557
856
|
on_widget_selected { |selection_event|
|
558
|
-
|
559
|
-
observer.call(selection.map(&:get_data))
|
560
|
-
else
|
561
|
-
observer.call(selection.first&.get_data)
|
562
|
-
end
|
857
|
+
observer.call(selection_event.table_item.get_data) # TODO ensure selection doesn't conflict with editing
|
563
858
|
}
|
564
859
|
end,
|
565
860
|
},
|
@@ -594,6 +889,8 @@ require 'glimmer/swt/date_time_proxy'
|
|
594
889
|
require 'glimmer/swt/group_proxy'
|
595
890
|
require 'glimmer/swt/label_proxy'
|
596
891
|
require 'glimmer/swt/list_proxy'
|
892
|
+
require 'glimmer/swt/menu_item_proxy'
|
893
|
+
require 'glimmer/swt/menu_proxy'
|
597
894
|
require 'glimmer/swt/radio_proxy'
|
598
895
|
require 'glimmer/swt/tab_folder_proxy'
|
599
896
|
require 'glimmer/swt/tab_item_proxy'
|