glimmer 0.10.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.4
1
+ 1.0.0
@@ -1,7 +1,24 @@
1
- # Glimmer - a JRuby DSL that enables easy and efficient authoring of user
2
- # interfaces using the robust platform-independent Eclipse SWT library. Glimmer
3
- # comes with built-in data-binding support to greatly facilitate synchronizing
4
- # UI with domain models.
1
+ # Copyright (c) 2007-2020 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
+
5
22
  require 'logger'
6
23
  require 'set'
7
24
  require 'array_include_methods'
@@ -62,6 +79,5 @@ module Glimmer
62
79
  end
63
80
 
64
81
  require 'glimmer/error'
65
- require 'glimmer/excluded_keyword_error'
66
82
  require 'glimmer/invalid_keyword_error'
67
83
  require 'glimmer/dsl/engine'
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 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
+
1
22
  module Glimmer
2
23
  module Config
3
24
  class << self
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 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
+
1
22
  require 'glimmer/data_binding/observable'
2
23
  require 'glimmer/data_binding/observer'
3
24
 
@@ -7,7 +28,7 @@ module Glimmer
7
28
  include Observable
8
29
  include Observer
9
30
 
10
- attr_reader :binding_options
31
+ attr_reader :binding_options, :property_name_expression
11
32
 
12
33
  def initialize(base_model, property_name_expression, binding_options = nil)
13
34
  @base_model = base_model
@@ -60,19 +81,10 @@ module Glimmer
60
81
  end
61
82
 
62
83
  def apply_converter(converter, value)
63
- if converter.nil?
64
- value
65
- elsif converter.is_a?(String) || converter.is_a?(Symbol)
66
- if value.respond_to?(converter)
67
- value.send(converter)
68
- else
69
- raise Glimmer::Error, "Unsupported bind converter: #{converter.inspect}"
70
- end
71
- elsif converter.respond_to?(:call, value)
72
- converter.call(value)
73
- else
74
- raise Glimmer::Error, "Unsupported bind converter: #{converter.inspect}"
75
- end
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}"
76
88
  end
77
89
 
78
90
  # All nested property names
@@ -99,10 +111,6 @@ module Glimmer
99
111
  property_name_expression.match(/[.\[]/)
100
112
  end
101
113
 
102
- def property_name_expression
103
- @property_name_expression
104
- end
105
-
106
114
  def computed?
107
115
  !computed_by.empty?
108
116
  end
@@ -179,17 +187,19 @@ module Glimmer
179
187
  model, property_name = zip
180
188
  nested_property_observer = nested_property_observers[property_name]
181
189
  previous_index = i - 1
182
- parent_model = previous_index.negative? ? self : nested_models[previous_index]
183
- parent_property_name = previous_index.negative? ? nil : nested_property_names[previous_index]
184
- parent_observer = previous_index.negative? ? observer : nested_property_observers[parent_property_name]
190
+ if previous_index.negative?
191
+ parent_model = self
192
+ parent_property_name = nil
193
+ parent_observer = observer
194
+ else
195
+ parent_model = nested_models[previous_index]
196
+ parent_property_name = nested_property_names[previous_index]
197
+ parent_observer = nested_property_observers[parent_property_name]
198
+ end
185
199
  parent_property_name = nil if parent_property_name.to_s.start_with?('[')
186
200
  unless model.nil?
187
- if property_indexed?(property_name)
188
- # TODO figure out a way to deal with this more uniformly
189
- observer_registration = nested_property_observer.observe(model)
190
- else
191
- observer_registration = nested_property_observer.observe(model, property_name)
192
- end
201
+ # TODO figure out a way to deal with this more uniformly
202
+ observer_registration = property_indexed?(property_name) ? nested_property_observer.observe(model) : nested_property_observer.observe(model, property_name)
193
203
  parent_registration = parent_observer.registration_for(parent_model, parent_property_name)
194
204
  parent_observer.add_dependent(parent_registration => observer_registration)
195
205
  end
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 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
+
1
22
  require 'glimmer/error'
2
23
 
3
24
  module Glimmer
@@ -1,13 +1,32 @@
1
- require 'set'
2
- require 'array_include_methods'
1
+ # Copyright (c) 2007-2020 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.
3
21
 
22
+ require 'set'
4
23
  require 'glimmer/data_binding/observable'
24
+ require 'array_include_methods'
5
25
 
6
26
  using ArrayIncludeMethods
7
27
 
8
28
  module Glimmer
9
29
  module DataBinding
10
- # TODO prefix utility methods with double-underscore
11
30
  module ObservableArray
12
31
  include Observable
13
32
 
@@ -37,11 +56,7 @@ module Glimmer
37
56
  if !element_properties.empty?
38
57
  old_element_properties = element_properties_for(observer)
39
58
  observer_element_properties[observer] = element_properties_for(observer) - Set.new(element_properties)
40
- each do |element|
41
- element_properties.each do |property|
42
- observer.unobserve(element, property)
43
- end
44
- end
59
+ each { |element| element_properties.each { |property| observer.unobserve(element, property) } }
45
60
  end
46
61
  if element_properties_for(observer).empty?
47
62
  property_observer_list.delete(observer)
@@ -169,9 +184,7 @@ module Glimmer
169
184
  remove_element_observers(old_value)
170
185
  end
171
186
  super(&block).tap do
172
- each do |element|
173
- add_element_observers(element)
174
- end
187
+ each { |element| add_element_observers(element) }
175
188
  notify_observers
176
189
  end
177
190
  else
@@ -181,9 +194,7 @@ module Glimmer
181
194
  alias map! collect!
182
195
 
183
196
  def compact!
184
- super.tap do
185
- notify_observers
186
- end
197
+ super.tap { notify_observers }
187
198
  end
188
199
 
189
200
  def flatten!(level=nil)
@@ -192,17 +203,13 @@ module Glimmer
192
203
  remove_element_observers(old_value)
193
204
  end
194
205
  (level.nil? ? super() : super(level)).tap do
195
- each do |element|
196
- add_element_observers(element)
197
- end
206
+ each { |element| add_element_observers(element) }
198
207
  notify_observers
199
208
  end
200
209
  end
201
210
 
202
211
  def rotate!(count=1)
203
- super(count).tap do
204
- notify_observers
205
- end
212
+ super(count).tap { notify_observers }
206
213
  end
207
214
 
208
215
  def select!(&block)
@@ -221,9 +228,7 @@ module Glimmer
221
228
  end
222
229
 
223
230
  def shuffle!(hash = nil)
224
- (hash.nil? ? super() : super(random: hash[:random])).tap do
225
- notify_observers
226
- end
231
+ (hash.nil? ? super() : super(random: hash[:random])).tap { notify_observers }
227
232
  end
228
233
 
229
234
  def slice!(arg1, arg2=nil)
@@ -238,15 +243,11 @@ module Glimmer
238
243
  end
239
244
 
240
245
  def sort!(&block)
241
- (block.nil? ? super() : super(&block)).tap do
242
- notify_observers
243
- end
246
+ (block.nil? ? super() : super(&block)).tap { notify_observers }
244
247
  end
245
248
 
246
249
  def sort_by!(&block)
247
- (block.nil? ? super() : super(&block)).tap do
248
- notify_observers
249
- end
250
+ (block.nil? ? super() : super(&block)).tap { notify_observers }
250
251
  end
251
252
 
252
253
  def uniq!(&block)
@@ -255,15 +256,15 @@ module Glimmer
255
256
  remove_element_observers(old_value)
256
257
  end
257
258
  (block.nil? ? super() : super(&block)).tap do
258
- each do |element|
259
- add_element_observers(element)
260
- end
259
+ each { |element| add_element_observers(element) }
261
260
  notify_observers
262
261
  end
263
262
  end
264
263
 
265
264
  def reject!(&block)
266
- if block_given?
265
+ if block.nil?
266
+ super
267
+ else
267
268
  old_array = Array.new(self)
268
269
  super(&block).tap do
269
270
  (old_array - self).each do |old_value|
@@ -272,17 +273,12 @@ module Glimmer
272
273
  end
273
274
  notify_observers
274
275
  end
275
- else
276
- super
277
276
  end
278
277
  end
279
278
 
280
279
  def unregister_dependent_observers(old_value)
281
- # TODO look into optimizing this
282
280
  return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
283
- property_observer_list.each do |observer|
284
- observer.unregister_dependents_with_observable(observer.registration_for(self), old_value)
285
- end
281
+ property_observer_list.each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self), old_value) }
286
282
  end
287
283
  end
288
284
  end
@@ -1,9 +1,29 @@
1
+ # Copyright (c) 2007-2020 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
+
1
22
  require 'glimmer/data_binding/observable'
2
23
  require 'glimmer/data_binding/observer'
3
24
 
4
25
  module Glimmer
5
26
  module DataBinding
6
- # TODO prefix utility methods with double-underscore
7
27
  module ObservableModel
8
28
  include Observable
9
29
 
@@ -17,6 +37,17 @@ module Glimmer
17
37
  @observable_model.notify_observers(@property_name)
18
38
  end
19
39
  end
40
+
41
+ PROPERTY_WRITER_FACTORY = lambda do |property_name|
42
+ property_writer_name = "#{property_name}="
43
+ lambda do |value|
44
+ old_value = self.send(property_name)
45
+ unregister_dependent_observers(property_name, old_value)
46
+ self.send("__original_#{property_writer_name}", value)
47
+ notify_observers(property_name)
48
+ ensure_array_object_observer(property_name, value, old_value)
49
+ end
50
+ end
20
51
 
21
52
  def add_observer(observer, property_name)
22
53
  return observer if has_observer?(observer, property_name)
@@ -47,11 +78,8 @@ module Glimmer
47
78
  end
48
79
 
49
80
  def notify_observers(property_name)
50
- property_observer_list(property_name).to_a.each do |observer|
51
- observer.call(send(property_name))
52
- end
81
+ property_observer_list(property_name).to_a.each { |observer| observer.call(send(property_name)) }
53
82
  end
54
- #TODO upon updating values, make sure dependent observers are cleared (not added as dependents here)
55
83
 
56
84
  def add_property_writer_observers(property_name)
57
85
  property_writer_name = "#{property_name}="
@@ -60,27 +88,22 @@ module Glimmer
60
88
  begin
61
89
  singleton_method("__original_#{property_writer_name}")
62
90
  rescue
63
- old_method = self.class.instance_method(property_writer_name) rescue self.method(property_writer_name)
64
- define_singleton_method("__original_#{property_writer_name}", old_method)
65
- define_singleton_method(property_writer_name) do |value|
66
- old_value = self.send(property_name)
67
- unregister_dependent_observers(property_name, old_value)
68
- self.send("__original_#{property_writer_name}", value)
69
- notify_observers(property_name)
70
- ensure_array_object_observer(property_name, value, old_value)
71
- end
91
+ define_singleton_method("__original_#{property_writer_name}", property_writer_method(property_writer_name))
92
+ define_singleton_method(property_writer_name, &PROPERTY_WRITER_FACTORY.call(property_name))
72
93
  end
73
94
  rescue => e
74
95
  #ignore writing if no property writer exists
75
96
  Glimmer::Config.logger.debug {"No need to observe property writer: #{property_writer_name}\n#{e.message}\n#{e.backtrace.join("\n")}"}
76
97
  end
98
+
99
+ def property_writer_method(property_writer_name)
100
+ self.class.instance_method(property_writer_name) rescue self.method(property_writer_name)
101
+ end
77
102
 
78
103
  def unregister_dependent_observers(property_name, old_value)
79
104
  # TODO look into optimizing this
80
105
  return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
81
- property_observer_list(property_name).each do |observer|
82
- observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value)
83
- end
106
+ property_observer_list(property_name).each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value) }
84
107
  end
85
108
 
86
109
  def ensure_array_object_observer(property_name, object, old_object = nil)
@@ -95,10 +118,8 @@ module Glimmer
95
118
  end
96
119
 
97
120
  def array_object_observer_for(property_name)
98
- @array_object_observers ||= {}
99
- unless @array_object_observers.has_key?(property_name)
100
- @array_object_observers[property_name] = ObservableModel::Notifier.new(self, property_name)
101
- end
121
+ @array_object_observers ||= {}
122
+ @array_object_observers[property_name] = ObservableModel::Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name)
102
123
  @array_object_observers[property_name]
103
124
  end
104
125
  end