glimmer-dsl-opal 0.0.3 → 0.0.8
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 +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
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'glimmer/dsl/static_expression'
|
2
|
+
require 'glimmer/dsl/parent_expression'
|
3
|
+
require 'glimmer/opal/table_proxy'
|
4
|
+
|
5
|
+
module Glimmer
|
6
|
+
module DSL
|
7
|
+
module Opal
|
8
|
+
class TableExpression < StaticExpression
|
9
|
+
include ParentExpression
|
10
|
+
|
11
|
+
def interpret(parent, keyword, *args, &block)
|
12
|
+
Glimmer::Opal::TableProxy.new(parent, args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
require 'glimmer/data_binding/model_binding'
|
3
|
+
require 'glimmer/data_binding/table_items_binding'
|
4
|
+
require 'glimmer/opal/table_proxy'
|
5
|
+
|
6
|
+
module Glimmer
|
7
|
+
module DSL
|
8
|
+
module Opal
|
9
|
+
#Depends on BindCommandHandler and TableColumnPropertiesDataBindingCommandHandler
|
10
|
+
class TableItemsDataBindingExpression < Expression
|
11
|
+
def can_interpret?(parent, keyword, *args, &block)
|
12
|
+
keyword == "items" and
|
13
|
+
block.nil? and
|
14
|
+
parent.is_a?(Glimmer::Opal::TableProxy) and
|
15
|
+
args.size == 2 and
|
16
|
+
args[0].is_a?(DataBinding::ModelBinding) and
|
17
|
+
args[0].evaluate_property.is_a?(Array) and
|
18
|
+
args[1].is_a?(Array)
|
19
|
+
end
|
20
|
+
|
21
|
+
def interpret(parent, keyword, *args, &block)
|
22
|
+
model_binding = args[0]
|
23
|
+
column_properties = args[1]
|
24
|
+
DataBinding::TableItemsBinding.new(parent, model_binding, column_properties)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Opal
|
3
|
+
class DisplayProxy
|
4
|
+
class << self
|
5
|
+
def instance
|
6
|
+
@instance ||= new
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def async_exec(&block)
|
11
|
+
executer = lambda do
|
12
|
+
if $document.at_css('.modal')
|
13
|
+
sleep(0.05)
|
14
|
+
Async::Task.new(&executer)
|
15
|
+
else
|
16
|
+
block.call
|
17
|
+
end
|
18
|
+
end
|
19
|
+
Async::Task.new(&executer)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,14 +3,23 @@ require 'glimmer/opal/element_proxy'
|
|
3
3
|
module Glimmer
|
4
4
|
module Opal
|
5
5
|
class DivProxy < ElementProxy
|
6
|
+
attr_reader :layout
|
7
|
+
|
6
8
|
def initialize(parent, args)
|
7
9
|
super(parent, args)
|
8
|
-
GridLayoutProxy.new(self, [])
|
10
|
+
@layout = GridLayoutProxy.new(self, [])
|
11
|
+
end
|
12
|
+
|
13
|
+
def redraw
|
14
|
+
super()
|
15
|
+
@children.each do |child|
|
16
|
+
add_child(child) # TODO think of impact of this on performance, and of other alternatives
|
17
|
+
end
|
9
18
|
end
|
10
19
|
|
11
20
|
def dom
|
12
21
|
div_id = id
|
13
|
-
div_style =
|
22
|
+
div_style = css
|
14
23
|
@dom ||= DOM {
|
15
24
|
div(id: div_id, class: 'grid-layout', style: div_style)
|
16
25
|
}
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'glimmer/opal/element_proxy'
|
2
|
+
require 'glimmer/opal/point'
|
2
3
|
|
3
4
|
module Glimmer
|
4
5
|
module Opal
|
5
6
|
class DocumentProxy < ElementProxy
|
6
7
|
# TODO consider renaming to ShellProxy to match SWT API
|
8
|
+
attr_reader :minimum_size
|
7
9
|
|
8
10
|
def initialize(args)
|
9
11
|
@args = args
|
@@ -23,28 +25,156 @@ module Glimmer
|
|
23
25
|
$document.title = value
|
24
26
|
end
|
25
27
|
end
|
28
|
+
|
29
|
+
def minimum_size=(width_or_minimum_size, height = nil)
|
30
|
+
@minimum_size = height.nil? ? width_or_minimum_size : Point.new(width_or_minimum_size, height)
|
31
|
+
redraw
|
32
|
+
end
|
26
33
|
|
27
34
|
def head_dom
|
28
35
|
# TODO make grid-layout support grab excess space false
|
29
36
|
@head_dom ||= DOM {
|
30
37
|
head {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
<<~CSS
|
39
|
+
<style>
|
40
|
+
html {
|
41
|
+
width: 100%;
|
42
|
+
height: 100%;
|
43
|
+
}
|
44
|
+
body {
|
45
|
+
width: 100%;
|
46
|
+
height: 100%;
|
47
|
+
margin: 0;
|
48
|
+
}
|
49
|
+
body > iframe {
|
50
|
+
width: 100%;
|
51
|
+
height: 100%;
|
52
|
+
}
|
53
|
+
ul {
|
54
|
+
list-style: none;
|
55
|
+
padding: 0;
|
56
|
+
}
|
57
|
+
li {
|
58
|
+
cursor: default;
|
59
|
+
padding-left: 10px;
|
60
|
+
padding-right: 10px;
|
61
|
+
}
|
62
|
+
li.empty-list-item {
|
63
|
+
color: transparent;
|
64
|
+
}
|
65
|
+
.tabs {
|
66
|
+
overflow: hidden;
|
67
|
+
border: 1px solid #ccc;
|
68
|
+
background-color: #f1f1f1;
|
69
|
+
}
|
70
|
+
|
71
|
+
/* Style the buttons inside the tab */
|
72
|
+
.tabs .tab {
|
73
|
+
background-color: inherit;
|
74
|
+
float: left;
|
75
|
+
border: none;
|
76
|
+
outline: none;
|
77
|
+
cursor: pointer;
|
78
|
+
padding: 14px 16px;
|
79
|
+
transition: 0.3s;
|
80
|
+
font-size: 17px;
|
81
|
+
}
|
82
|
+
|
83
|
+
/* Change background color of buttons on hover */
|
84
|
+
.tabs .tab:hover {
|
85
|
+
background-color: #ddd;
|
86
|
+
}
|
87
|
+
|
88
|
+
/* Create an active/current tablink class */
|
89
|
+
.tabs .tab.active {
|
90
|
+
background-color: #ccc;
|
91
|
+
}
|
92
|
+
|
93
|
+
/* Style the tab content */
|
94
|
+
.tab-item {
|
95
|
+
padding: 6px 12px;
|
96
|
+
border: 1px solid #ccc;
|
97
|
+
border-top: none;
|
98
|
+
}
|
99
|
+
|
100
|
+
.hide {
|
101
|
+
display: none !important;
|
102
|
+
}
|
103
|
+
|
104
|
+
/* The Modal (background) */
|
105
|
+
.modal {
|
106
|
+
position: fixed; /* Stay in place */
|
107
|
+
z-index: 1; /* Sit on top */
|
108
|
+
padding-top: 100px; /* Location of the box */
|
109
|
+
left: 0;
|
110
|
+
top: 0;
|
111
|
+
width: 100%; /* Full width */
|
112
|
+
height: 100%; /* Full height */
|
113
|
+
overflow: auto; /* Enable scroll if needed */
|
114
|
+
background-color: rgb(0,0,0); /* Fallback color */
|
115
|
+
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
116
|
+
text-align: center;
|
117
|
+
}
|
118
|
+
|
119
|
+
/* Modal Content */
|
120
|
+
.modal-content {
|
121
|
+
background-color: #fefefe;
|
122
|
+
margin: auto;
|
123
|
+
border: 1px solid #888;
|
124
|
+
display: inline-block;
|
125
|
+
min-width: 200px;
|
126
|
+
}
|
127
|
+
|
128
|
+
.modal-content .text {
|
129
|
+
background: rgb(80, 116, 211);
|
130
|
+
color: white;
|
131
|
+
padding: 5px;
|
132
|
+
}
|
133
|
+
|
134
|
+
.modal-content .message {
|
135
|
+
padding: 20px;
|
136
|
+
}
|
137
|
+
|
138
|
+
/* The Close Button */
|
139
|
+
.close {
|
140
|
+
color: #aaaaaa;
|
141
|
+
float: right;
|
142
|
+
font-weight: bold;
|
143
|
+
margin: 5px;
|
144
|
+
}
|
145
|
+
|
146
|
+
.close:hover,
|
147
|
+
.close:focus {
|
148
|
+
color: #000;
|
149
|
+
text-decoration: none;
|
150
|
+
cursor: pointer;
|
151
|
+
}
|
152
|
+
|
153
|
+
.selected {
|
154
|
+
background: rgb(80, 116, 211);
|
155
|
+
color: white;
|
156
|
+
}
|
157
|
+
|
158
|
+
table {
|
159
|
+
border-spacing: 0;
|
160
|
+
}
|
161
|
+
|
162
|
+
table tr th,td {
|
163
|
+
cursor: default;
|
164
|
+
}
|
165
|
+
|
166
|
+
</style>
|
167
|
+
CSS
|
41
168
|
}
|
42
169
|
}
|
43
170
|
end
|
44
171
|
|
45
172
|
def dom
|
173
|
+
i = 0
|
174
|
+
body_style = ''
|
175
|
+
body_style += "min-width: #{@minimum_size.x}px; min-height: #{@minimum_size.y}px;" if @minimum_size
|
46
176
|
@dom ||= DOM {
|
47
|
-
body {
|
177
|
+
body(style: body_style) {
|
48
178
|
}
|
49
179
|
}
|
50
180
|
end
|
@@ -5,26 +5,40 @@ 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
9
|
|
10
10
|
def initialize(parent, args)
|
11
11
|
@parent = parent
|
12
12
|
@args = args
|
13
|
-
@children =
|
14
|
-
@parent.add_child(self)
|
13
|
+
@children = Set.new
|
15
14
|
@css_classes = Set.new
|
15
|
+
@css = ''
|
16
|
+
@enabled = true
|
17
|
+
@parent.add_child(self)
|
16
18
|
end
|
17
19
|
|
18
20
|
def add_child(child)
|
19
|
-
|
21
|
+
# return if @children.include?(child) # TODO consider adding an option to enable this if needed to prevent dom repetition
|
20
22
|
@children << child
|
21
23
|
dom << child.dom
|
22
24
|
end
|
25
|
+
|
26
|
+
def enabled=(value)
|
27
|
+
@enabled = value
|
28
|
+
redraw
|
29
|
+
end
|
23
30
|
|
24
31
|
def redraw
|
25
|
-
|
26
|
-
|
27
|
-
|
32
|
+
if @dom
|
33
|
+
old_dom = @dom
|
34
|
+
@dom = nil
|
35
|
+
old_dom.replace dom
|
36
|
+
else
|
37
|
+
dom
|
38
|
+
end
|
39
|
+
@children.each do |child|
|
40
|
+
child.redraw
|
41
|
+
end
|
28
42
|
end
|
29
43
|
|
30
44
|
# Subclasses must override with their own mappings
|
@@ -37,6 +51,7 @@ module Glimmer
|
|
37
51
|
end
|
38
52
|
|
39
53
|
def id
|
54
|
+
# TODO replace hash with autoincrement per name
|
40
55
|
"#{name}-#{hash}"
|
41
56
|
end
|
42
57
|
|
@@ -70,18 +85,26 @@ module Glimmer
|
|
70
85
|
redraw
|
71
86
|
end
|
72
87
|
|
73
|
-
def
|
74
|
-
@
|
88
|
+
def css=(css)
|
89
|
+
@css = css
|
75
90
|
redraw
|
76
91
|
end
|
77
92
|
|
93
|
+
def has_style?(symbol)
|
94
|
+
@args.include?(symbol) # not a very solid implementation. Bring SWT constants eventually
|
95
|
+
end
|
96
|
+
|
78
97
|
def handle_observation_request(keyword, &event_listener)
|
79
98
|
return unless observation_request_to_event_mapping.keys.include?(keyword)
|
80
|
-
event =
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
99
|
+
event = nil
|
100
|
+
delegate = nil
|
101
|
+
[observation_request_to_event_mapping[keyword]].flatten.each do |mapping|
|
102
|
+
event = mapping[:event]
|
103
|
+
event_handler = mapping[:event_handler]
|
104
|
+
potential_event_listener = event_handler&.call(event_listener)
|
105
|
+
event_listener = event_handler&.call(event_listener) || event_listener
|
106
|
+
delegate = $document.on(event, selector, &event_listener)
|
107
|
+
end
|
85
108
|
EventListenerProxy.new(element_proxy: self, event: event, selector: selector, delegate: delegate)
|
86
109
|
end
|
87
110
|
|
@@ -171,7 +194,7 @@ module Glimmer
|
|
171
194
|
# },
|
172
195
|
InputProxy => {
|
173
196
|
:text => lambda do |observer|
|
174
|
-
on_modify_text { |modify_event|
|
197
|
+
on_modify_text { |modify_event|
|
175
198
|
observer.call(text)
|
176
199
|
}
|
177
200
|
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
|