primer_view_components 0.0.45 → 0.0.49
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +194 -0
- data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_component.d.ts} +0 -0
- data/app/components/primer/{auto_complete_component.js → auto_complete/auto_component.js} +0 -0
- data/app/components/primer/base_component.rb +36 -7
- data/app/components/primer/beta/auto_complete.rb +159 -0
- data/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
- data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.html.erb +0 -0
- data/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
- data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.ts +0 -0
- data/app/components/primer/beta/auto_complete/item.rb +44 -0
- data/app/components/primer/beta/avatar.rb +77 -0
- data/app/components/primer/{avatar_stack_component.html.erb → beta/avatar_stack.html.erb} +0 -0
- data/app/components/primer/beta/avatar_stack.rb +92 -0
- data/app/components/primer/border_box_component.rb +3 -0
- data/app/components/primer/component.rb +9 -1
- data/app/components/primer/details_component.rb +12 -8
- data/app/components/primer/image_crop.html.erb +4 -4
- data/app/components/primer/image_crop.rb +1 -1
- data/app/components/primer/markdown.rb +9 -9
- data/app/components/primer/menu_component.rb +7 -3
- data/app/components/primer/navigation/tab_component.rb +34 -6
- data/app/components/primer/popover_component.rb +6 -3
- data/app/components/primer/primer.d.ts +1 -1
- data/app/components/primer/primer.js +1 -1
- data/app/components/primer/primer.ts +1 -1
- data/app/components/primer/tab_nav_component.rb +9 -6
- data/app/components/primer/timeline_item_component.rb +2 -2
- data/app/components/primer/tooltip.rb +1 -1
- data/app/components/primer/truncate.rb +6 -1
- data/app/components/primer/underline_nav_component.rb +13 -6
- data/{app/lib → lib}/primer/classify.rb +12 -39
- data/{app/lib → lib}/primer/classify/cache.rb +6 -20
- data/{app/lib → lib}/primer/classify/flex.rb +0 -0
- data/{app/lib → lib}/primer/classify/functional_background_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/functional_border_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/functional_colors.rb +0 -0
- data/{app/lib → lib}/primer/classify/functional_text_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/grid.rb +0 -0
- data/{app/lib → lib}/primer/classify/utilities.rb +54 -22
- data/{app/lib → lib}/primer/classify/utilities.yml +124 -0
- data/lib/primer/view_components.rb +35 -6
- data/lib/primer/view_components/constants.rb +55 -0
- data/lib/primer/view_components/linters/argument_mappers/base.rb +39 -0
- data/lib/primer/view_components/linters/argument_mappers/button.rb +35 -44
- data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +25 -0
- data/lib/primer/view_components/linters/argument_mappers/label.rb +56 -0
- data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +1 -2
- data/lib/primer/view_components/linters/autocorrectable.rb +30 -0
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -23
- data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +21 -0
- data/lib/primer/view_components/linters/helpers.rb +56 -38
- data/lib/primer/view_components/linters/label_component_migration_counter.rb +25 -0
- data/lib/primer/view_components/statuses.rb +14 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/config/default.yml +12 -0
- data/lib/rubocop/cop/primer.rb +4 -0
- data/lib/rubocop/cop/primer/no_tag_memoize.rb +42 -0
- data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +75 -0
- data/lib/tasks/constants.rake +12 -0
- data/lib/tasks/docs.rake +89 -34
- data/lib/tasks/utilities.rake +9 -11
- data/lib/yard/docs_helper.rb +12 -3
- data/static/arguments.yml +977 -0
- data/static/assets/view-components.svg +18 -0
- data/static/classes.yml +174 -0
- data/static/constants.json +628 -0
- data/static/statuses.json +5 -5
- metadata +44 -27
- data/app/components/primer/auto_complete.rb +0 -156
- data/app/components/primer/auto_complete/item.rb +0 -42
- data/app/components/primer/avatar_component.rb +0 -75
- data/app/components/primer/avatar_stack_component.rb +0 -84
- data/app/components/primer/details_menu_component.d.ts +0 -1
- data/app/components/primer/details_menu_component.js +0 -1
@@ -1,4 +1,71 @@
|
|
1
1
|
---
|
2
|
+
:animation:
|
3
|
+
:fade_in:
|
4
|
+
- anim-fade-in
|
5
|
+
:fade_out:
|
6
|
+
- anim-fade-out
|
7
|
+
:fade_up:
|
8
|
+
- anim-fade-up
|
9
|
+
:fade_down:
|
10
|
+
- anim-fade-down
|
11
|
+
:grow_x:
|
12
|
+
- anim-grow-x
|
13
|
+
:shrink_x:
|
14
|
+
- anim-shrink-x
|
15
|
+
:scale_in:
|
16
|
+
- anim-scale-in
|
17
|
+
:pulse:
|
18
|
+
- anim-pulse
|
19
|
+
:pulse_in:
|
20
|
+
- anim-pulse-in
|
21
|
+
:hover_grow:
|
22
|
+
- anim-hover-grow
|
23
|
+
:rotate:
|
24
|
+
- anim-rotate
|
25
|
+
:position:
|
26
|
+
:static:
|
27
|
+
- position-static
|
28
|
+
- position-sm-static
|
29
|
+
- position-md-static
|
30
|
+
- position-lg-static
|
31
|
+
- position-xl-static
|
32
|
+
:relative:
|
33
|
+
- position-relative
|
34
|
+
- position-sm-relative
|
35
|
+
- position-md-relative
|
36
|
+
- position-lg-relative
|
37
|
+
- position-xl-relative
|
38
|
+
:absolute:
|
39
|
+
- position-absolute
|
40
|
+
- position-sm-absolute
|
41
|
+
- position-md-absolute
|
42
|
+
- position-lg-absolute
|
43
|
+
- position-xl-absolute
|
44
|
+
:fixed:
|
45
|
+
- position-fixed
|
46
|
+
- position-sm-fixed
|
47
|
+
- position-md-fixed
|
48
|
+
- position-lg-fixed
|
49
|
+
- position-xl-fixed
|
50
|
+
:sticky:
|
51
|
+
- position-sticky
|
52
|
+
- position-sm-sticky
|
53
|
+
- position-md-sticky
|
54
|
+
- position-lg-sticky
|
55
|
+
- position-xl-sticky
|
56
|
+
:vertical_align:
|
57
|
+
:middle:
|
58
|
+
- v-align-middle
|
59
|
+
:top:
|
60
|
+
- v-align-top
|
61
|
+
:bottom:
|
62
|
+
- v-align-bottom
|
63
|
+
:text_top:
|
64
|
+
- v-align-text-top
|
65
|
+
:text_bottom:
|
66
|
+
- v-align-text-bottom
|
67
|
+
:baseline:
|
68
|
+
- v-align-baseline
|
2
69
|
:float:
|
3
70
|
:left:
|
4
71
|
- float-left
|
@@ -1136,6 +1203,63 @@
|
|
1136
1203
|
- py-md-12
|
1137
1204
|
- py-lg-12
|
1138
1205
|
- py-xl-12
|
1206
|
+
:word_break:
|
1207
|
+
:break_all:
|
1208
|
+
- wb-break-all
|
1209
|
+
:display:
|
1210
|
+
:block:
|
1211
|
+
- d-block
|
1212
|
+
- d-sm-block
|
1213
|
+
- d-md-block
|
1214
|
+
- d-lg-block
|
1215
|
+
- d-xl-block
|
1216
|
+
:flex:
|
1217
|
+
- d-flex
|
1218
|
+
- d-sm-flex
|
1219
|
+
- d-md-flex
|
1220
|
+
- d-lg-flex
|
1221
|
+
- d-xl-flex
|
1222
|
+
:inline:
|
1223
|
+
- d-inline
|
1224
|
+
- d-sm-inline
|
1225
|
+
- d-md-inline
|
1226
|
+
- d-lg-inline
|
1227
|
+
- d-xl-inline
|
1228
|
+
:inline_block:
|
1229
|
+
- d-inline-block
|
1230
|
+
- d-sm-inline-block
|
1231
|
+
- d-md-inline-block
|
1232
|
+
- d-lg-inline-block
|
1233
|
+
- d-xl-inline-block
|
1234
|
+
:inline_flex:
|
1235
|
+
- d-inline-flex
|
1236
|
+
- d-sm-inline-flex
|
1237
|
+
- d-md-inline-flex
|
1238
|
+
- d-lg-inline-flex
|
1239
|
+
- d-xl-inline-flex
|
1240
|
+
:none:
|
1241
|
+
- d-none
|
1242
|
+
- d-sm-none
|
1243
|
+
- d-md-none
|
1244
|
+
- d-lg-none
|
1245
|
+
- d-xl-none
|
1246
|
+
:table:
|
1247
|
+
- d-table
|
1248
|
+
- d-sm-table
|
1249
|
+
- d-md-table
|
1250
|
+
- d-lg-table
|
1251
|
+
- d-xl-table
|
1252
|
+
:table_cell:
|
1253
|
+
- d-table-cell
|
1254
|
+
- d-sm-table-cell
|
1255
|
+
- d-md-table-cell
|
1256
|
+
- d-lg-table-cell
|
1257
|
+
- d-xl-table-cell
|
1258
|
+
:visibility:
|
1259
|
+
:hidden:
|
1260
|
+
- v-hidden
|
1261
|
+
:visible:
|
1262
|
+
- v-visible
|
1139
1263
|
:hide:
|
1140
1264
|
:sm:
|
1141
1265
|
- hide-sm
|
@@ -1,27 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "primer/classify"
|
3
4
|
require "primer/view_components/version"
|
4
5
|
require "primer/view_components/engine"
|
5
6
|
|
6
7
|
module Primer
|
7
8
|
# :nodoc:
|
8
9
|
module ViewComponents
|
9
|
-
|
10
|
+
DEFAULT_STATIC_PATH = File.expand_path("static")
|
10
11
|
DEFAULT_STATUS_FILE_NAME = "statuses.json"
|
12
|
+
DEFAULT_CONSTANTS_FILE_NAME = "constants.json"
|
11
13
|
|
12
14
|
# generate_statuses returns a hash mapping component name to
|
13
15
|
# the component's status sorted alphabetically by the component name.
|
14
16
|
def self.generate_statuses
|
15
|
-
|
17
|
+
Primer::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
|
16
18
|
mem[component.to_s] = component.status.to_s
|
17
19
|
end
|
18
|
-
|
19
|
-
statuses.sort_by { |k, _v| k }.to_h
|
20
20
|
end
|
21
21
|
|
22
22
|
# dump_statuses generates the status hash and then serializes
|
23
23
|
# it as json at the given path
|
24
|
-
def self.dump_statuses(path:
|
24
|
+
def self.dump_statuses(path: DEFAULT_STATIC_PATH)
|
25
25
|
require "json"
|
26
26
|
|
27
27
|
statuses = generate_statuses
|
@@ -34,8 +34,37 @@ module Primer
|
|
34
34
|
|
35
35
|
# read_statuses returns a JSON string matching the output of
|
36
36
|
# generate_statuses
|
37
|
-
def self.read_statuses(path:
|
37
|
+
def self.read_statuses(path: DEFAULT_STATIC_PATH)
|
38
38
|
File.read(File.join(path, DEFAULT_STATUS_FILE_NAME))
|
39
39
|
end
|
40
|
+
|
41
|
+
# generate_constants returns a hash mapping component name to
|
42
|
+
# all of its constants.
|
43
|
+
def self.generate_constants
|
44
|
+
Primer::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
|
45
|
+
mem[component.to_s] = component.constants(false).sort.each_with_object({}) do |constant, h|
|
46
|
+
h[constant] = component.const_get(constant)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# dump_constants generates the constants hash and then serializes
|
52
|
+
# it as json at the given path
|
53
|
+
def self.dump_constants(path: DEFAULT_STATIC_PATH)
|
54
|
+
require "json"
|
55
|
+
|
56
|
+
constants = generate_constants
|
57
|
+
|
58
|
+
File.open(File.join(path, DEFAULT_CONSTANTS_FILE_NAME), "w") do |f|
|
59
|
+
f.write(JSON.pretty_generate(constants))
|
60
|
+
f.write($INPUT_RECORD_SEPARATOR)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# read_constants returns a JSON string matching the output of
|
65
|
+
# generate_constants
|
66
|
+
def self.read_constants(path: DEFAULT_STATIC_PATH)
|
67
|
+
File.read(File.join(path, DEFAULT_CONSTANTS_FILE_NAME))
|
68
|
+
end
|
40
69
|
end
|
41
70
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Primer
|
6
|
+
module ViewComponents
|
7
|
+
# A module for constants that are used in the view components.
|
8
|
+
class Constants
|
9
|
+
CONSTANTS = JSON.parse(
|
10
|
+
File.read(
|
11
|
+
File.join(File.dirname(__FILE__), "../../../static/constants.json")
|
12
|
+
)
|
13
|
+
).freeze
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def get(component:, constant:, invert: true, symbolize: false)
|
17
|
+
values = CONSTANTS.dig(component, constant)
|
18
|
+
|
19
|
+
case values
|
20
|
+
when Hash
|
21
|
+
format_hash(values, invert, symbolize)
|
22
|
+
when Array
|
23
|
+
format_array(values, symbolize)
|
24
|
+
else
|
25
|
+
values
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def format_hash(values, invert, symbolize)
|
32
|
+
val = values.invert if invert
|
33
|
+
# remove defaults
|
34
|
+
val = val.except("", nil)
|
35
|
+
|
36
|
+
return val.transform_values { |v| symbolize_value(v) } if symbolize
|
37
|
+
|
38
|
+
val
|
39
|
+
end
|
40
|
+
|
41
|
+
def format_array(values, symbolize)
|
42
|
+
val = values.select(&:present?)
|
43
|
+
|
44
|
+
return val.map { |v| symbolize_value(v) } if symbolize
|
45
|
+
|
46
|
+
val
|
47
|
+
end
|
48
|
+
|
49
|
+
def symbolize_value(value)
|
50
|
+
":#{value}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "conversion_error"
|
4
|
+
require_relative "system_arguments"
|
5
|
+
require "primer/view_components/constants"
|
6
|
+
|
7
|
+
module ERBLint
|
8
|
+
module Linters
|
9
|
+
module ArgumentMappers
|
10
|
+
# Provides the base interface to implement an `ArgumentMapper`.
|
11
|
+
# Override attribute_to_args in a child class to customize its mapping behavior.
|
12
|
+
class Base
|
13
|
+
DEFAULT_TAG = nil
|
14
|
+
|
15
|
+
def initialize(tag)
|
16
|
+
@tag = tag
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
to_args.map { |k, v| "#{k}: #{v}" }.join(", ")
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_args
|
24
|
+
args = {}
|
25
|
+
|
26
|
+
args[:tag] = ":#{@tag.name}" unless self.class::DEFAULT_TAG.nil? || @tag.name == self.class::DEFAULT_TAG
|
27
|
+
|
28
|
+
@tag.attributes.each do |attribute|
|
29
|
+
args.merge!(attribute_to_args(attribute))
|
30
|
+
end
|
31
|
+
|
32
|
+
args
|
33
|
+
end
|
34
|
+
|
35
|
+
def attribute_to_args(attribute); end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,62 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
4
|
-
require_relative "system_arguments"
|
3
|
+
require_relative "base"
|
5
4
|
|
6
5
|
module ERBLint
|
7
6
|
module Linters
|
8
7
|
module ArgumentMappers
|
9
8
|
# Maps classes in a button element to arguments for the Button component.
|
10
|
-
class Button
|
11
|
-
|
12
|
-
"btn-primary" => ":primary",
|
13
|
-
"btn-danger" => ":danger",
|
14
|
-
"btn-outline" => ":outline",
|
15
|
-
"btn-invisible" => ":invisible",
|
16
|
-
"btn-link" => ":link"
|
17
|
-
}.freeze
|
9
|
+
class Button < Base
|
10
|
+
require "pry"
|
18
11
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
SCHEME_MAPPINGS = Primer::ViewComponents::Constants.get(
|
13
|
+
component: "Primer::ButtonComponent",
|
14
|
+
constant: "SCHEME_MAPPINGS",
|
15
|
+
symbolize: true
|
16
|
+
).freeze
|
23
17
|
|
24
|
-
|
18
|
+
VARIANT_MAPPINGS = Primer::ViewComponents::Constants.get(
|
19
|
+
component: "Primer::ButtonComponent",
|
20
|
+
constant: "VARIANT_MAPPINGS",
|
21
|
+
symbolize: true
|
22
|
+
).freeze
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def to_args
|
35
|
-
args = {}
|
24
|
+
TYPE_OPTIONS = Primer::ViewComponents::Constants.get(
|
25
|
+
component: "Primer::BaseButton",
|
26
|
+
constant: "TYPE_OPTIONS"
|
27
|
+
).freeze
|
28
|
+
DEFAULT_TAG = Primer::ViewComponents::Constants.get(
|
29
|
+
component: "Primer::BaseButton",
|
30
|
+
constant: "DEFAULT_TAG"
|
31
|
+
).freeze
|
36
32
|
|
37
|
-
|
33
|
+
def attribute_to_args(attribute)
|
34
|
+
attr_name = attribute.name
|
38
35
|
|
39
|
-
|
40
|
-
|
36
|
+
if attr_name == "class"
|
37
|
+
classes_to_args(attribute)
|
38
|
+
elsif attr_name == "disabled"
|
39
|
+
{ disabled: true }
|
40
|
+
elsif attr_name == "type"
|
41
|
+
# button is the default type, so we don't need to do anything.
|
42
|
+
return {} if attribute.value == "button"
|
41
43
|
|
42
|
-
|
43
|
-
args = args.merge(classes_to_args(attribute))
|
44
|
-
elsif attr_name == "disabled"
|
45
|
-
args[:disabled] = true
|
46
|
-
elsif attr_name == "type"
|
47
|
-
# button is the default type, so we don't need to do anything.
|
48
|
-
next if attribute.value == "button"
|
44
|
+
raise ConversionError, "Button component does not support type \"#{attribute.value}\"" unless TYPE_OPTIONS.include?(attribute.value)
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
# Assume the attribute is a system argument.
|
55
|
-
args.merge!(SystemArguments.new(attribute).to_args)
|
56
|
-
end
|
46
|
+
{ type: ":#{attribute.value}" }
|
47
|
+
else
|
48
|
+
# Assume the attribute is a system argument.
|
49
|
+
SystemArguments.new(attribute).to_args
|
57
50
|
end
|
58
|
-
|
59
|
-
args
|
60
51
|
end
|
61
52
|
|
62
53
|
def classes_to_args(classes)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module ERBLint
|
6
|
+
module Linters
|
7
|
+
module ArgumentMappers
|
8
|
+
# Maps attributes in the clipboard-copy element to arguments for the ClipboardCopy component.
|
9
|
+
class ClipboardCopy < Base
|
10
|
+
DEFAULT_TAG = "clipboard-copy"
|
11
|
+
|
12
|
+
def attribute_to_args(attribute)
|
13
|
+
attr_name = attribute.name
|
14
|
+
|
15
|
+
if attr_name == "value"
|
16
|
+
{ value: attribute.value.to_json }
|
17
|
+
else
|
18
|
+
# Assume the attribute is a system argument.
|
19
|
+
SystemArguments.new(attribute).to_args
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module ERBLint
|
6
|
+
module Linters
|
7
|
+
module ArgumentMappers
|
8
|
+
# Maps classes in a label element to arguments for the Label component.
|
9
|
+
class Label < Base
|
10
|
+
SCHEME_MAPPINGS = Primer::ViewComponents::Constants.get(
|
11
|
+
component: "Primer::LabelComponent",
|
12
|
+
constant: "SCHEME_MAPPINGS",
|
13
|
+
symbolize: true
|
14
|
+
).freeze
|
15
|
+
|
16
|
+
VARIANT_MAPPINGS = Primer::ViewComponents::Constants.get(
|
17
|
+
component: "Primer::LabelComponent",
|
18
|
+
constant: "VARIANT_MAPPINGS",
|
19
|
+
symbolize: true
|
20
|
+
).freeze
|
21
|
+
|
22
|
+
DEFAULT_TAG = Primer::ViewComponents::Constants.get(
|
23
|
+
component: "Primer::LabelComponent",
|
24
|
+
constant: "DEFAULT_TAG"
|
25
|
+
).freeze
|
26
|
+
|
27
|
+
def attribute_to_args(attribute)
|
28
|
+
attr_name = attribute.name
|
29
|
+
|
30
|
+
if attr_name == "class"
|
31
|
+
classes_to_args(attribute)
|
32
|
+
elsif attr_name == "title"
|
33
|
+
{ title: attribute.value.to_json }
|
34
|
+
else
|
35
|
+
# Assume the attribute is a system argument.
|
36
|
+
SystemArguments.new(attribute).to_args
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def classes_to_args(classes)
|
41
|
+
classes.value.split(" ").each_with_object({}) do |class_name, acc|
|
42
|
+
next if class_name == "Label"
|
43
|
+
|
44
|
+
if SCHEME_MAPPINGS[class_name] && acc[:scheme].nil?
|
45
|
+
acc[:scheme] = SCHEME_MAPPINGS[class_name]
|
46
|
+
elsif VARIANT_MAPPINGS[class_name] && acc[:variant].nil?
|
47
|
+
acc[:variant] = VARIANT_MAPPINGS[class_name]
|
48
|
+
else
|
49
|
+
raise ConversionError, "Cannot convert class \"#{class_name}\""
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|