glimmer-dsl-opal 0.0.4 → 0.0.9
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/CHANGELOG.md +35 -0
- data/README.md +983 -34
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal.rb +5 -2
- data/lib/glimmer/data_binding/ext/observable_model.rb +40 -0
- data/lib/glimmer/data_binding/table_items_binding.rb +70 -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/column_properties_expression.rb +22 -0
- data/lib/glimmer/dsl/opal/dsl.rb +11 -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/tab_folder_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/tab_item_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/table_column_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/table_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +29 -0
- data/lib/glimmer/opal/display_proxy.rb +23 -0
- data/lib/glimmer/opal/div_proxy.rb +11 -2
- data/lib/glimmer/opal/document_proxy.rb +124 -4
- data/lib/glimmer/opal/element_proxy.rb +45 -14
- data/lib/glimmer/opal/grid_layout_proxy.rb +3 -1
- data/lib/glimmer/opal/iframe_proxy.rb +23 -0
- data/lib/glimmer/opal/input_proxy.rb +8 -4
- data/lib/glimmer/opal/label_proxy.rb +1 -1
- data/lib/glimmer/opal/layout_data_proxy.rb +23 -2
- data/lib/glimmer/opal/list_proxy.rb +2 -2
- data/lib/glimmer/opal/modal.rb +94 -0
- data/lib/glimmer/opal/point.rb +5 -0
- data/lib/glimmer/opal/select_proxy.rb +1 -1
- data/lib/glimmer/opal/tab_folder.rb +53 -0
- data/lib/glimmer/opal/tab_item.rb +98 -0
- data/lib/glimmer/opal/table_column.rb +50 -0
- data/lib/glimmer/opal/table_item.rb +136 -0
- data/lib/glimmer/opal/table_proxy.rb +149 -0
- data/lib/samples/elaborate/contact_manager.rb +1 -2
- 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 +28 -16
- data/lib/glimmer/config.rb +0 -22
- data/lib/glimmer/dsl/engine.rb +0 -193
- data/lib/glimmer/dsl/expression.rb +0 -42
- data/lib/glimmer/dsl/expression_handler.rb +0 -48
- data/lib/glimmer/dsl/parent_expression.rb +0 -12
- data/lib/glimmer/dsl/static_expression.rb +0 -36
- data/lib/glimmer/dsl/top_level_expression.rb +0 -7
- data/lib/glimmer/error.rb +0 -6
- data/lib/glimmer/invalid_keyword_error.rb +0 -6
@@ -5,26 +5,54 @@ module Glimmer
|
|
5
5
|
class ElementProxy
|
6
6
|
include Glimmer
|
7
7
|
include PropertyOwner
|
8
|
-
attr_reader :parent, :args, :css_classes, :
|
8
|
+
attr_reader :parent, :args, :css_classes, :css, :children, :enabled
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def next_id_number_for(name)
|
12
|
+
@max_id_numbers[name] = max_id_number_for(name) + 1
|
13
|
+
end
|
14
|
+
|
15
|
+
def max_id_number_for(name)
|
16
|
+
@max_id_numbers[name] = max_id_numbers[name] || 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def max_id_numbers
|
20
|
+
@max_id_numbers ||= {}
|
21
|
+
end
|
22
|
+
end
|
9
23
|
|
10
24
|
def initialize(parent, args)
|
11
25
|
@parent = parent
|
12
26
|
@args = args
|
13
|
-
@children =
|
14
|
-
@parent.add_child(self)
|
27
|
+
@children = Set.new
|
15
28
|
@css_classes = Set.new
|
29
|
+
@css = ''
|
30
|
+
@enabled = true
|
31
|
+
@parent.add_child(self)
|
16
32
|
end
|
17
33
|
|
18
34
|
def add_child(child)
|
19
|
-
|
35
|
+
# return if @children.include?(child) # TODO consider adding an option to enable this if needed to prevent dom repetition
|
20
36
|
@children << child
|
21
37
|
dom << child.dom
|
22
38
|
end
|
39
|
+
|
40
|
+
def enabled=(value)
|
41
|
+
@enabled = value
|
42
|
+
redraw
|
43
|
+
end
|
23
44
|
|
24
45
|
def redraw
|
25
|
-
|
26
|
-
|
27
|
-
|
46
|
+
if @dom
|
47
|
+
old_dom = @dom
|
48
|
+
@dom = nil
|
49
|
+
old_dom.replace dom
|
50
|
+
else
|
51
|
+
dom
|
52
|
+
end
|
53
|
+
@children.each do |child|
|
54
|
+
child.redraw
|
55
|
+
end
|
28
56
|
end
|
29
57
|
|
30
58
|
# Subclasses must override with their own mappings
|
@@ -37,9 +65,14 @@ module Glimmer
|
|
37
65
|
end
|
38
66
|
|
39
67
|
def id
|
40
|
-
"#{name}-#{
|
68
|
+
@id ||= "#{name}-#{ElementProxy.next_id_number_for(name)}"
|
41
69
|
end
|
42
|
-
|
70
|
+
|
71
|
+
# Sets id explicitly. Useful in cases of wanting to maintain a stable id
|
72
|
+
def id=(value)
|
73
|
+
@id = value
|
74
|
+
end
|
75
|
+
|
43
76
|
# Subclasses can override with their own selector
|
44
77
|
def selector
|
45
78
|
"#{name}##{id}"
|
@@ -70,10 +103,8 @@ module Glimmer
|
|
70
103
|
redraw
|
71
104
|
end
|
72
105
|
|
73
|
-
|
74
|
-
|
75
|
-
def style=(css)
|
76
|
-
@style = css
|
106
|
+
def css=(css)
|
107
|
+
@css = css
|
77
108
|
redraw
|
78
109
|
end
|
79
110
|
|
@@ -181,7 +212,7 @@ module Glimmer
|
|
181
212
|
# },
|
182
213
|
InputProxy => {
|
183
214
|
:text => lambda do |observer|
|
184
|
-
on_modify_text { |modify_event|
|
215
|
+
on_modify_text { |modify_event|
|
185
216
|
observer.call(text)
|
186
217
|
}
|
187
218
|
end,
|
@@ -10,7 +10,9 @@ module Glimmer
|
|
10
10
|
@parent = parent
|
11
11
|
@args = args
|
12
12
|
@parent.add_css_class('grid-layout')
|
13
|
+
@horizontal_spacing = 10
|
13
14
|
@vertical_spacing = 10
|
15
|
+
@num_columns = @args.first || 1
|
14
16
|
reapply
|
15
17
|
end
|
16
18
|
|
@@ -39,7 +41,7 @@ module Glimmer
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def reapply
|
42
|
-
@parent.
|
44
|
+
@parent.css = <<~CSS
|
43
45
|
display: grid;
|
44
46
|
grid-template-columns: #{'auto ' * @num_columns.to_i};
|
45
47
|
grid-row-gap: #{@vertical_spacing}px;
|
@@ -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
|
@@ -19,8 +19,10 @@ module Glimmer
|
|
19
19
|
event: 'keyup',
|
20
20
|
event_handler: -> (event_listener) {
|
21
21
|
-> (event) {
|
22
|
-
|
23
|
-
|
22
|
+
if args.last[:type] == 'text'
|
23
|
+
@text = event.target.value
|
24
|
+
event_listener.call(event)
|
25
|
+
end
|
24
26
|
}
|
25
27
|
}
|
26
28
|
}
|
@@ -30,10 +32,12 @@ module Glimmer
|
|
30
32
|
def dom
|
31
33
|
input_text = @text
|
32
34
|
input_id = id
|
33
|
-
input_style =
|
35
|
+
input_style = css
|
34
36
|
input_args = @args.last
|
37
|
+
input_disabled = @enabled ? {} : {'disabled': 'disabled'}
|
38
|
+
input_args = input_args.merge(type: 'password') if has_style?(:password)
|
35
39
|
@dom ||= DOM {
|
36
|
-
input input_args.merge(id: input_id, style: input_style, value: input_text)
|
40
|
+
input input_args.merge(id: input_id, style: input_style, value: input_text, style: 'min-width: 27px;').merge(input_disabled)
|
37
41
|
}
|
38
42
|
end
|
39
43
|
end
|
@@ -4,7 +4,13 @@ module Glimmer
|
|
4
4
|
module Opal
|
5
5
|
class LayoutDataProxy
|
6
6
|
include PropertyOwner
|
7
|
-
attr_reader :parent,
|
7
|
+
attr_reader :parent,
|
8
|
+
:args,
|
9
|
+
:horizontal_alignment,
|
10
|
+
:vertical_alignment,
|
11
|
+
:grab_excess_horizontal_space,
|
12
|
+
:grab_excess_vertical_space,
|
13
|
+
:height_hint
|
8
14
|
|
9
15
|
def initialize(parent, args)
|
10
16
|
@parent = parent
|
@@ -12,18 +18,33 @@ module Glimmer
|
|
12
18
|
reapply
|
13
19
|
end
|
14
20
|
|
21
|
+
def height_hint=(height_hint)
|
22
|
+
@height_hint = height_hint
|
23
|
+
reapply
|
24
|
+
end
|
25
|
+
|
15
26
|
def horizontal_alignment=(horizontal_alignment)
|
16
27
|
@horizontal_alignment = horizontal_alignment
|
17
28
|
reapply
|
18
29
|
end
|
19
30
|
|
31
|
+
def vertical_alignment=(vertical_alignment)
|
32
|
+
@vertical_alignment = vertical_alignment
|
33
|
+
reapply
|
34
|
+
end
|
35
|
+
|
20
36
|
def grab_excess_horizontal_space=(grab_excess_horizontal_space)
|
21
37
|
@grab_excess_horizontal_space = grab_excess_horizontal_space
|
22
38
|
reapply
|
23
39
|
end
|
24
40
|
|
41
|
+
def grab_excess_vertical_space=(grab_excess_vertical_space)
|
42
|
+
@grab_excess_vertical_space = grab_excess_vertical_space
|
43
|
+
reapply
|
44
|
+
end
|
45
|
+
|
25
46
|
def reapply
|
26
|
-
# @parent.
|
47
|
+
# @parent.css = <<~CSS
|
27
48
|
# CSS
|
28
49
|
end
|
29
50
|
end
|
@@ -60,13 +60,13 @@ module Glimmer
|
|
60
60
|
def dom
|
61
61
|
list_items = @items
|
62
62
|
list_id = id
|
63
|
-
list_style =
|
63
|
+
list_style = css
|
64
64
|
list_selection = selection
|
65
65
|
@dom ||= DOM {
|
66
66
|
ul(id: list_id, style: list_style) {
|
67
67
|
list_items.to_a.each_with_index do |item, index|
|
68
68
|
li_class = ''
|
69
|
-
li_class += ' selected
|
69
|
+
li_class += ' selected' if list_selection.include?(item)
|
70
70
|
li_class += ' empty-list-item' if item == ITEM_EMPTY
|
71
71
|
li(class: li_class) {
|
72
72
|
item
|
@@ -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,53 @@
|
|
1
|
+
require 'glimmer/opal/element_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 redraw
|
21
|
+
super()
|
22
|
+
@children.each do |child|
|
23
|
+
add_child(child) # TODO think of impact of this on performance
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def hide_all_tab_content
|
28
|
+
@children.each(&:hide)
|
29
|
+
end
|
30
|
+
|
31
|
+
def name
|
32
|
+
'div'
|
33
|
+
end
|
34
|
+
|
35
|
+
def tabs_dom
|
36
|
+
tabs_id = id + '-tabs'
|
37
|
+
@tabs_dom ||= DOM {
|
38
|
+
div(id: tabs_id, class: 'tabs')
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def dom
|
43
|
+
tab_folder_id = id
|
44
|
+
tab_folder_id_style = css
|
45
|
+
@dom ||= DOM {
|
46
|
+
div(id: tab_folder_id, style: tab_folder_id_style, class: 'tab-folder') {
|
47
|
+
|
48
|
+
}
|
49
|
+
}.tap {|the_dom| the_dom << tabs_dom }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'glimmer/opal/div_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'
|