glimmer 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|