glimmer-dsl-opal 0.0.1 → 0.0.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.md +95 -20
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal.rb +10 -8
- data/lib/glimmer/data_binding/element_binding.rb +35 -0
- data/lib/glimmer/data_binding/observable_element.rb +14 -0
- data/lib/glimmer/dsl/opal/bind_expression.rb +37 -0
- data/lib/glimmer/dsl/opal/button_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/combo_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +40 -0
- data/lib/glimmer/dsl/opal/composite_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/data_binding_expression.rb +34 -0
- data/lib/glimmer/dsl/opal/dsl.rb +9 -0
- data/lib/glimmer/dsl/opal/label_expression.rb +2 -2
- data/lib/glimmer/dsl/opal/property_expression.rb +1 -1
- data/lib/glimmer/dsl/opal/shell_expression.rb +2 -2
- data/lib/glimmer/dsl/opal/widget_listener_expression.rb +18 -0
- data/lib/glimmer/opal/div_proxy.rb +14 -0
- data/lib/glimmer/opal/{shell.rb → document_proxy.rb} +19 -5
- data/lib/glimmer/opal/element_proxy.rb +52 -0
- data/lib/glimmer/opal/event_listener_proxy.rb +18 -0
- data/lib/glimmer/opal/input_proxy.rb +30 -0
- data/lib/glimmer/opal/label_proxy.rb +24 -0
- data/lib/glimmer/opal/select_proxy.rb +58 -0
- data/lib/samples/elaborate/contact_manager.rb +95 -0
- data/lib/samples/elaborate/contact_manager/contact.rb +11 -0
- data/lib/samples/elaborate/contact_manager/contact_manager_presenter.rb +36 -0
- data/lib/samples/elaborate/contact_manager/contact_repository.rb +244 -0
- data/lib/samples/elaborate/launch +6 -0
- data/lib/samples/elaborate/login.rb +88 -0
- data/lib/samples/elaborate/tic_tac_toe.rb +53 -0
- data/lib/samples/elaborate/tic_tac_toe/board.rb +124 -0
- data/lib/samples/elaborate/tic_tac_toe/cell.rb +27 -0
- data/lib/samples/hello/hello_browser.rb +8 -0
- data/lib/samples/hello/hello_combo.rb +34 -0
- data/lib/samples/hello/hello_computed.rb +69 -0
- data/lib/samples/hello/hello_computed/contact.rb +21 -0
- data/lib/samples/hello/hello_list_multi_selection.rb +44 -0
- data/lib/samples/hello/hello_list_single_selection.rb +34 -0
- data/lib/samples/hello/hello_tab.rb +24 -0
- data/lib/samples/hello/hello_world.rb +8 -0
- data/lib/samples/hello/launch +10 -0
- data/lib/samples/launch +4 -0
- metadata +39 -6
- data/lib/glimmer/opal/label.rb +0 -31
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'glimmer/dsl/static_expression'
|
2
2
|
require 'glimmer/dsl/parent_expression'
|
3
|
-
require 'glimmer/opal/
|
3
|
+
require 'glimmer/opal/label_proxy'
|
4
4
|
|
5
5
|
module Glimmer
|
6
6
|
module DSL
|
@@ -9,7 +9,7 @@ module Glimmer
|
|
9
9
|
include ParentExpression
|
10
10
|
|
11
11
|
def interpret(parent, keyword, *args, &block)
|
12
|
-
Glimmer::Opal::
|
12
|
+
Glimmer::Opal::LabelProxy.new(parent, args)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'glimmer/dsl/static_expression'
|
2
2
|
require 'glimmer/dsl/top_level_expression'
|
3
3
|
require 'glimmer/dsl/parent_expression'
|
4
|
-
require 'glimmer/opal/
|
4
|
+
require 'glimmer/opal/document_proxy'
|
5
5
|
|
6
6
|
module Glimmer
|
7
7
|
module DSL
|
@@ -11,7 +11,7 @@ module Glimmer
|
|
11
11
|
include ParentExpression
|
12
12
|
|
13
13
|
def interpret(parent, keyword, *args, &block)
|
14
|
-
Glimmer::Opal::
|
14
|
+
Glimmer::Opal::DocumentProxy.new(args)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module DSL
|
5
|
+
module Opal
|
6
|
+
class WidgetListenerExpression < Expression
|
7
|
+
|
8
|
+
def can_interpret?(parent, keyword, *args, &block)
|
9
|
+
keyword.start_with?('on_') and args.empty? and block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
def interpret(parent, keyword, *args, &block)
|
13
|
+
parent.handle_observation_request(keyword, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,10 +1,15 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
1
3
|
module Glimmer
|
2
4
|
module Opal
|
3
|
-
class
|
5
|
+
class DocumentProxy < ElementProxy
|
6
|
+
# TODO consider renaming to ShellProxy to match SWT API
|
7
|
+
|
4
8
|
def initialize(args)
|
5
9
|
@args = args
|
6
10
|
@children = []
|
7
11
|
$document.ready do
|
12
|
+
$document.head.replace(head_dom)
|
8
13
|
$document.body.replace(dom)
|
9
14
|
end
|
10
15
|
end
|
@@ -17,10 +22,19 @@ module Glimmer
|
|
17
22
|
$document.title = value
|
18
23
|
end
|
19
24
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
def head_dom
|
26
|
+
@head_dom ||= DOM {
|
27
|
+
head {
|
28
|
+
<<~CSS
|
29
|
+
<style>
|
30
|
+
div.grid_layout > * {
|
31
|
+
display: block;
|
32
|
+
margin-bottom: 10px;
|
33
|
+
}
|
34
|
+
</style>
|
35
|
+
CSS
|
36
|
+
}
|
37
|
+
}
|
24
38
|
end
|
25
39
|
|
26
40
|
def dom
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Opal
|
3
|
+
class ElementProxy
|
4
|
+
attr_reader :parent, :args
|
5
|
+
|
6
|
+
def initialize(parent, args)
|
7
|
+
@parent = parent
|
8
|
+
@args = args
|
9
|
+
@children = []
|
10
|
+
@parent.add_child(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_child(child)
|
14
|
+
return if @children.include?(child)
|
15
|
+
@children << child
|
16
|
+
dom << child.dom
|
17
|
+
end
|
18
|
+
|
19
|
+
def redraw
|
20
|
+
old_dom = @dom
|
21
|
+
@dom = nil
|
22
|
+
old_dom.replace dom
|
23
|
+
end
|
24
|
+
|
25
|
+
# Subclasses must override with their own mappings
|
26
|
+
def observation_request_to_event_mapping
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
self.class.name.split('::').last.underscore.sub(/_proxy$/, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
def id
|
35
|
+
"#{name}-#{hash}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Subclasses can override with their own selector
|
39
|
+
def selector
|
40
|
+
"#{name}##{id}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle_observation_request(keyword, &event_listener)
|
44
|
+
event = observation_request_to_event_mapping[keyword][:event]
|
45
|
+
event_handler = observation_request_to_event_mapping[keyword][:event_handler]
|
46
|
+
event_listener = event_handler&.call(event_listener) || event_listener
|
47
|
+
delegate = $document.on(event, selector, &event_listener)
|
48
|
+
EventListenerProxy.new(element_proxy: self, event: event, selector: selector, delegate: delegate)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Opal
|
3
|
+
class EventListenerProxy
|
4
|
+
attr_reader :element_proxy, :event, :selector, :delegate
|
5
|
+
|
6
|
+
def initialize(element_proxy:, event:, selector:, delegate:)
|
7
|
+
@element_proxy = element_proxy
|
8
|
+
@event = event
|
9
|
+
@selector = selector
|
10
|
+
@delegate = delegate
|
11
|
+
end
|
12
|
+
|
13
|
+
def unregister
|
14
|
+
$document.off(@delegate)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class InputProxy < ElementProxy
|
6
|
+
attr_reader :text
|
7
|
+
|
8
|
+
def text=(value)
|
9
|
+
@text = value
|
10
|
+
redraw
|
11
|
+
end
|
12
|
+
|
13
|
+
def observation_request_to_event_mapping
|
14
|
+
{
|
15
|
+
'on_widget_selected' => {
|
16
|
+
event: 'click'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def dom
|
22
|
+
input_text = @text
|
23
|
+
input_id = id
|
24
|
+
@dom ||= DOM {
|
25
|
+
input id: input_id, type: 'button', value: input_text
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class LabelProxy < ElementProxy
|
6
|
+
attr_reader :text
|
7
|
+
|
8
|
+
def text=(value)
|
9
|
+
@text = value
|
10
|
+
redraw
|
11
|
+
end
|
12
|
+
|
13
|
+
def dom
|
14
|
+
label_text = @text
|
15
|
+
label_id = id
|
16
|
+
@dom ||= DOM {
|
17
|
+
label(id: label_id) {
|
18
|
+
label_text
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'glimmer/data_binding/observable_element'
|
2
|
+
require 'glimmer/opal/event_listener_proxy'
|
3
|
+
require 'glimmer/opal/element_proxy'
|
4
|
+
|
5
|
+
module Glimmer
|
6
|
+
module Opal
|
7
|
+
class SelectProxy < ElementProxy
|
8
|
+
include Glimmer::DataBinding::ObservableElement
|
9
|
+
attr_reader :text, :items
|
10
|
+
|
11
|
+
def initialize(parent, args)
|
12
|
+
super(parent, args)
|
13
|
+
@items = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def text=(value)
|
17
|
+
@text = value
|
18
|
+
redraw
|
19
|
+
end
|
20
|
+
|
21
|
+
def items=(the_items)
|
22
|
+
@items = the_items
|
23
|
+
redraw
|
24
|
+
end
|
25
|
+
|
26
|
+
def observation_request_to_event_mapping
|
27
|
+
{
|
28
|
+
'on_widget_selected' => {
|
29
|
+
event: 'change',
|
30
|
+
event_handler: -> (event_listener) {
|
31
|
+
-> (event) {
|
32
|
+
@text = event.target.value
|
33
|
+
event_listener.call(event)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def dom
|
41
|
+
select_text = @text
|
42
|
+
items = @items
|
43
|
+
select_id = id
|
44
|
+
@dom ||= DOM {
|
45
|
+
select(id: select_id) {
|
46
|
+
items.to_a.each do |item|
|
47
|
+
option_hash = {value: item}
|
48
|
+
option_hash[:selected] = 'selected' if select_text == item
|
49
|
+
option(option_hash) {
|
50
|
+
item
|
51
|
+
}
|
52
|
+
end
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require_relative "contact_manager/contact_manager_presenter"
|
2
|
+
|
3
|
+
class ContactManager
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@contact_manager_presenter = ContactManagerPresenter.new
|
8
|
+
@contact_manager_presenter.list
|
9
|
+
end
|
10
|
+
|
11
|
+
def launch
|
12
|
+
shell {
|
13
|
+
text "Contact Manager"
|
14
|
+
composite {
|
15
|
+
composite {
|
16
|
+
grid_layout 2, false
|
17
|
+
label {text "First &Name: "}
|
18
|
+
text {
|
19
|
+
text bind(@contact_manager_presenter, :first_name)
|
20
|
+
on_key_pressed {|key_event|
|
21
|
+
@contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
|
22
|
+
}
|
23
|
+
}
|
24
|
+
label {text "&Last Name: "}
|
25
|
+
text {
|
26
|
+
text bind(@contact_manager_presenter, :last_name)
|
27
|
+
on_key_pressed {|key_event|
|
28
|
+
@contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
|
29
|
+
}
|
30
|
+
}
|
31
|
+
label {text "&Email: "}
|
32
|
+
text {
|
33
|
+
text bind(@contact_manager_presenter, :email)
|
34
|
+
on_key_pressed {|key_event|
|
35
|
+
@contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
|
36
|
+
}
|
37
|
+
}
|
38
|
+
composite {
|
39
|
+
grid_layout 2, false
|
40
|
+
button {
|
41
|
+
text "&Find"
|
42
|
+
on_widget_selected {
|
43
|
+
@contact_manager_presenter.find
|
44
|
+
}
|
45
|
+
}
|
46
|
+
button {
|
47
|
+
text "&List All"
|
48
|
+
on_widget_selected {
|
49
|
+
@contact_manager_presenter.list
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
table(:multi) { |table_proxy|
|
56
|
+
layout_data {
|
57
|
+
horizontal_alignment :fill
|
58
|
+
vertical_alignment :fill
|
59
|
+
grab_excess_horizontal_space true
|
60
|
+
grab_excess_vertical_space true
|
61
|
+
height_hint 200
|
62
|
+
}
|
63
|
+
table_column {
|
64
|
+
text "First Name"
|
65
|
+
width 80
|
66
|
+
on_widget_selected {
|
67
|
+
@contact_manager_presenter.toggle_sort(:first_name)
|
68
|
+
}
|
69
|
+
}
|
70
|
+
table_column {
|
71
|
+
text "Last Name"
|
72
|
+
width 80
|
73
|
+
on_widget_selected {
|
74
|
+
@contact_manager_presenter.toggle_sort(:last_name)
|
75
|
+
}
|
76
|
+
}
|
77
|
+
table_column {
|
78
|
+
text "Email"
|
79
|
+
width 200
|
80
|
+
on_widget_selected {
|
81
|
+
@contact_manager_presenter.toggle_sort(:email)
|
82
|
+
}
|
83
|
+
}
|
84
|
+
items bind(@contact_manager_presenter, :results),
|
85
|
+
column_properties(:first_name, :last_name, :email)
|
86
|
+
on_mouse_down { |event|
|
87
|
+
table_proxy.edit_table_item(event.table_item, event.column_index)
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}.open
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
ContactManager.new.launch
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative "contact_repository"
|
2
|
+
|
3
|
+
class ContactManager
|
4
|
+
class ContactManagerPresenter
|
5
|
+
attr_accessor :results
|
6
|
+
@@contact_attributes = [:first_name, :last_name, :email]
|
7
|
+
@@contact_attributes.each {|attribute_name| attr_accessor attribute_name}
|
8
|
+
|
9
|
+
def initialize(contact_repository = nil)
|
10
|
+
@contact_repository = contact_repository || ContactRepository.new
|
11
|
+
@results = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def list
|
15
|
+
self.results = @contact_repository.find({})
|
16
|
+
end
|
17
|
+
|
18
|
+
def find
|
19
|
+
filter_map = {}
|
20
|
+
@@contact_attributes.each do |attribute_name|
|
21
|
+
filter_map[attribute_name] = self.send(attribute_name) if self.send(attribute_name)
|
22
|
+
end
|
23
|
+
self.results = @contact_repository.find(filter_map)
|
24
|
+
@sort_attribute_name = nil
|
25
|
+
@sort_direction_ascending = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def toggle_sort(attribute_name)
|
29
|
+
@sort_attribute_name = attribute_name
|
30
|
+
@sort_direction_ascending = !@sort_direction_ascending
|
31
|
+
sorted_results = self.results.sort_by {|contact| contact.send(attribute_name).downcase}
|
32
|
+
sorted_results = sorted_results.reverse unless @sort_direction_ascending
|
33
|
+
self.results = sorted_results
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|