glimmer-dsl-web 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +475 -219
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +12 -5
- data/lib/glimmer/data_binding/element_binding.rb +3 -3
- data/lib/glimmer/dsl/web/bind_expression.rb +36 -0
- data/lib/glimmer/dsl/web/data_binding_expression.rb +30 -0
- data/lib/glimmer/dsl/web/dsl.rb +7 -0
- data/lib/glimmer/dsl/web/element_expression.rb +3 -21
- data/lib/glimmer/dsl/web/general_element_expression.rb +29 -0
- data/lib/glimmer/dsl/web/p_expression.rb +12 -0
- data/lib/glimmer/dsl/web/select_expression.rb +12 -0
- data/lib/glimmer/dsl/web/shine_data_binding_expression.rb +42 -0
- data/lib/glimmer/web/element_proxy.rb +31 -156
- data/lib/glimmer/web/event_proxy.rb +59 -0
- data/lib/glimmer/web/listener_proxy.rb +36 -14
- data/lib/glimmer-dsl-web/samples/hello/hello_button.rb +4 -69
- data/lib/glimmer-dsl-web/samples/hello/hello_data_binding.rb +166 -0
- data/lib/glimmer-dsl-web/samples/hello/hello_form.rb +102 -0
- data/lib/glimmer-dsl-web.rb +1 -7
- metadata +11 -23
- data/lib/glimmer/data_binding/observable_element.rb +0 -14
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|
data/glimmer-dsl-web.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-web 0.0.
|
5
|
+
# stub: glimmer-dsl-web 0.0.6 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-web".freeze
|
9
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.6".freeze
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andy Maleh".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2024-01-01"
|
15
15
|
s.description = "Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library) - Enables frontend GUI development with Ruby by adopting a DSL that follows web-like HTML syntax, enabling the transfer of HTML/CSS/JS skills to Ruby frontend development. This library relies on Opal Ruby.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -31,18 +31,26 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/glimmer-dsl-web/ext/date.rb",
|
32
32
|
"lib/glimmer-dsl-web/ext/exception.rb",
|
33
33
|
"lib/glimmer-dsl-web/samples/hello/hello_button.rb",
|
34
|
+
"lib/glimmer-dsl-web/samples/hello/hello_data_binding.rb",
|
35
|
+
"lib/glimmer-dsl-web/samples/hello/hello_form.rb",
|
34
36
|
"lib/glimmer-dsl-web/samples/hello/hello_world.rb",
|
35
37
|
"lib/glimmer-dsl-web/vendor/jquery.js",
|
36
38
|
"lib/glimmer/config/opal_logger.rb",
|
37
39
|
"lib/glimmer/data_binding/element_binding.rb",
|
38
|
-
"lib/glimmer/
|
40
|
+
"lib/glimmer/dsl/web/bind_expression.rb",
|
41
|
+
"lib/glimmer/dsl/web/data_binding_expression.rb",
|
39
42
|
"lib/glimmer/dsl/web/dsl.rb",
|
40
43
|
"lib/glimmer/dsl/web/element_expression.rb",
|
44
|
+
"lib/glimmer/dsl/web/general_element_expression.rb",
|
41
45
|
"lib/glimmer/dsl/web/listener_expression.rb",
|
46
|
+
"lib/glimmer/dsl/web/p_expression.rb",
|
42
47
|
"lib/glimmer/dsl/web/property_expression.rb",
|
48
|
+
"lib/glimmer/dsl/web/select_expression.rb",
|
49
|
+
"lib/glimmer/dsl/web/shine_data_binding_expression.rb",
|
43
50
|
"lib/glimmer/util/proc_tracker.rb",
|
44
51
|
"lib/glimmer/web.rb",
|
45
52
|
"lib/glimmer/web/element_proxy.rb",
|
53
|
+
"lib/glimmer/web/event_proxy.rb",
|
46
54
|
"lib/glimmer/web/listener_proxy.rb",
|
47
55
|
"lib/glimmer/web/property_owner.rb"
|
48
56
|
]
|
@@ -58,7 +66,6 @@ Gem::Specification.new do |s|
|
|
58
66
|
s.add_runtime_dependency(%q<glimmer-dsl-css>.freeze, ["~> 1.2.2".freeze])
|
59
67
|
s.add_runtime_dependency(%q<opal-async>.freeze, ["~> 1.4.0".freeze])
|
60
68
|
s.add_runtime_dependency(%q<to_collection>.freeze, [">= 2.0.1".freeze, "< 3.0.0".freeze])
|
61
|
-
s.add_runtime_dependency(%q<pure-struct>.freeze, [">= 1.0.2".freeze, "< 2.0.0".freeze])
|
62
69
|
s.add_development_dependency(%q<puts_debuggerer>.freeze, [">= 0".freeze])
|
63
70
|
s.add_development_dependency(%q<rake>.freeze, [">= 10.1.0".freeze, "< 14.0.0".freeze])
|
64
71
|
s.add_development_dependency(%q<rake-tui>.freeze, [">= 0".freeze])
|
@@ -4,7 +4,6 @@ require 'glimmer/data_binding/observer'
|
|
4
4
|
module Glimmer
|
5
5
|
module DataBinding
|
6
6
|
class ElementBinding
|
7
|
-
# TODO consider renaming to WidgetBinding since it's no longer dealing with elements directly yet widgets instead
|
8
7
|
include Glimmer
|
9
8
|
include Observable
|
10
9
|
include Observer
|
@@ -15,7 +14,8 @@ module Glimmer
|
|
15
14
|
@property = property
|
16
15
|
@translator = translator || proc {|value| value}
|
17
16
|
|
18
|
-
# TODO
|
17
|
+
# TODO implement automatic cleanup upon calling element.remove
|
18
|
+
# Alternatively, have this be built into ElementProxy and remove this code
|
19
19
|
# if @element.respond_to?(:dispose)
|
20
20
|
# @element.on_widget_disposed do |dispose_event|
|
21
21
|
# unregister_all_observables
|
@@ -25,7 +25,7 @@ module Glimmer
|
|
25
25
|
|
26
26
|
def call(value)
|
27
27
|
converted_value = translated_value = @translator.call(value)
|
28
|
-
@element.
|
28
|
+
@element.send("#{@property}=", converted_value) unless evaluate_property == converted_value
|
29
29
|
end
|
30
30
|
|
31
31
|
def evaluate_property
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2023 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/dsl/static_expression'
|
23
|
+
require 'glimmer/dsl/bind_expression'
|
24
|
+
require 'glimmer/data_binding/model_binding'
|
25
|
+
|
26
|
+
module Glimmer
|
27
|
+
module DSL
|
28
|
+
module Web
|
29
|
+
# Responsible for setting up the return value of the bind keyword (command symbol)
|
30
|
+
# as a ModelBinding. It is then used by other data-binding expressions
|
31
|
+
class BindExpression < StaticExpression
|
32
|
+
include Glimmer::DSL::BindExpression
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 Web
|
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) and
|
19
|
+
parent.respond_to?(:data_bind)
|
20
|
+
end
|
21
|
+
|
22
|
+
def interpret(parent, keyword, *args, &block)
|
23
|
+
model_binding = args[0]
|
24
|
+
property = keyword
|
25
|
+
parent.data_bind(property, model_binding)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/glimmer/dsl/web/dsl.rb
CHANGED
@@ -3,6 +3,11 @@ require 'glimmer/dsl/engine'
|
|
3
3
|
require 'glimmer/dsl/web/element_expression'
|
4
4
|
require 'glimmer/dsl/web/listener_expression'
|
5
5
|
require 'glimmer/dsl/web/property_expression'
|
6
|
+
require 'glimmer/dsl/web/p_expression'
|
7
|
+
require 'glimmer/dsl/web/select_expression'
|
8
|
+
require 'glimmer/dsl/web/bind_expression'
|
9
|
+
require 'glimmer/dsl/web/data_binding_expression'
|
10
|
+
require 'glimmer/dsl/web/shine_data_binding_expression'
|
6
11
|
|
7
12
|
module Glimmer
|
8
13
|
module DSL
|
@@ -19,7 +24,9 @@ module Glimmer
|
|
19
24
|
Web,
|
20
25
|
%w[
|
21
26
|
listener
|
27
|
+
data_binding
|
22
28
|
property
|
29
|
+
shine_data_binding
|
23
30
|
element
|
24
31
|
]
|
25
32
|
)
|
@@ -1,34 +1,16 @@
|
|
1
1
|
require 'glimmer/dsl/expression'
|
2
|
-
require 'glimmer/dsl/
|
3
|
-
require 'glimmer/web/element_proxy'
|
2
|
+
require 'glimmer/dsl/web/general_element_expression'
|
4
3
|
|
5
4
|
module Glimmer
|
6
5
|
module DSL
|
7
6
|
module Web
|
8
7
|
class ElementExpression < Expression
|
9
|
-
include
|
8
|
+
include GeneralElementExpression
|
10
9
|
|
11
10
|
def can_interpret?(parent, keyword, *args, &block)
|
12
11
|
# TODO automatically pass parent option as element if not passed instead of rejecting elements without a paraent nor root
|
13
12
|
# TODO raise a proper error if root is an element that is not found (maybe do this in model)
|
14
|
-
!keyword.to_s.start_with?('
|
15
|
-
end
|
16
|
-
|
17
|
-
def interpret(parent, keyword, *args, &block)
|
18
|
-
Glimmer::Web::ElementProxy.for(keyword, parent, args, block)
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_content(parent, keyword, *args, &block)
|
22
|
-
if parent.rendered? || parent.skip_content_on_render_blocks?
|
23
|
-
return_value = super(parent, keyword, *args, &block)
|
24
|
-
if return_value.is_a?(String) && parent.dom_element.text.to_s.empty?
|
25
|
-
parent.add_text_content(return_value)
|
26
|
-
end
|
27
|
-
parent.post_add_content
|
28
|
-
return_value
|
29
|
-
else
|
30
|
-
parent.add_content_on_render(&block)
|
31
|
-
end
|
13
|
+
!keyword.to_s.start_with?('on')
|
32
14
|
end
|
33
15
|
end
|
34
16
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'glimmer/dsl/parent_expression'
|
2
|
+
require 'glimmer/web/element_proxy'
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module DSL
|
6
|
+
module Web
|
7
|
+
module GeneralElementExpression
|
8
|
+
include ParentExpression
|
9
|
+
|
10
|
+
def interpret(parent, keyword, *args, &block)
|
11
|
+
Glimmer::Web::ElementProxy.for(keyword, parent, args, block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_content(parent, keyword, *args, &block)
|
15
|
+
if parent.rendered? || parent.skip_content_on_render_blocks?
|
16
|
+
return_value = super(parent, keyword, *args, &block)
|
17
|
+
if return_value.is_a?(String) && parent.dom_element.text.to_s.empty?
|
18
|
+
parent.add_text_content(return_value)
|
19
|
+
end
|
20
|
+
parent.post_add_content
|
21
|
+
return_value
|
22
|
+
else
|
23
|
+
parent.add_content_on_render(&block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (c) 2020-2022 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/dsl/expression'
|
23
|
+
require 'glimmer/data_binding/model_binding'
|
24
|
+
require 'glimmer/data_binding/shine'
|
25
|
+
|
26
|
+
module Glimmer
|
27
|
+
module DSL
|
28
|
+
module Web
|
29
|
+
class ShineDataBindingExpression < Expression
|
30
|
+
def can_interpret?(parent, keyword, *args, &block)
|
31
|
+
args.size == 0 and
|
32
|
+
block.nil? and
|
33
|
+
(parent.respond_to?("#{keyword}=") and parent.respond_to?(keyword))
|
34
|
+
end
|
35
|
+
|
36
|
+
def interpret(parent, keyword, *args, &block)
|
37
|
+
Glimmer::DataBinding::Shine.new(parent, keyword)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -74,7 +74,7 @@ module Glimmer
|
|
74
74
|
|
75
75
|
GLIMMER_ATTRIBUTES = [:parent]
|
76
76
|
|
77
|
-
attr_reader :keyword, :parent, :args, :options, :children, :enabled, :foreground, :background, :
|
77
|
+
attr_reader :keyword, :parent, :args, :options, :children, :enabled, :foreground, :background, :removed?, :rendered
|
78
78
|
alias rendered? rendered
|
79
79
|
|
80
80
|
def initialize(keyword, parent, args, block)
|
@@ -176,16 +176,6 @@ module Glimmer
|
|
176
176
|
dom_element.css('background-color', background.to_css) unless background.nil?
|
177
177
|
end
|
178
178
|
|
179
|
-
def focus=(value)
|
180
|
-
@focus = value
|
181
|
-
dom_element.focus # TODO consider if a delay or async_exec is needed here
|
182
|
-
end
|
183
|
-
|
184
|
-
def set_focus
|
185
|
-
self.focus = true
|
186
|
-
end
|
187
|
-
alias setFocus set_focus
|
188
|
-
|
189
179
|
def parent_selector
|
190
180
|
@parent&.selector
|
191
181
|
end
|
@@ -196,7 +186,9 @@ module Glimmer
|
|
196
186
|
else
|
197
187
|
# TODO consider moving this to initializer
|
198
188
|
options[:parent] ||= 'body'
|
199
|
-
Document.find(options[:parent])
|
189
|
+
the_element = Document.find(options[:parent])
|
190
|
+
the_element = Document.find('body') if the_element.length == 0
|
191
|
+
the_element
|
200
192
|
end
|
201
193
|
end
|
202
194
|
|
@@ -226,7 +218,7 @@ module Glimmer
|
|
226
218
|
end
|
227
219
|
end
|
228
220
|
end
|
229
|
-
alias
|
221
|
+
alias rerender render
|
230
222
|
|
231
223
|
def attach(the_parent_dom_element)
|
232
224
|
the_parent_dom_element.append(@dom)
|
@@ -743,7 +735,7 @@ module Glimmer
|
|
743
735
|
def can_handle_observation_request?(keyword)
|
744
736
|
# TODO sort this out for Opal
|
745
737
|
keyword = keyword.to_s
|
746
|
-
keyword.start_with?('
|
738
|
+
keyword.start_with?('on')
|
747
739
|
# if keyword.start_with?('on_swt_')
|
748
740
|
# constant_name = keyword.sub(/^on_swt_/, '')
|
749
741
|
# SWTProxy.has_constant?(constant_name)
|
@@ -765,10 +757,10 @@ module Glimmer
|
|
765
757
|
|
766
758
|
def handle_javascript_observation_request(keyword, original_event_listener)
|
767
759
|
listener = ListenerProxy.new(
|
768
|
-
|
760
|
+
element: self,
|
769
761
|
selector: selector,
|
770
762
|
dom_element: dom_element,
|
771
|
-
|
763
|
+
event_attribute: keyword,
|
772
764
|
listener: original_event_listener,
|
773
765
|
original_event_listener: original_event_listener
|
774
766
|
)
|
@@ -813,11 +805,19 @@ module Glimmer
|
|
813
805
|
event_listener_proxies.clear
|
814
806
|
end
|
815
807
|
|
816
|
-
def
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
808
|
+
def data_bind(property, model_binding)
|
809
|
+
element_binding_parameters = [self, property]
|
810
|
+
element_binding = DataBinding::ElementBinding.new(*element_binding_parameters)
|
811
|
+
element_binding.call(model_binding.evaluate_property)
|
812
|
+
#TODO make this options observer dependent and all similar observers in element specific data binding handlers
|
813
|
+
element_binding.observe(model_binding)
|
814
|
+
unless model_binding.binding_options[:read_only]
|
815
|
+
# TODO add guards against nil cases for hash below
|
816
|
+
listener_keyword = data_binding_element_keyword_to_property_listener_map[keyword][property]
|
817
|
+
data_binding_read_listener = lambda do |event|
|
818
|
+
model_binding.call(send(property))
|
819
|
+
end
|
820
|
+
handle_observation_request(listener_keyword, data_binding_read_listener)
|
821
821
|
end
|
822
822
|
end
|
823
823
|
|
@@ -827,6 +827,7 @@ module Glimmer
|
|
827
827
|
end
|
828
828
|
|
829
829
|
def respond_to_missing?(method_name, include_private = false)
|
830
|
+
# TODO consider doing more correct checking of availability of properties/methods using native `` ticks
|
830
831
|
property_name = property_name_for(method_name)
|
831
832
|
super(method_name, include_private) ||
|
832
833
|
(dom_element && dom_element.length > 0 && Native.call(dom_element, '0').respond_to?(method_name.to_s.camelcase, include_private)) ||
|
@@ -836,6 +837,7 @@ module Glimmer
|
|
836
837
|
end
|
837
838
|
|
838
839
|
def method_missing(method_name, *args, &block)
|
840
|
+
# TODO consider doing more correct checking of availability of properties/methods using native `` ticks
|
839
841
|
property_name = property_name_for(method_name)
|
840
842
|
if method_name.to_s.start_with?('on_')
|
841
843
|
handle_observation_request(method_name, block)
|
@@ -931,144 +933,17 @@ module Glimmer
|
|
931
933
|
}
|
932
934
|
end
|
933
935
|
|
934
|
-
def
|
935
|
-
@
|
936
|
-
|
937
|
-
|
938
|
-
# on_focus_gained { |focus_event|
|
939
|
-
# observer.call(true)
|
940
|
-
# }
|
941
|
-
# on_focus_lost { |focus_event|
|
942
|
-
# observer.call(false)
|
943
|
-
# }
|
944
|
-
# end,
|
945
|
-
# },
|
946
|
-
MenuItemProxy => {
|
947
|
-
:selection => proc do |observer|
|
948
|
-
on_widget_selected { |selection_event|
|
949
|
-
# TODO look into validity of this and perhaps move toggle logic to MenuItemProxy
|
950
|
-
if check?
|
951
|
-
observer.call(!selection)
|
952
|
-
else
|
953
|
-
observer.call(selection)
|
954
|
-
end
|
955
|
-
}
|
956
|
-
end
|
957
|
-
},
|
958
|
-
ScaleProxy => {
|
959
|
-
:selection => proc do |observer|
|
960
|
-
on_widget_selected { |selection_event|
|
961
|
-
observer.call(selection)
|
962
|
-
}
|
963
|
-
end
|
964
|
-
},
|
965
|
-
SliderProxy => {
|
966
|
-
:selection => proc do |observer|
|
967
|
-
on_widget_selected { |selection_event|
|
968
|
-
observer.call(selection)
|
969
|
-
}
|
970
|
-
end
|
936
|
+
def data_binding_element_keyword_to_property_listener_map
|
937
|
+
@data_binding_element_keyword_to_property_listener_map ||= {
|
938
|
+
'input' => {
|
939
|
+
'value' => 'oninput',
|
971
940
|
},
|
972
|
-
|
973
|
-
|
974
|
-
on_widget_selected { |selection_event|
|
975
|
-
observer.call(selection)
|
976
|
-
}
|
977
|
-
end
|
941
|
+
'select' => {
|
942
|
+
'value' => 'onchange',
|
978
943
|
},
|
979
|
-
|
980
|
-
|
981
|
-
on_modify_text { |modify_event|
|
982
|
-
observer.call(text)
|
983
|
-
}
|
984
|
-
end,
|
985
|
-
# :caret_position => proc do |observer|
|
986
|
-
# on_event_keydown { |event|
|
987
|
-
# observer.call(getCaretPosition)
|
988
|
-
# }
|
989
|
-
# on_event_keyup { |event|
|
990
|
-
# observer.call(getCaretPosition)
|
991
|
-
# }
|
992
|
-
# on_event_mousedown { |event|
|
993
|
-
# observer.call(getCaretPosition)
|
994
|
-
# }
|
995
|
-
# on_event_mouseup { |event|
|
996
|
-
# observer.call(getCaretPosition)
|
997
|
-
# }
|
998
|
-
# end,
|
999
|
-
# :selection => proc do |observer|
|
1000
|
-
# on_event_keydown { |event|
|
1001
|
-
# observer.call(getSelection)
|
1002
|
-
# }
|
1003
|
-
# on_event_keyup { |event|
|
1004
|
-
# observer.call(getSelection)
|
1005
|
-
# }
|
1006
|
-
# on_event_mousedown { |event|
|
1007
|
-
# observer.call(getSelection)
|
1008
|
-
# }
|
1009
|
-
# on_event_mouseup { |event|
|
1010
|
-
# observer.call(getSelection)
|
1011
|
-
# }
|
1012
|
-
# end,
|
1013
|
-
# :selection_count => proc do |observer|
|
1014
|
-
# on_event_keydown { |event|
|
1015
|
-
# observer.call(getSelectionCount)
|
1016
|
-
# }
|
1017
|
-
# on_event_keyup { |event|
|
1018
|
-
# observer.call(getSelectionCount)
|
1019
|
-
# }
|
1020
|
-
# on_event_mousedown { |event|
|
1021
|
-
# observer.call(getSelectionCount)
|
1022
|
-
# }
|
1023
|
-
# on_event_mouseup { |event|
|
1024
|
-
# observer.call(getSelectionCount)
|
1025
|
-
# }
|
1026
|
-
# end,
|
1027
|
-
# :top_index => proc do |observer|
|
1028
|
-
# @last_top_index = getTopIndex
|
1029
|
-
# on_paint_control { |event|
|
1030
|
-
# if getTopIndex != @last_top_index
|
1031
|
-
# @last_top_index = getTopIndex
|
1032
|
-
# observer.call(@last_top_index)
|
1033
|
-
# end
|
1034
|
-
# }
|
1035
|
-
# end,
|
1036
|
-
},
|
1037
|
-
# Java::OrgEclipseSwtCustom::StyledText => {
|
1038
|
-
# :text => proc do |observer|
|
1039
|
-
# on_modify_text { |modify_event|
|
1040
|
-
# observer.call(getText)
|
1041
|
-
# }
|
1042
|
-
# end,
|
1043
|
-
# },
|
1044
|
-
DateTimeProxy => {
|
1045
|
-
:date_time => proc do |observer|
|
1046
|
-
on_widget_selected { |selection_event|
|
1047
|
-
observer.call(date_time)
|
1048
|
-
}
|
1049
|
-
end
|
944
|
+
'textarea' => {
|
945
|
+
'value' => 'oninput',
|
1050
946
|
},
|
1051
|
-
RadioProxy => { #radio?
|
1052
|
-
:selection => proc do |observer|
|
1053
|
-
on_widget_selected { |selection_event|
|
1054
|
-
observer.call(selection)
|
1055
|
-
}
|
1056
|
-
end
|
1057
|
-
},
|
1058
|
-
TableProxy => {
|
1059
|
-
:selection => proc do |observer|
|
1060
|
-
on_widget_selected { |selection_event|
|
1061
|
-
observer.call(selection_event.table_item.get_data) # TODO ensure selection doesn't conflict with editing
|
1062
|
-
}
|
1063
|
-
end,
|
1064
|
-
},
|
1065
|
-
# Java::OrgEclipseSwtWidgets::MenuItem => {
|
1066
|
-
# :selection => proc do |observer|
|
1067
|
-
# on_widget_selected { |selection_event|
|
1068
|
-
# observer.call(getSelection)
|
1069
|
-
# }
|
1070
|
-
# end
|
1071
|
-
# },
|
1072
947
|
}
|
1073
948
|
end
|
1074
949
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2023 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
module Glimmer
|
23
|
+
module Web
|
24
|
+
class EventProxy
|
25
|
+
attr_reader :js_event, :listener
|
26
|
+
|
27
|
+
def initialize(js_event:, listener:)
|
28
|
+
@js_event = js_event
|
29
|
+
@listener = listener
|
30
|
+
end
|
31
|
+
|
32
|
+
def element = listener.element
|
33
|
+
def event_name = listener.event_name
|
34
|
+
def event_attribute = listener.event_attribute
|
35
|
+
|
36
|
+
def original_event
|
37
|
+
Native(`#{js_event.to_n}.originalEvent`)
|
38
|
+
end
|
39
|
+
|
40
|
+
def respond_to_missing?(method_name, include_private = false)
|
41
|
+
property_name = method_name.to_s.camelcase
|
42
|
+
super(method_name, include_private) ||
|
43
|
+
js_event.respond_to?(method_name, include_private) ||
|
44
|
+
`#{property_name} in #{original_event.to_n}`
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(method_name, *args, &block)
|
48
|
+
property_name = method_name.to_s.camelcase
|
49
|
+
if js_event.respond_to?(method_name, true)
|
50
|
+
js_event.send(method_name, *args, &block)
|
51
|
+
elsif `#{property_name} in #{original_event.to_n}`
|
52
|
+
original_event[property_name]
|
53
|
+
else
|
54
|
+
super(method_name, *args, &block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|