glimmer-dsl-opal 0.10.1 → 0.13.0
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 +29 -0
- data/README.md +34 -27
- data/VERSION +1 -1
- data/lib/display.rb +3 -0
- data/lib/glimmer-dsl-opal.rb +1 -1
- data/lib/glimmer-dsl-opal/ext/glimmer/dsl/engine.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +15 -13
- data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +55 -28
- data/lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb +2 -2
- data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox.rb +16 -14
- data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox_group.rb +14 -9
- data/lib/glimmer-dsl-opal/samples/hello/hello_combo.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +5 -5
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +16 -12
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_date_time.rb +4 -4
- data/lib/glimmer-dsl-opal/samples/hello/hello_group.rb +6 -6
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_radio.rb +18 -16
- data/lib/glimmer-dsl-opal/samples/hello/hello_radio_group.rb +17 -12
- data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +4 -4
- data/lib/glimmer/data_binding/table_items_binding.rb +3 -2
- data/lib/glimmer/dsl/opal/bind_expression.rb +24 -25
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +8 -8
- data/lib/glimmer/dsl/opal/dsl.rb +4 -0
- data/lib/glimmer/dsl/opal/menu_expression.rb +1 -1
- data/lib/glimmer/dsl/opal/property_expression.rb +2 -1
- data/lib/glimmer/dsl/opal/shape_expression.rb +26 -0
- data/lib/glimmer/dsl/opal/shell_expression.rb +1 -1
- data/lib/glimmer/dsl/opal/shine_data_binding_expression.rb +49 -0
- data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +2 -2
- data/lib/glimmer/dsl/opal/widget_expression.rb +1 -1
- data/lib/glimmer/swt/combo_proxy.rb +1 -0
- data/lib/glimmer/swt/composite_proxy.rb +2 -0
- data/lib/glimmer/swt/dialog_proxy.rb +2 -5
- data/lib/glimmer/swt/display_proxy.rb +104 -10
- data/lib/glimmer/swt/grid_layout_proxy.rb +17 -17
- data/lib/glimmer/swt/layout_proxy.rb +23 -3
- data/lib/glimmer/swt/message_box_proxy.rb +4 -4
- data/lib/glimmer/swt/row_layout_proxy.rb +12 -3
- data/lib/glimmer/swt/table_proxy.rb +19 -3
- data/lib/glimmer/swt/widget_proxy.rb +3 -4
- data/lib/glimmer/ui/custom_shell.rb +22 -5
- data/lib/glimmer/ui/custom_widget.rb +11 -2
- data/lib/glimmer/util/proc_tracker.rb +5 -3
- metadata +11 -9
@@ -19,6 +19,23 @@ module Glimmer
|
|
19
19
|
# TODO do the following instead of reapply
|
20
20
|
# @parent.add_css_class("num-columns-#{@num_columns}")
|
21
21
|
# reinitialize # TODO reimplement without using reinitialize
|
22
|
+
layout_css = <<~CSS
|
23
|
+
grid-template-columns: #{'auto ' * @num_columns.to_i};
|
24
|
+
grid-row-gap: #{@vertical_spacing}px;
|
25
|
+
grid-column-gap: #{@horizontal_spacing}px;
|
26
|
+
CSS
|
27
|
+
if @parent.css_classes.include?('grid-layout')
|
28
|
+
layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
|
29
|
+
@parent.dom_element.css(key, value) unless key.nil?
|
30
|
+
end
|
31
|
+
if @parent.is_a?(GroupProxy)
|
32
|
+
@parent.dom_element.find('legend').css('grid-column-start', "span #{@num_columns.to_i}")
|
33
|
+
end
|
34
|
+
else
|
35
|
+
layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
|
36
|
+
@parent.dom_element.css(key, 'initial') unless key.nil?
|
37
|
+
end
|
38
|
+
end
|
22
39
|
end
|
23
40
|
|
24
41
|
def make_columns_equal_width=(equal_width)
|
@@ -63,23 +80,6 @@ module Glimmer
|
|
63
80
|
self.margin_width = 15
|
64
81
|
self.margin_height = 15
|
65
82
|
self.num_columns = @args.first || 1
|
66
|
-
layout_css = <<~CSS
|
67
|
-
grid-template-columns: #{'auto ' * @num_columns.to_i};
|
68
|
-
grid-row-gap: #{@vertical_spacing}px;
|
69
|
-
grid-column-gap: #{@horizontal_spacing}px;
|
70
|
-
CSS
|
71
|
-
if @parent.css_classes.include?('grid-layout')
|
72
|
-
layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
|
73
|
-
@parent.dom_element.css(key, value) unless key.nil?
|
74
|
-
end
|
75
|
-
if @parent.is_a?(GroupProxy)
|
76
|
-
@parent.dom_element.find('legend').css('grid-column-start', "span #{@num_columns.to_i}")
|
77
|
-
end
|
78
|
-
else
|
79
|
-
layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
|
80
|
-
@parent.dom_element.css(key, 'initial') unless key.nil?
|
81
|
-
end
|
82
|
-
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -1,3 +1,24 @@
|
|
1
|
+
# Copyright (c) 2020-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
1
22
|
require 'glimmer/swt/property_owner'
|
2
23
|
|
3
24
|
module Glimmer
|
@@ -13,9 +34,8 @@ module Glimmer
|
|
13
34
|
end
|
14
35
|
|
15
36
|
def layout_class(keyword)
|
16
|
-
|
17
|
-
|
18
|
-
a_layout_class = Glimmer::SWT.const_get(class_name_main.to_sym) rescue Glimmer::SWT.const_get(class_name_alternative.to_sym)
|
37
|
+
class_name_main = "#{keyword.camelcase(:upper)}Proxy"
|
38
|
+
a_layout_class = Glimmer::SWT.const_get(class_name_main.to_sym)
|
19
39
|
a_layout_class if a_layout_class.ancestors.include?(Glimmer::SWT::LayoutProxy)
|
20
40
|
rescue => e
|
21
41
|
Glimmer::Config.logger.debug "Layout #{keyword} was not found!"
|
@@ -74,14 +74,13 @@ module Glimmer
|
|
74
74
|
i = 0
|
75
75
|
@parent = parent
|
76
76
|
@parent = nil if parent.is_a?(LatestShellProxy)
|
77
|
-
@parent ||= DisplayProxy.instance.shells.
|
77
|
+
@parent ||= DisplayProxy.instance.shells.detect(&:open?) || ShellProxy.new([])
|
78
78
|
@args = args
|
79
79
|
@block = block
|
80
80
|
@children = Set.new
|
81
81
|
@enabled = true
|
82
82
|
on_widget_selected {
|
83
83
|
hide
|
84
|
-
@open = false
|
85
84
|
}
|
86
85
|
DisplayProxy.instance.message_boxes << self
|
87
86
|
end
|
@@ -106,7 +105,7 @@ module Glimmer
|
|
106
105
|
|
107
106
|
def open
|
108
107
|
shell.open(async: false) unless shell.open?
|
109
|
-
owned_proc = Glimmer::Util::ProcTracker.new(owner: self) {
|
108
|
+
owned_proc = Glimmer::Util::ProcTracker.new(owner: self, invoked_from: :open) {
|
110
109
|
parent.post_initialize_child(self)
|
111
110
|
@open = true
|
112
111
|
}
|
@@ -115,10 +114,11 @@ module Glimmer
|
|
115
114
|
|
116
115
|
def hide
|
117
116
|
dom_element.remove
|
117
|
+
@open = false
|
118
118
|
end
|
119
119
|
|
120
120
|
def content(&block)
|
121
|
-
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::MessageBoxExpression.new, &block)
|
121
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::MessageBoxExpression.new, 'message_box', *@args, &block)
|
122
122
|
end
|
123
123
|
|
124
124
|
def selector
|
@@ -42,13 +42,17 @@ module Glimmer
|
|
42
42
|
}
|
43
43
|
CSS
|
44
44
|
|
45
|
-
attr_reader :type, :margin_width, :margin_height, :margin_top, :margin_right, :margin_bottom, :margin_left, :spacing, :pack, :center
|
45
|
+
attr_reader :type, :fill, :margin_width, :margin_height, :margin_top, :margin_right, :margin_bottom, :margin_left, :spacing, :pack, :center
|
46
46
|
|
47
47
|
def initialize(parent, args)
|
48
48
|
super(parent, args)
|
49
|
-
@type = args.first || :horizontal
|
50
|
-
self.pack = true
|
51
49
|
@parent.dom_element.add_class('row-layout')
|
50
|
+
self.type = args.first || :horizontal
|
51
|
+
self.pack = true
|
52
|
+
end
|
53
|
+
|
54
|
+
def type=(value)
|
55
|
+
@type = value
|
52
56
|
@parent.dom_element.add_class(horizontal? ? 'row-layout-horizontal' : 'row-layout-vertical')
|
53
57
|
end
|
54
58
|
|
@@ -75,6 +79,11 @@ module Glimmer
|
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
82
|
+
def fill=(value)
|
83
|
+
# TODO verify this is a correct implementation and interpretation of RowLayout in SWT
|
84
|
+
self.pack(!value)
|
85
|
+
end
|
86
|
+
|
78
87
|
def center=(center_value)
|
79
88
|
@center = center_value
|
80
89
|
# Using padding for width since margin-right isn't getting respected with width 100%
|
@@ -257,9 +257,7 @@ module Glimmer
|
|
257
257
|
@table_editor.minimumWidth = 90
|
258
258
|
@table_editor.minimumHeight = 20
|
259
259
|
if editable?
|
260
|
-
|
261
|
-
edit_table_item(event.table_item, event.column_index)
|
262
|
-
}
|
260
|
+
add_editable_event_listener
|
263
261
|
end
|
264
262
|
end
|
265
263
|
|
@@ -311,6 +309,24 @@ module Glimmer
|
|
311
309
|
end
|
312
310
|
alias editable editable?
|
313
311
|
|
312
|
+
def editable=(value)
|
313
|
+
if value
|
314
|
+
args.push(:editable)
|
315
|
+
dom_element.addClass('editable')
|
316
|
+
add_editable_event_listener
|
317
|
+
else
|
318
|
+
args.delete(:editable)
|
319
|
+
dom_element.removeClass('editable')
|
320
|
+
@editable_on_mouse_up_event_listener.deregister # TODO see why table event listener deregistration is not working
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def add_editable_event_listener
|
325
|
+
@editable_on_mouse_up_event_listener = on_mouse_up { |event|
|
326
|
+
edit_table_item(event.table_item, event.column_index) if editable?
|
327
|
+
}
|
328
|
+
end
|
329
|
+
|
314
330
|
def selection
|
315
331
|
@selection.to_a
|
316
332
|
end
|
@@ -46,9 +46,8 @@ module Glimmer
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def widget_class(keyword)
|
49
|
-
|
50
|
-
class_name_main
|
51
|
-
Glimmer::SWT.const_get(class_name_main.to_sym) rescue Glimmer::SWT.const_get(class_name_alternative.to_sym)
|
49
|
+
class_name_main = "#{keyword.camelcase(:upper)}Proxy"
|
50
|
+
Glimmer::SWT.const_get(class_name_main.to_sym)
|
52
51
|
rescue => e
|
53
52
|
puts "Widget #{keyword} was not found!"
|
54
53
|
nil
|
@@ -309,7 +308,7 @@ module Glimmer
|
|
309
308
|
end
|
310
309
|
|
311
310
|
def content(&block)
|
312
|
-
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::WidgetExpression.new, &block)
|
311
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::WidgetExpression.new, self.class.underscored_widget_name(self), &block)
|
313
312
|
end
|
314
313
|
|
315
314
|
# Subclasses must override with their own mappings
|
@@ -28,15 +28,26 @@ module Glimmer
|
|
28
28
|
module CustomShell
|
29
29
|
include Glimmer::UI::CustomWidget
|
30
30
|
|
31
|
+
module ClassMethods
|
32
|
+
include Glimmer
|
33
|
+
attr_reader :custom_shell
|
34
|
+
|
35
|
+
def launch
|
36
|
+
custom_shell = send(self.name.underscore.gsub('::', '__'))
|
37
|
+
custom_shell.open
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
31
41
|
class << self
|
32
42
|
def included(klass)
|
33
43
|
klass.extend(CustomWidget::ClassMethods)
|
44
|
+
klass.extend(CustomShell::ClassMethods)
|
34
45
|
klass.include(Glimmer)
|
35
46
|
Glimmer::UI::CustomWidget.add_custom_widget_namespaces_for(klass)
|
36
47
|
keyword = klass.name.split(':').last.underscore
|
37
48
|
LocalStorage[keyword] = $LOADED_FEATURES.last
|
38
49
|
end
|
39
|
-
|
50
|
+
|
40
51
|
def request_parameter_string
|
41
52
|
URI.decode_www_form_component(`document.location.href`.match(/\?(.*)$/).to_a[1].to_s)
|
42
53
|
end
|
@@ -59,11 +70,17 @@ module Glimmer
|
|
59
70
|
raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.is_a?(Glimmer::SWT::ShellProxy) || body_root.is_a?(Glimmer::UI::CustomShell)
|
60
71
|
end
|
61
72
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
73
|
+
def open(async: true)
|
74
|
+
work = lambda do
|
75
|
+
body_root.open
|
76
|
+
end
|
77
|
+
if async
|
78
|
+
Glimmer::SWT::DisplayProxy.instance.async_exec(&work)
|
79
|
+
else
|
80
|
+
work.call
|
81
|
+
end
|
66
82
|
end
|
83
|
+
|
67
84
|
|
68
85
|
# DO NOT OVERRIDE. JUST AN ALIAS FOR `#open`. OVERRIDE `#open` INSTEAD.
|
69
86
|
def show
|
@@ -83,6 +83,16 @@ module Glimmer
|
|
83
83
|
@after_body_blocks ||= []
|
84
84
|
@after_body_blocks << block
|
85
85
|
end
|
86
|
+
|
87
|
+
def keyword
|
88
|
+
self.name.underscore.gsub('::', '__')
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns shortcut keyword to use for this custom widget (keyword minus namespace)
|
92
|
+
def shortcut_keyword
|
93
|
+
self.name.underscore.gsub('::', '__').split('__').last
|
94
|
+
end
|
95
|
+
|
86
96
|
end
|
87
97
|
|
88
98
|
class << self
|
@@ -143,7 +153,6 @@ module Glimmer
|
|
143
153
|
def reset_custom_widget_namespaces
|
144
154
|
@custom_widget_namespaces = Set[Object, Glimmer::UI]
|
145
155
|
end
|
146
|
-
|
147
156
|
end
|
148
157
|
# <- end of class methods
|
149
158
|
|
@@ -259,7 +268,7 @@ module Glimmer
|
|
259
268
|
# Otherwise, if a block is passed, it adds it as content to this custom widget
|
260
269
|
def content(&block)
|
261
270
|
if block_given?
|
262
|
-
|
271
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::CustomWidgetExpression.new, self.class.keyword, &block)
|
263
272
|
else
|
264
273
|
@content
|
265
274
|
end
|
@@ -23,12 +23,14 @@ require 'delegate'
|
|
23
23
|
|
24
24
|
module Glimmer
|
25
25
|
module Util
|
26
|
+
# Decorator that provides tracking facilities for Ruby procs, tracking owner (string), invoked_form method name (symbol/string), and called? (boolean)
|
26
27
|
class ProcTracker < DelegateClass(Proc)
|
27
|
-
attr_reader :owner
|
28
|
+
attr_reader :owner, :invoked_from
|
28
29
|
|
29
|
-
def initialize(proc = nil, owner: nil, &block)
|
30
|
+
def initialize(proc = nil, owner: nil, invoked_from: nil, &block)
|
30
31
|
super(proc || block)
|
31
32
|
@owner = owner
|
33
|
+
@invoked_from = invoked_from
|
32
34
|
end
|
33
35
|
|
34
36
|
def call(*args)
|
@@ -41,7 +43,7 @@ module Glimmer
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def respond_to?(method, *args, &block)
|
44
|
-
%w[owner called?].include?(method.to_s) || super(method, *args, &block)
|
46
|
+
%w[owner invoked_from called?].include?(method.to_s) || super(method, *args, &block)
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-opal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: glimmer-dsl-xml
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.2.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.2.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: glimmer-dsl-css
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
47
|
+
version: 1.2.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.
|
54
|
+
version: 1.2.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: opal-async
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -349,7 +349,9 @@ files:
|
|
349
349
|
- lib/glimmer/dsl/opal/radio_group_selection_data_binding_expression.rb
|
350
350
|
- lib/glimmer/dsl/opal/rgb_expression.rb
|
351
351
|
- lib/glimmer/dsl/opal/rgba_expression.rb
|
352
|
+
- lib/glimmer/dsl/opal/shape_expression.rb
|
352
353
|
- lib/glimmer/dsl/opal/shell_expression.rb
|
354
|
+
- lib/glimmer/dsl/opal/shine_data_binding_expression.rb
|
353
355
|
- lib/glimmer/dsl/opal/swt_expression.rb
|
354
356
|
- lib/glimmer/dsl/opal/sync_exec_expression.rb
|
355
357
|
- lib/glimmer/dsl/opal/table_column_expression.rb
|
@@ -429,7 +431,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
429
431
|
- !ruby/object:Gem::Version
|
430
432
|
version: '0'
|
431
433
|
requirements: []
|
432
|
-
rubygems_version: 3.
|
434
|
+
rubygems_version: 3.2.22
|
433
435
|
signing_key:
|
434
436
|
specification_version: 4
|
435
437
|
summary: Glimmer DSL for Opal
|