glimmer 1.0.10 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +428 -357
- data/VERSION +1 -1
- data/glimmer.gemspec +8 -6
- data/lib/glimmer.rb +5 -1
- data/lib/glimmer/config.rb +2 -2
- data/lib/glimmer/data_binding/model_binding.rb +43 -25
- data/lib/glimmer/data_binding/observable_array.rb +1 -0
- data/lib/glimmer/data_binding/observable_model.rb +1 -0
- data/lib/glimmer/data_binding/observer.rb +4 -0
- data/lib/glimmer/dsl/engine.rb +6 -4
- data/lib/glimmer/dsl/expression.rb +1 -1
- data/lib/glimmer/dsl/parent_expression.rb +1 -1
- data/lib/glimmer/ext/module.rb +11 -0
- metadata +12 -9
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.2.0
|
data/glimmer.gemspec
CHANGED
@@ -2,19 +2,20 @@
|
|
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 1.0
|
5
|
+
# stub: glimmer 1.2.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer".freeze
|
9
|
-
s.version = "1.0
|
9
|
+
s.version = "1.2.0"
|
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 = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-
|
15
|
-
s.description = "Glimmer is a Ruby DSL Framework consisting of a DSL Engine and an Observable/Observer/Data-Binding Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer DSL for CSS.".freeze
|
14
|
+
s.date = "2021-03-03"
|
15
|
+
s.description = "Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of a DSL Engine and an Observable/Observer/Data-Binding Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer DSL for CSS.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
|
+
"CHANGELOG.md",
|
18
19
|
"LICENSE.txt",
|
19
20
|
"README.md"
|
20
21
|
]
|
@@ -40,12 +41,13 @@ Gem::Specification.new do |s|
|
|
40
41
|
"lib/glimmer/dsl/static_expression.rb",
|
41
42
|
"lib/glimmer/dsl/top_level_expression.rb",
|
42
43
|
"lib/glimmer/error.rb",
|
44
|
+
"lib/glimmer/ext/module.rb",
|
43
45
|
"lib/glimmer/invalid_keyword_error.rb"
|
44
46
|
]
|
45
47
|
s.homepage = "http://github.com/AndyObtiva/glimmer".freeze
|
46
48
|
s.licenses = ["MIT".freeze]
|
47
|
-
s.rubygems_version = "3.
|
48
|
-
s.summary = "Glimmer
|
49
|
+
s.rubygems_version = "3.2.3".freeze
|
50
|
+
s.summary = "Glimmer - DSL Engine for Ruby GUI and More".freeze
|
49
51
|
|
50
52
|
if s.respond_to? :specification_version then
|
51
53
|
s.specification_version = 4
|
data/lib/glimmer.rb
CHANGED
@@ -35,6 +35,7 @@ end
|
|
35
35
|
$LOAD_PATH.unshift(File.expand_path('..', __FILE__))
|
36
36
|
|
37
37
|
require 'glimmer/config'
|
38
|
+
require 'glimmer/ext/module'
|
38
39
|
|
39
40
|
# Glimmer provides a JRuby Desktop UI DSL + Data-Binding functionality
|
40
41
|
#
|
@@ -65,7 +66,9 @@ module Glimmer
|
|
65
66
|
|
66
67
|
def method_missing(method_symbol, *args, &block)
|
67
68
|
# This if statement speeds up Glimmer in girb or whenever directly including on main object
|
68
|
-
is_excluded = Config.excluded_keyword_checkers.
|
69
|
+
is_excluded = Config.excluded_keyword_checkers.any? do |checker|
|
70
|
+
instance_exec(method_symbol, *args, &checker)
|
71
|
+
end
|
69
72
|
if is_excluded
|
70
73
|
Glimmer::Config.logger.debug "Glimmer excluded keyword: #{method_symbol}" if Glimmer::Config.log_excluded_keywords?
|
71
74
|
super(method_symbol, *args, &block)
|
@@ -78,6 +81,7 @@ module Glimmer
|
|
78
81
|
Glimmer.loop_reset!
|
79
82
|
end
|
80
83
|
Glimmer.loop_last_data = new_loop_data
|
84
|
+
Glimmer::Config.logger.info {">"*80}
|
81
85
|
Glimmer::Config.logger.info {"Interpreting keyword: #{method_symbol}"}
|
82
86
|
Glimmer::DSL::Engine.interpret(method_symbol, *args, &block)
|
83
87
|
end
|
data/lib/glimmer/config.rb
CHANGED
@@ -56,10 +56,10 @@ module Glimmer
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def reset_logger!
|
59
|
-
self.logger = Logger.new(
|
59
|
+
self.logger = Logger.new($stdout).tap do |logger|
|
60
60
|
logger.level = Logger::ERROR
|
61
61
|
begin
|
62
|
-
logger.level = ENV['GLIMMER_LOGGER_LEVEL']
|
62
|
+
logger.level = ENV['GLIMMER_LOGGER_LEVEL']&.strip&.downcase
|
63
63
|
rescue => e
|
64
64
|
puts e.message
|
65
65
|
end
|
@@ -49,9 +49,7 @@ module Glimmer
|
|
49
49
|
def nested_models
|
50
50
|
@nested_models = [base_model]
|
51
51
|
model_property_names.reduce(base_model) do |reduced_model, nested_model_property_name|
|
52
|
-
if reduced_model.nil?
|
53
|
-
nil
|
54
|
-
else
|
52
|
+
if !reduced_model.nil?
|
55
53
|
invoke_property_reader(reduced_model, nested_model_property_name).tap do |new_reduced_model|
|
56
54
|
@nested_models << new_reduced_model
|
57
55
|
end
|
@@ -72,21 +70,6 @@ module Glimmer
|
|
72
70
|
nested_property? ? nested_property_name : property_name_expression
|
73
71
|
end
|
74
72
|
|
75
|
-
def convert_on_read(value)
|
76
|
-
apply_converter(@binding_options[:on_read], value)
|
77
|
-
end
|
78
|
-
|
79
|
-
def convert_on_write(value)
|
80
|
-
apply_converter(@binding_options[:on_write], value)
|
81
|
-
end
|
82
|
-
|
83
|
-
def apply_converter(converter, value)
|
84
|
-
return value if converter.nil?
|
85
|
-
return value.send(converter) if (converter.is_a?(String) || converter.is_a?(Symbol)) && value.respond_to?(converter)
|
86
|
-
return converter.call(value) if converter.respond_to?(:call, value)
|
87
|
-
raise Glimmer::Error, "Unsupported bind converter: #{converter.inspect}"
|
88
|
-
end
|
89
|
-
|
90
73
|
# All nested property names
|
91
74
|
# e.g. property name expression "address.state" gives ['address', 'state']
|
92
75
|
# If there are any indexed property names, this returns indexes as properties.
|
@@ -127,7 +110,10 @@ module Glimmer
|
|
127
110
|
property_name => Observer.proc do |new_value|
|
128
111
|
# Ensure reattaching observers when a higher level nested property is updated (e.g. person.address changes reattaches person.address.street observer)
|
129
112
|
add_observer(observer)
|
130
|
-
|
113
|
+
converted_value = evaluate_property
|
114
|
+
observer.call(converted_value).tap do
|
115
|
+
apply_processor(@binding_options[:after_read], converted_value)
|
116
|
+
end
|
131
117
|
end
|
132
118
|
)
|
133
119
|
end
|
@@ -142,7 +128,10 @@ module Glimmer
|
|
142
128
|
add_nested_observers(observer)
|
143
129
|
else
|
144
130
|
model_binding_observer = Observer.proc do |new_value|
|
145
|
-
|
131
|
+
converted_value = evaluate_property
|
132
|
+
observer.call(converted_value).tap do
|
133
|
+
apply_processor(@binding_options[:after_read], converted_value)
|
134
|
+
end
|
146
135
|
end
|
147
136
|
observer_registration = model_binding_observer.observe(model, property_name)
|
148
137
|
my_registration = observer.registration_for(self)
|
@@ -167,7 +156,10 @@ module Glimmer
|
|
167
156
|
@computed_observer_collection ||= Concurrent::Hash.new
|
168
157
|
unless @computed_observer_collection.has_key?(observer)
|
169
158
|
@computed_observer_collection[observer] = Observer.proc do |new_value|
|
170
|
-
|
159
|
+
converted_value = evaluate_property
|
160
|
+
observer.call(converted_value).tap do
|
161
|
+
apply_processor(@binding_options[:after_read], converted_value)
|
162
|
+
end
|
171
163
|
end
|
172
164
|
end
|
173
165
|
@computed_observer_collection[observer]
|
@@ -215,9 +207,10 @@ module Glimmer
|
|
215
207
|
def evaluate_property
|
216
208
|
value = nil
|
217
209
|
value = invoke_property_reader(model, property_name) unless model.nil?
|
210
|
+
apply_processor(@binding_options[:before_read], value)
|
218
211
|
convert_on_read(value)
|
219
212
|
end
|
220
|
-
|
213
|
+
|
221
214
|
def evaluate_options_property
|
222
215
|
model.send(options_property_name) unless model.nil?
|
223
216
|
end
|
@@ -230,6 +223,29 @@ module Glimmer
|
|
230
223
|
property_expression.to_s.start_with?('[')
|
231
224
|
end
|
232
225
|
|
226
|
+
private
|
227
|
+
|
228
|
+
def convert_on_read(value)
|
229
|
+
apply_processor(@binding_options[:on_read], value)
|
230
|
+
end
|
231
|
+
|
232
|
+
def convert_on_write(value)
|
233
|
+
apply_processor(@binding_options[:on_write], value)
|
234
|
+
end
|
235
|
+
|
236
|
+
def apply_processor(processor, value)
|
237
|
+
return value if processor.nil?
|
238
|
+
return value.send(processor) if (processor.is_a?(String) || processor.is_a?(Symbol)) && value.respond_to?(processor)
|
239
|
+
return invoke_proc_with_exact_parameters(processor, value) if processor.respond_to?(:call)
|
240
|
+
raise Glimmer::Error, "Unsupported bind processor: #{processor.inspect}"
|
241
|
+
end
|
242
|
+
|
243
|
+
def invoke_proc_with_exact_parameters(proc_object, *args)
|
244
|
+
return if proc_object.nil?
|
245
|
+
args = args[0...proc_object.parameters.size]
|
246
|
+
proc_object.call(*args)
|
247
|
+
end
|
248
|
+
|
233
249
|
def invoke_property_reader(object, property_expression)
|
234
250
|
if property_indexed?(property_expression)
|
235
251
|
property_method = '[]'
|
@@ -243,15 +259,17 @@ module Glimmer
|
|
243
259
|
|
244
260
|
def invoke_property_writer(object, property_expression, value)
|
245
261
|
raise "Cannot invoke `#{property_expression}` because ModelBinding#binding_options[:read_only]=true" if @binding_options[:read_only]
|
246
|
-
|
262
|
+
apply_processor(@binding_options[:before_write], value)
|
263
|
+
converted_value = convert_on_write(value)
|
247
264
|
if property_indexed?(property_expression)
|
248
265
|
property_method = '[]='
|
249
266
|
property_argument = property_expression[1...-2]
|
250
267
|
property_argument = property_argument.to_i if property_argument.match(/\d+/)
|
251
|
-
object.send(property_method, property_argument,
|
268
|
+
object.send(property_method, property_argument, converted_value)
|
252
269
|
else
|
253
|
-
object.send(property_expression,
|
270
|
+
object.send(property_expression, converted_value)
|
254
271
|
end
|
272
|
+
apply_processor(@binding_options[:after_write], converted_value)
|
255
273
|
end
|
256
274
|
end
|
257
275
|
end
|
@@ -289,6 +289,7 @@ module Glimmer
|
|
289
289
|
return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
|
290
290
|
property_observer_list.each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self), old_value) }
|
291
291
|
end
|
292
|
+
alias deregister_dependent_observers unregister_dependent_observers
|
292
293
|
end
|
293
294
|
end
|
294
295
|
end
|
@@ -124,6 +124,7 @@ module Glimmer
|
|
124
124
|
return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
|
125
125
|
property_observer_list(property_name).each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value) }
|
126
126
|
end
|
127
|
+
alias deregister_dependent_observers unregister_dependent_observers
|
127
128
|
|
128
129
|
def ensure_array_object_observer(property_name, object, old_object = nil)
|
129
130
|
return unless object&.is_a?(Array)
|
@@ -110,6 +110,7 @@ module Glimmer
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
alias unobserve unregister
|
113
|
+
alias deregister unregister
|
113
114
|
|
114
115
|
def unregister_dependents_with_observable(registration, dependent_observable)
|
115
116
|
thedependents = dependents_for(registration).select do |thedependent|
|
@@ -117,12 +118,15 @@ module Glimmer
|
|
117
118
|
end
|
118
119
|
thedependents.each(&:unregister)
|
119
120
|
end
|
121
|
+
alias unobserve_dependents_with_observable unregister_dependents_with_observable
|
122
|
+
alias deregister_dependents_with_observable unregister_dependents_with_observable
|
120
123
|
|
121
124
|
# cleans up all registrations in observables
|
122
125
|
def unregister_all_observables
|
123
126
|
registrations.each(&:unregister)
|
124
127
|
end
|
125
128
|
alias unobserve_all_observables unregister_all_observables
|
129
|
+
alias deregister_all_observables unregister_all_observables
|
126
130
|
|
127
131
|
# add dependent observer to unregister when unregistering observer
|
128
132
|
def add_dependent(parent_to_dependent_hash)
|
data/lib/glimmer/dsl/engine.rb
CHANGED
@@ -37,7 +37,7 @@ module Glimmer
|
|
37
37
|
STATIC_EXPRESSION_METHOD_FACTORY = lambda do |keyword|
|
38
38
|
lambda do |*args, &block|
|
39
39
|
if Glimmer::DSL::Engine.no_dsls?
|
40
|
-
|
40
|
+
Glimmer::Config.logger.error {Glimmer::DSL::Engine::MESSAGE_NO_DSLS}
|
41
41
|
else
|
42
42
|
retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
43
43
|
# TODO consider replacing Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls with Glimmer::DSL::Engine.enabled_static_expression_dsls(keyword)
|
@@ -55,6 +55,7 @@ module Glimmer
|
|
55
55
|
else
|
56
56
|
raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
|
57
57
|
Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
|
58
|
+
Glimmer::Config.logger.info {"Assuming DSL: #{Glimmer::DSL::Engine.dsl_stack.last}"}
|
58
59
|
static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
59
60
|
static_expression_can_interpret = nil
|
60
61
|
if static_expression.nil? || !(static_expression_can_interpret = static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block))
|
@@ -169,13 +170,14 @@ module Glimmer
|
|
169
170
|
dynamic_expression_dsl = (dynamic_expression_chains_of_responsibility.keys - disabled_dsls).first if dsl.nil?
|
170
171
|
# TODO consider pushing this code into interpret_expresion to provide hooks that work around it regardless of static vs dynamic
|
171
172
|
dsl_stack.push(dynamic_expression_dsl || dsl)
|
173
|
+
Glimmer::Config.logger.info {"Assuming DSL: #{dsl_stack.last}"}
|
172
174
|
expression = dynamic_expression_chains_of_responsibility[dsl].handle(parent, keyword, *args, &block)
|
173
175
|
interpret_expression(expression, keyword, *args, &block)
|
174
176
|
end
|
175
177
|
|
176
178
|
def interpret_expression(expression, keyword, *args, &block)
|
177
179
|
expression.interpret(parent, keyword, *args, &block).tap do |ui_object|
|
178
|
-
add_content(ui_object, expression, &block)
|
180
|
+
add_content(ui_object, expression, keyword, *args, &block)
|
179
181
|
dsl_stack.pop
|
180
182
|
end
|
181
183
|
end
|
@@ -185,12 +187,12 @@ module Glimmer
|
|
185
187
|
# This allows evaluating parent UI object properties and children
|
186
188
|
#
|
187
189
|
# For example, a shell widget would get properties set and children added
|
188
|
-
def add_content(parent, expression, &block)
|
190
|
+
def add_content(parent, expression, keyword, *args, &block)
|
189
191
|
if block_given? && expression.is_a?(ParentExpression)
|
190
192
|
dsl_stack.push(expression.class.dsl)
|
191
193
|
parent_stack.push(parent)
|
192
194
|
begin
|
193
|
-
expression.add_content(parent, &block)
|
195
|
+
expression.add_content(parent, keyword, *args, &block)
|
194
196
|
ensure
|
195
197
|
parent_stack.pop
|
196
198
|
dsl_stack.pop
|
@@ -50,7 +50,7 @@ module Glimmer
|
|
50
50
|
# Adds block content to specified parent UI object (Optional)
|
51
51
|
#
|
52
52
|
# Only expressions that receive a content block should implement
|
53
|
-
def add_content(parent, &block)
|
53
|
+
def add_content(parent, keyword, *args, &block)
|
54
54
|
# No Op by default
|
55
55
|
end
|
56
56
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Module
|
2
|
+
alias append_features_without_glimmer append_features
|
3
|
+
def append_features(mod)
|
4
|
+
if self == Glimmer && mod == Object
|
5
|
+
Glimmer::Config.logger.debug { 'Appending Glimmer to Singleton Class of main object (not appending to Object everywhere to avoid method pollution)' }
|
6
|
+
TOPLEVEL_BINDING.receiver.singleton_class.include(self)
|
7
|
+
else
|
8
|
+
append_features_without_glimmer(mod)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: array_include_methods
|
@@ -228,15 +228,17 @@ dependencies:
|
|
228
228
|
- - ">="
|
229
229
|
- !ruby/object:Gem::Version
|
230
230
|
version: '0'
|
231
|
-
description: Glimmer is a Ruby DSL Framework
|
232
|
-
Library. Used in the Glimmer
|
233
|
-
|
234
|
-
|
235
|
-
XML (& HTML), and the Glimmer
|
231
|
+
description: Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of
|
232
|
+
a DSL Engine and an Observable/Observer/Data-Binding Library. Used in the Glimmer
|
233
|
+
DSL for SWT (JRuby Desktop Development GUI Framework), the Glimmer DSL for Tk (Ruby
|
234
|
+
Desktop Development GUI Library), the Glimmer DSL for Opal (Pure Ruby Web GUI and
|
235
|
+
Auto-Webifier of Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer
|
236
|
+
DSL for CSS.
|
236
237
|
email: andy.am@gmail.com
|
237
238
|
executables: []
|
238
239
|
extensions: []
|
239
240
|
extra_rdoc_files:
|
241
|
+
- CHANGELOG.md
|
240
242
|
- LICENSE.txt
|
241
243
|
- README.md
|
242
244
|
files:
|
@@ -261,6 +263,7 @@ files:
|
|
261
263
|
- lib/glimmer/dsl/static_expression.rb
|
262
264
|
- lib/glimmer/dsl/top_level_expression.rb
|
263
265
|
- lib/glimmer/error.rb
|
266
|
+
- lib/glimmer/ext/module.rb
|
264
267
|
- lib/glimmer/invalid_keyword_error.rb
|
265
268
|
homepage: http://github.com/AndyObtiva/glimmer
|
266
269
|
licenses:
|
@@ -281,8 +284,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
281
284
|
- !ruby/object:Gem::Version
|
282
285
|
version: '0'
|
283
286
|
requirements: []
|
284
|
-
rubygems_version: 3.
|
287
|
+
rubygems_version: 3.2.3
|
285
288
|
signing_key:
|
286
289
|
specification_version: 4
|
287
|
-
summary: Glimmer
|
290
|
+
summary: Glimmer - DSL Engine for Ruby GUI and More
|
288
291
|
test_files: []
|