glimmer-dsl-opal 0.0.2 → 0.0.7
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 +704 -40
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal.rb +3 -2
- data/lib/glimmer/data_binding/element_binding.rb +1 -1
- data/lib/glimmer/data_binding/ext/observable_model.rb +40 -0
- data/lib/glimmer/data_binding/list_selection_binding.rb +51 -0
- data/lib/glimmer/dsl/opal/async_exec_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/browser_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/button_expression.rb +1 -0
- data/lib/glimmer/dsl/opal/dsl.rb +15 -1
- data/lib/glimmer/dsl/opal/grid_layout_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/layout_data_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/list_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/list_selection_data_binding_expression.rb +42 -0
- data/lib/glimmer/dsl/opal/message_box_expression.rb +20 -0
- data/lib/glimmer/dsl/opal/observe_expression.rb +32 -0
- data/lib/glimmer/dsl/opal/property_expression.rb +6 -2
- data/lib/glimmer/dsl/opal/tab_folder_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/tab_item_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/text_expression.rb +22 -0
- data/lib/glimmer/opal/display_proxy.rb +23 -0
- data/lib/glimmer/opal/div_proxy.rb +9 -1
- data/lib/glimmer/opal/document_proxy.rb +131 -5
- data/lib/glimmer/opal/element_proxy.rb +246 -11
- data/lib/glimmer/opal/grid_layout_proxy.rb +54 -0
- data/lib/glimmer/opal/iframe_proxy.rb +23 -0
- data/lib/glimmer/opal/input_proxy.rb +16 -1
- data/lib/glimmer/opal/label_proxy.rb +2 -1
- data/lib/glimmer/opal/layout_data_proxy.rb +31 -0
- data/lib/glimmer/opal/list_proxy.rb +80 -0
- data/lib/glimmer/opal/modal.rb +94 -0
- data/lib/glimmer/opal/point.rb +5 -0
- data/lib/glimmer/opal/property_owner.rb +22 -0
- data/lib/glimmer/opal/select_proxy.rb +2 -1
- data/lib/glimmer/opal/tab_folder.rb +46 -0
- data/lib/glimmer/opal/tab_item.rb +98 -0
- data/lib/samples/elaborate/login.rb +0 -1
- data/lib/samples/elaborate/tic_tac_toe.rb +5 -5
- data/lib/samples/hello/hello_tab.rb +2 -2
- metadata +25 -2
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'glimmer/opal/property_owner'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class GridLayoutProxy
|
6
|
+
include PropertyOwner
|
7
|
+
attr_reader :parent, :args, :num_columns, :make_columns_equal_width, :horizontal_spacing, :vertical_spacing
|
8
|
+
|
9
|
+
def initialize(parent, args)
|
10
|
+
@parent = parent
|
11
|
+
@args = args
|
12
|
+
@parent.add_css_class('grid-layout')
|
13
|
+
@horizontal_spacing = 10
|
14
|
+
@vertical_spacing = 10
|
15
|
+
@num_columns = @args.first || 1
|
16
|
+
reapply
|
17
|
+
end
|
18
|
+
|
19
|
+
def num_columns=(columns)
|
20
|
+
@num_columns = columns
|
21
|
+
# @parent.add_css_class("num-columns-#{@num_columns}")
|
22
|
+
reapply
|
23
|
+
end
|
24
|
+
|
25
|
+
def make_columns_equal_width=(equal_width)
|
26
|
+
@make_columns_equal_width = equal_width
|
27
|
+
# @parent.add_css_class('make_columns_equal_width') if @make_columns_equal_width
|
28
|
+
reapply
|
29
|
+
end
|
30
|
+
|
31
|
+
def horizontal_spacing=(spacing)
|
32
|
+
@horizontal_spacing = spacing
|
33
|
+
# @parent.add_css_class("horizontal-spacing-#{@horizontal_spacing}")
|
34
|
+
reapply
|
35
|
+
end
|
36
|
+
|
37
|
+
def vertical_spacing=(spacing)
|
38
|
+
@vertical_spacing = spacing
|
39
|
+
# @parent.add_css_class("vertical-spacing-#{@vertical_spacing}")
|
40
|
+
reapply
|
41
|
+
end
|
42
|
+
|
43
|
+
def reapply
|
44
|
+
@parent.css = <<~CSS
|
45
|
+
display: grid;
|
46
|
+
grid-template-columns: #{'auto ' * @num_columns.to_i};
|
47
|
+
grid-row-gap: #{@vertical_spacing}px;
|
48
|
+
grid-column-gap: #{@horizontal_spacing}px;
|
49
|
+
justify-content: start;
|
50
|
+
CSS
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class IframeProxy < ElementProxy
|
6
|
+
attr_reader :url
|
7
|
+
|
8
|
+
def url=(value)
|
9
|
+
@url = value
|
10
|
+
redraw
|
11
|
+
end
|
12
|
+
|
13
|
+
def dom
|
14
|
+
iframe_id = id
|
15
|
+
iframe_url = url
|
16
|
+
@dom ||= DOM {
|
17
|
+
iframe(src: iframe_url, frameBorder: 0) {
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -14,6 +14,17 @@ module Glimmer
|
|
14
14
|
{
|
15
15
|
'on_widget_selected' => {
|
16
16
|
event: 'click'
|
17
|
+
},
|
18
|
+
'on_modify_text' => {
|
19
|
+
event: 'keyup',
|
20
|
+
event_handler: -> (event_listener) {
|
21
|
+
-> (event) {
|
22
|
+
if args.last[:type] == 'text'
|
23
|
+
@text = event.target.value
|
24
|
+
event_listener.call(event)
|
25
|
+
end
|
26
|
+
}
|
27
|
+
}
|
17
28
|
}
|
18
29
|
}
|
19
30
|
end
|
@@ -21,8 +32,12 @@ module Glimmer
|
|
21
32
|
def dom
|
22
33
|
input_text = @text
|
23
34
|
input_id = id
|
35
|
+
input_style = css
|
36
|
+
input_args = @args.last
|
37
|
+
input_disabled = @enabled ? {} : {'disabled': 'disabled'}
|
38
|
+
input_args = input_args.merge(type: 'password') if has_style?(:password)
|
24
39
|
@dom ||= DOM {
|
25
|
-
input id: input_id,
|
40
|
+
input input_args.merge(id: input_id, style: input_style, value: input_text, style: 'min-width: 27px;').merge(input_disabled)
|
26
41
|
}
|
27
42
|
end
|
28
43
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'glimmer/opal/property_owner'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class LayoutDataProxy
|
6
|
+
include PropertyOwner
|
7
|
+
attr_reader :parent, :args, :horizontal_alignment, :grab_excess_horizontal_space
|
8
|
+
|
9
|
+
def initialize(parent, args)
|
10
|
+
@parent = parent
|
11
|
+
@args = args
|
12
|
+
reapply
|
13
|
+
end
|
14
|
+
|
15
|
+
def horizontal_alignment=(horizontal_alignment)
|
16
|
+
@horizontal_alignment = horizontal_alignment
|
17
|
+
reapply
|
18
|
+
end
|
19
|
+
|
20
|
+
def grab_excess_horizontal_space=(grab_excess_horizontal_space)
|
21
|
+
@grab_excess_horizontal_space = grab_excess_horizontal_space
|
22
|
+
reapply
|
23
|
+
end
|
24
|
+
|
25
|
+
def reapply
|
26
|
+
# @parent.css = <<~CSS
|
27
|
+
# CSS
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class ListProxy < ElementProxy
|
6
|
+
ITEM_EMPTY = '_____'
|
7
|
+
attr_reader :items, :selection
|
8
|
+
|
9
|
+
def initialize(parent, args)
|
10
|
+
super(parent, args)
|
11
|
+
@selection = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def items=(items)
|
15
|
+
@items = items.map {|item| item.strip == '' ? ITEM_EMPTY : item}
|
16
|
+
redraw
|
17
|
+
end
|
18
|
+
|
19
|
+
def index_of(item)
|
20
|
+
@items.index(item)
|
21
|
+
end
|
22
|
+
|
23
|
+
# used for multi-selection taking an array
|
24
|
+
def selection=(selection)
|
25
|
+
@selection = selection
|
26
|
+
redraw
|
27
|
+
end
|
28
|
+
|
29
|
+
# used for single selection taking an index
|
30
|
+
def select(index, meta = false)
|
31
|
+
selected_item = @items[index]
|
32
|
+
if @selection.include?(selected_item)
|
33
|
+
@selection.delete(selected_item) if meta
|
34
|
+
else
|
35
|
+
@selection = [] if !meta || (!has_style?(:multi) && @selection.to_a.size >= 1)
|
36
|
+
@selection << selected_item
|
37
|
+
end
|
38
|
+
self.selection = @selection
|
39
|
+
end
|
40
|
+
|
41
|
+
def observation_request_to_event_mapping
|
42
|
+
{
|
43
|
+
'on_widget_selected' => {
|
44
|
+
event: 'click',
|
45
|
+
event_handler: -> (event_listener) {
|
46
|
+
-> (event) {
|
47
|
+
selected_item = event.target.text
|
48
|
+
select(index_of(selected_item), event.meta?)
|
49
|
+
event_listener.call(event)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def name
|
57
|
+
'ul'
|
58
|
+
end
|
59
|
+
|
60
|
+
def dom
|
61
|
+
list_items = @items
|
62
|
+
list_id = id
|
63
|
+
list_style = css
|
64
|
+
list_selection = selection
|
65
|
+
@dom ||= DOM {
|
66
|
+
ul(id: list_id, style: list_style) {
|
67
|
+
list_items.to_a.each_with_index do |item, index|
|
68
|
+
li_class = ''
|
69
|
+
li_class += ' selected-list-item' if list_selection.include?(item)
|
70
|
+
li_class += ' empty-list-item' if item == ITEM_EMPTY
|
71
|
+
li(class: li_class) {
|
72
|
+
item
|
73
|
+
}
|
74
|
+
end
|
75
|
+
}
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class Modal < ElementProxy
|
6
|
+
attr_reader :text, :message
|
7
|
+
|
8
|
+
def initialize(parent, args)
|
9
|
+
i = 0
|
10
|
+
@parent = parent
|
11
|
+
@args = args
|
12
|
+
@children = Set.new
|
13
|
+
@css_classes = Set.new(['modal'])
|
14
|
+
@css = ''
|
15
|
+
@enabled = true
|
16
|
+
content do
|
17
|
+
on_widget_selected {
|
18
|
+
hide
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def text=(txt)
|
24
|
+
@text = txt
|
25
|
+
redraw if @dom
|
26
|
+
end
|
27
|
+
|
28
|
+
def message=(msg)
|
29
|
+
@message = msg
|
30
|
+
redraw if @dom
|
31
|
+
end
|
32
|
+
|
33
|
+
def document
|
34
|
+
element = self
|
35
|
+
begin
|
36
|
+
element = element.parent
|
37
|
+
end while(element.parent)
|
38
|
+
element
|
39
|
+
end
|
40
|
+
|
41
|
+
def open
|
42
|
+
document.add_child(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def hide
|
46
|
+
dom.remove
|
47
|
+
end
|
48
|
+
|
49
|
+
def content(&block)
|
50
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::MessageBoxExpression.new, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def name
|
54
|
+
'div'
|
55
|
+
end
|
56
|
+
|
57
|
+
def selector
|
58
|
+
super + ' .close'
|
59
|
+
end
|
60
|
+
|
61
|
+
def observation_request_to_event_mapping
|
62
|
+
{
|
63
|
+
'on_widget_selected' => {
|
64
|
+
event: 'click'
|
65
|
+
},
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def dom
|
70
|
+
modal_id = id
|
71
|
+
modal_style = css
|
72
|
+
modal_text = text
|
73
|
+
modal_message = message
|
74
|
+
modal_css_classes = css_classes
|
75
|
+
modal_class = modal_css_classes.to_a.join(' ')
|
76
|
+
@dom ||= DOM {
|
77
|
+
div(id: modal_id, style: modal_style, class: modal_class) {
|
78
|
+
div(class: 'modal-content') {
|
79
|
+
header.text {
|
80
|
+
modal_text
|
81
|
+
}
|
82
|
+
p.message {
|
83
|
+
modal_message
|
84
|
+
}
|
85
|
+
input(type: 'button', class: 'close', autofocus: 'autofocus', value: 'OK')
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
require 'glimmer/dsl/opal/message_box_expression'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Opal
|
3
|
+
# Adapts Glimmer UI classes to SWT JavaBean property owner classes (which are now adapted to Opal)
|
4
|
+
module PropertyOwner
|
5
|
+
def get_attribute(attribute_name)
|
6
|
+
send(attribute_getter(attribute_name))
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_attribute(attribute_name, *args)
|
10
|
+
send(attribute_setter(attribute_name), *args) unless send(attribute_getter(attribute_name)) == args.first
|
11
|
+
end
|
12
|
+
|
13
|
+
def attribute_setter(attribute_name)
|
14
|
+
"#{attribute_name.to_s.underscore}="
|
15
|
+
end
|
16
|
+
|
17
|
+
def attribute_getter(attribute_name)
|
18
|
+
attribute_name.to_s.underscore
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -41,8 +41,9 @@ module Glimmer
|
|
41
41
|
select_text = @text
|
42
42
|
items = @items
|
43
43
|
select_id = id
|
44
|
+
select_style = css
|
44
45
|
@dom ||= DOM {
|
45
|
-
select(id: select_id) {
|
46
|
+
select(id: select_id, style: select_style) {
|
46
47
|
items.to_a.each do |item|
|
47
48
|
option_hash = {value: item}
|
48
49
|
option_hash[:selected] = 'selected' if select_text == item
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'glimmer/opal/div_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class TabFolder < ElementProxy
|
6
|
+
attr_reader :tabs
|
7
|
+
|
8
|
+
def initialize(parent, args)
|
9
|
+
super(parent, args)
|
10
|
+
@tabs = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_child(child)
|
14
|
+
super(child)
|
15
|
+
if @children.size == 1
|
16
|
+
child.show
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def hide_all_tab_content
|
21
|
+
@children.each(&:hide)
|
22
|
+
end
|
23
|
+
|
24
|
+
def name
|
25
|
+
'div'
|
26
|
+
end
|
27
|
+
|
28
|
+
def tabs_dom
|
29
|
+
tabs_id = id + '-tabs'
|
30
|
+
@tabs_dom ||= DOM {
|
31
|
+
div(id: tabs_id, class: 'tabs')
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def dom
|
36
|
+
tab_folder_id = id
|
37
|
+
tab_folder_id_style = css
|
38
|
+
@dom ||= DOM {
|
39
|
+
div(id: tab_folder_id, style: tab_folder_id_style, class: 'tab-folder') {
|
40
|
+
|
41
|
+
}
|
42
|
+
}.tap {|the_dom| the_dom << tabs_dom }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'glimmer/opal/input_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class TabItem < DivProxy
|
6
|
+
include Glimmer
|
7
|
+
attr_reader :text, :content_visible
|
8
|
+
|
9
|
+
def initialize(parent, args)
|
10
|
+
super(parent, args)
|
11
|
+
css_classes << 'tab-item'
|
12
|
+
content do
|
13
|
+
on_widget_selected {
|
14
|
+
@parent.hide_all_tab_content
|
15
|
+
show
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def content(&block)
|
21
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::TabItemExpression.new, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def show
|
25
|
+
@content_visible = true
|
26
|
+
redraw
|
27
|
+
end
|
28
|
+
|
29
|
+
def hide
|
30
|
+
@content_visible = false
|
31
|
+
redraw
|
32
|
+
end
|
33
|
+
|
34
|
+
def text=(value)
|
35
|
+
@text = value
|
36
|
+
redraw
|
37
|
+
end
|
38
|
+
|
39
|
+
def name
|
40
|
+
'button'
|
41
|
+
end
|
42
|
+
|
43
|
+
def selector
|
44
|
+
super + '-tab'
|
45
|
+
end
|
46
|
+
|
47
|
+
def observation_request_to_event_mapping
|
48
|
+
{
|
49
|
+
'on_widget_selected' => {
|
50
|
+
event: 'click'
|
51
|
+
},
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def redraw
|
56
|
+
if @tab_dom
|
57
|
+
old_tab_dom = @tab_dom
|
58
|
+
@tab_dom = nil
|
59
|
+
old_tab_dom.replace tab_dom
|
60
|
+
else
|
61
|
+
tab_dom
|
62
|
+
end
|
63
|
+
super
|
64
|
+
end
|
65
|
+
|
66
|
+
def tab_dom
|
67
|
+
tab_id = id + '-tab'
|
68
|
+
tab_text = text
|
69
|
+
tab_active = content_visible ? 'active' : ''
|
70
|
+
@tab_dom ||= DOM {
|
71
|
+
button(id: tab_id, class: "tab #{tab_active}") {
|
72
|
+
tab_text
|
73
|
+
}
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def dom
|
78
|
+
tab_item_id = id
|
79
|
+
tab_item_id_style = css
|
80
|
+
tab_item_css_classes = css_classes
|
81
|
+
if content_visible
|
82
|
+
tab_item_css_classes.delete('hide')
|
83
|
+
else
|
84
|
+
tab_item_css_classes << 'hide'
|
85
|
+
end
|
86
|
+
if !@parent.tabs.include?(self)
|
87
|
+
@parent.tabs_dom << tab_dom
|
88
|
+
@parent.tabs << self
|
89
|
+
end
|
90
|
+
@dom ||= DOM {
|
91
|
+
div(id: tab_item_id, style: tab_item_id_style, class: tab_item_css_classes.to_a.join(' ')) {
|
92
|
+
}
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
require 'glimmer/dsl/opal/tab_item_expression'
|