glimmer 0.2.1 → 0.2.2
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/README.markdown +6 -3
- data/lib/command_handlers/bind_command_handler.rb +0 -8
- data/lib/command_handlers/models/block_observer.rb +1 -1
- data/lib/command_handlers/models/model_binding.rb +28 -7
- data/lib/command_handlers/models/observable_array.rb +24 -13
- data/lib/glimmer_application.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4916b9c2b6c19c4afbdb4a49cc586d7c1a12358a94ee5f425b78520227cf3c8f
|
4
|
+
data.tar.gz: 7ce6d54b43cfecb43fe395ab6a7b39d4db928ad674f9ce26b0635c457a611f91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c16290f6cd39289717bd5f2446d2d42a00c1b08298f5d1ddea658e8efaa738cfdfa2e79512fae0ba3120dcb9d07fef946967c3467f28916b91f9171fc147c5cb
|
7
|
+
data.tar.gz: f51597bec5ef7193ea66f089243b29fc90c0bf406abcb7aa2dc6e1c66f31aefd210c840682c47dbfd1732ebabda0331e95c3f1efd07072df93926fe3493a84ab
|
data/README.markdown
CHANGED
@@ -66,14 +66,14 @@ Please follow these instructions to make the `glimmer` command available on your
|
|
66
66
|
|
67
67
|
Run this command to install directly:
|
68
68
|
```
|
69
|
-
jgem install glimmer -v 0.2.
|
69
|
+
jgem install glimmer -v 0.2.2
|
70
70
|
```
|
71
71
|
|
72
72
|
### Option 2: Bundler
|
73
73
|
|
74
74
|
Add the following to `Gemfile`:
|
75
75
|
```
|
76
|
-
gem 'glimmer', '~> 0.2.
|
76
|
+
gem 'glimmer', '~> 0.2.2'
|
77
77
|
```
|
78
78
|
|
79
79
|
And, then run:
|
@@ -131,6 +131,7 @@ Data-binding is done with `bind` command following widget property to bind and t
|
|
131
131
|
Data-binding examples:
|
132
132
|
- `text bind(contact, :first_name)`
|
133
133
|
- `text bind(contact, 'address.street')`
|
134
|
+
- `text bind(contact, 'addresses[1].street')`
|
134
135
|
- `text bind(contact, :name, computed_by: [:first_name, :last_name])`
|
135
136
|
|
136
137
|
The first example binds the text property of a widget like `label` to the first name of a contact model.
|
@@ -138,7 +139,9 @@ The first example binds the text property of a widget like `label` to the first
|
|
138
139
|
The second example binds the text property of a widget like `label` to the nested street of
|
139
140
|
the address of a contact. This is called nested property data binding.
|
140
141
|
|
141
|
-
The third example
|
142
|
+
The third example binds the text property of a widget like `label` to the nested indexed address street of a contact. This is called nested indexed property data binding.
|
143
|
+
|
144
|
+
The fourth example demonstrates computed value data binding whereby the value of `name` depends on changes to both `first_name` and `last_name`
|
142
145
|
|
143
146
|
You may learn more about Glimmer's syntax by reading the Eclipse Zone Tutorial mentioned in resources and opening up the samples under the `samples` folder.
|
144
147
|
|
@@ -44,14 +44,6 @@ class BindCommandHandler
|
|
44
44
|
binding_options = args[2] if args[2].is_a?(Hash)
|
45
45
|
binding_options = args[3] if args[3].is_a?(Hash)
|
46
46
|
ModelBinding.new(args[0], args[1].to_s, property_type, binding_options)
|
47
|
-
#TODO replace ModelObserver with something else. It's inaccurate
|
48
|
-
# it doesn't observe the model, it updates it, observing the widget
|
49
|
-
# yet also contains information about observing the model, like the property
|
50
|
-
# to observe. That's the real object spit out here. Must name is something else.
|
51
|
-
# Maybe call ModelBinding and spin off Observer as ModelPropertyUpdateCommand
|
52
|
-
# similarly create a WidgetPropertyUpdateCommand (execute not update method)
|
53
|
-
# Have an observer be a general thin skeleton with an update method instead.
|
54
|
-
# In the future, switch observer to a simple block.
|
55
47
|
end
|
56
48
|
|
57
49
|
end
|
@@ -23,8 +23,19 @@ class ModelBinding
|
|
23
23
|
def nested_models
|
24
24
|
@nested_models = [base_model]
|
25
25
|
model_property_names.reduce(base_model) do |reduced_model, nested_model_property_name|
|
26
|
-
reduced_model.
|
26
|
+
if reduced_model.nil?
|
27
|
+
nil
|
28
|
+
else
|
29
|
+
if nested_model_property_name.start_with?('[')
|
30
|
+
property_method = '[]'
|
31
|
+
property_argument = nested_model_property_name[1...-1]
|
32
|
+
property_argument = property_argument.to_i if property_argument.match(/\d+/)
|
33
|
+
new_reduced_model = reduced_model.send(property_method, property_argument)
|
34
|
+
else
|
35
|
+
new_reduced_model = reduced_model.send(nested_model_property_name)
|
36
|
+
end
|
27
37
|
@nested_models << new_reduced_model
|
38
|
+
new_reduced_model
|
28
39
|
end
|
29
40
|
end
|
30
41
|
@nested_models
|
@@ -39,9 +50,11 @@ class ModelBinding
|
|
39
50
|
nested_property? ? nested_property_name : property_name_expression
|
40
51
|
end
|
41
52
|
# All nested property names
|
42
|
-
# e.g. property name expression "address.state" gives [
|
53
|
+
# e.g. property name expression "address.state" gives ['address', 'state']
|
54
|
+
# If there are any indexed property names, this returns indexes as properties.
|
55
|
+
# e.g. property name expression "addresses[1].state" gives ['addresses', '[1]', 'state']
|
43
56
|
def nested_property_names
|
44
|
-
property_name_expression.split(".")
|
57
|
+
@nested_property_names ||= property_name_expression.split(".").map {|pne| pne.match(/([^\[]+)(\[[^\]]+\])?/).to_a.drop(1)}.flatten.compact
|
45
58
|
end
|
46
59
|
# Final nested property name
|
47
60
|
# e.g. property name expression "address.state" gives :state
|
@@ -78,8 +91,15 @@ class ModelBinding
|
|
78
91
|
if nested_property?
|
79
92
|
nested_property_observers = nested_property_observers_for(observer)
|
80
93
|
nested_models.zip(nested_property_names).each do |model, property_name|
|
81
|
-
|
82
|
-
|
94
|
+
unless model.nil?
|
95
|
+
if property_name.start_with?('[')
|
96
|
+
model.extend ObservableArray unless model.is_a?(ObservableArray)
|
97
|
+
model.add_array_observer(nested_property_observers[property_name]) unless model.has_array_observer?(nested_property_observers[property_name])
|
98
|
+
else
|
99
|
+
model.extend ObservableModel unless model.is_a?(ObservableModel)
|
100
|
+
model.add_observer(property_name, nested_property_observers[property_name]) unless model.has_observer?(property_name, nested_property_observers[property_name])
|
101
|
+
end
|
102
|
+
end
|
83
103
|
end
|
84
104
|
else
|
85
105
|
model.extend ObservableModel unless model.is_a?(ObservableModel)
|
@@ -87,14 +107,15 @@ class ModelBinding
|
|
87
107
|
end
|
88
108
|
end
|
89
109
|
def update(value)
|
110
|
+
return if model.nil?
|
90
111
|
converted_value = @@property_type_converters[@property_type].call(value)
|
91
112
|
model.send(property_name + "=", converted_value) unless evaluate_property == converted_value
|
92
113
|
end
|
93
114
|
def evaluate_property
|
94
|
-
model.send(property_name)
|
115
|
+
model.send(property_name) unless model.nil?
|
95
116
|
end
|
96
117
|
def evaluate_options_property
|
97
|
-
model.send(property_name + "_options")
|
118
|
+
model.send(property_name + "_options") unless model.nil?
|
98
119
|
end
|
99
120
|
def options_property_name
|
100
121
|
self.property_name + "_options"
|
@@ -11,6 +11,14 @@ module ObservableArray
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
def add_array_observer(observer)
|
15
|
+
property_observer_list << observer
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_array_observer?(observer)
|
19
|
+
property_observer_list.include?(observer)
|
20
|
+
end
|
21
|
+
|
14
22
|
def property_observer_list
|
15
23
|
@property_observer_list = Set.new unless @property_observer_list
|
16
24
|
@property_observer_list
|
@@ -21,31 +29,34 @@ module ObservableArray
|
|
21
29
|
end
|
22
30
|
|
23
31
|
def self.extend_object(array)
|
24
|
-
array.instance_eval("alias
|
32
|
+
array.instance_eval("alias __original_add__ <<")
|
25
33
|
array.instance_eval <<-end_eval, __FILE__, __LINE__
|
26
34
|
def <<(value)
|
27
|
-
self.
|
35
|
+
self.__original_add__(value)
|
28
36
|
notify_observers
|
29
37
|
end
|
30
38
|
end_eval
|
31
39
|
|
32
|
-
|
33
|
-
|
40
|
+
array.instance_eval("alias __original_set_value__ []=")
|
41
|
+
array.instance_eval <<-end_eval, __FILE__, __LINE__
|
42
|
+
def []=(index, value)
|
43
|
+
self.__original_set_value__(index, value)
|
44
|
+
notify_observers
|
45
|
+
end
|
46
|
+
end_eval
|
47
|
+
|
48
|
+
notify_observers_on_invokation(array, "delete")
|
49
|
+
notify_observers_on_invokation(array, "delete_at")
|
34
50
|
notify_observers_on_invokation(array, "clear")
|
35
51
|
|
36
52
|
super
|
37
53
|
end
|
38
54
|
|
39
|
-
def self.notify_observers_on_invokation(model, method
|
40
|
-
model.instance_eval "alias
|
41
|
-
arguments = ""
|
42
|
-
for index in 1..argument_count
|
43
|
-
arguments += "argument" + index.to_s + ","
|
44
|
-
end
|
45
|
-
arguments = arguments[0..-2]
|
55
|
+
def self.notify_observers_on_invokation(model, method)
|
56
|
+
model.instance_eval "alias __original_#{method}__ #{method}\n"
|
46
57
|
model.instance_eval <<-end_eval, __FILE__, __LINE__
|
47
|
-
def #{method}(
|
48
|
-
self.
|
58
|
+
def #{method}(*args, &block)
|
59
|
+
self.__original_#{method}__(*args, &block)
|
49
60
|
notify_observers
|
50
61
|
end
|
51
62
|
end_eval
|
data/lib/glimmer_application.rb
CHANGED
@@ -26,11 +26,11 @@ This runs the Glimmer application hello_world.rb
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def jruby_command_options
|
29
|
-
"#{jruby_os_specific_options} -J-classpath \"#{swt_jar_file}\"
|
29
|
+
"#{jruby_os_specific_options} -J-classpath \"#{swt_jar_file}\""
|
30
30
|
end
|
31
31
|
|
32
32
|
def launch(application)
|
33
|
-
system "jruby #{jruby_command_options} -S #{application}"
|
33
|
+
system "jruby #{jruby_command_options} -r glimmer -S #{application}"
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|