glimmer-dsl-opal 0.0.3 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +1049 -35
- 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/list_selection_binding.rb +51 -0
- data/lib/glimmer/data_binding/table_items_binding.rb +67 -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 +14 -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/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 +141 -11
- data/lib/glimmer/opal/element_proxy.rb +38 -15
- 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 +80 -0
- 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 +30 -14
- 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
@@ -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
|
@@ -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' 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,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'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'glimmer/opal/element_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module Opal
|
5
|
+
class TableColumn < ElementProxy
|
6
|
+
include Glimmer
|
7
|
+
attr_reader :text, :width
|
8
|
+
|
9
|
+
def text=(value)
|
10
|
+
@text = value
|
11
|
+
redraw
|
12
|
+
end
|
13
|
+
|
14
|
+
def width=(value)
|
15
|
+
@width = value
|
16
|
+
redraw
|
17
|
+
end
|
18
|
+
|
19
|
+
def css
|
20
|
+
<<~CSS
|
21
|
+
width: #{width};
|
22
|
+
CSS
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
'th'
|
27
|
+
end
|
28
|
+
|
29
|
+
def observation_request_to_event_mapping
|
30
|
+
{
|
31
|
+
'on_widget_selected' => {
|
32
|
+
event: 'click'
|
33
|
+
},
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def dom
|
38
|
+
table_column_text = text
|
39
|
+
table_column_id = id
|
40
|
+
table_column_id_style = css
|
41
|
+
table_column_css_classes = css_classes
|
42
|
+
@dom ||= DOM {
|
43
|
+
th(id: table_column_id, style: table_column_id_style, class: table_column_css_classes.to_a.join(' ')) {
|
44
|
+
table_column_text
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|