custom_elements_manifest_parser 0.1.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +66 -0
- data/LICENSE.txt +21 -0
- data/README.md +244 -0
- data/Rakefile +23 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/custom_elements_manifest_parser.gemspec +43 -0
- data/lib/custom_elements_manifest_parser/base_struct.rb +10 -0
- data/lib/custom_elements_manifest_parser/data_types/attribute.rb +57 -0
- data/lib/custom_elements_manifest_parser/data_types/css_custom_property.rb +47 -0
- data/lib/custom_elements_manifest_parser/data_types/css_part.rb +32 -0
- data/lib/custom_elements_manifest_parser/data_types/demo.rb +29 -0
- data/lib/custom_elements_manifest_parser/data_types/event.rb +40 -0
- data/lib/custom_elements_manifest_parser/data_types/function_return_type.rb +25 -0
- data/lib/custom_elements_manifest_parser/data_types/parameter.rb +33 -0
- data/lib/custom_elements_manifest_parser/data_types/reference.rb +36 -0
- data/lib/custom_elements_manifest_parser/data_types/resolve_initializer.rb +16 -0
- data/lib/custom_elements_manifest_parser/data_types/slot.rb +31 -0
- data/lib/custom_elements_manifest_parser/data_types/source_reference.rb +17 -0
- data/lib/custom_elements_manifest_parser/data_types/type.rb +34 -0
- data/lib/custom_elements_manifest_parser/data_types/type_reference.rb +22 -0
- data/lib/custom_elements_manifest_parser/nodes/class_declaration.rb +39 -0
- data/lib/custom_elements_manifest_parser/nodes/class_field.rb +50 -0
- data/lib/custom_elements_manifest_parser/nodes/class_method.rb +55 -0
- data/lib/custom_elements_manifest_parser/nodes/custom_element_export.rb +52 -0
- data/lib/custom_elements_manifest_parser/nodes/custom_element_field.rb +23 -0
- data/lib/custom_elements_manifest_parser/nodes/function_declaration.rb +39 -0
- data/lib/custom_elements_manifest_parser/nodes/javascript_export.rb +59 -0
- data/lib/custom_elements_manifest_parser/nodes/javascript_module.rb +58 -0
- data/lib/custom_elements_manifest_parser/nodes/manifest.rb +36 -0
- data/lib/custom_elements_manifest_parser/nodes/mixin_declaration.rb +93 -0
- data/lib/custom_elements_manifest_parser/nodes/variable_declaration.rb +41 -0
- data/lib/custom_elements_manifest_parser/parser.rb +111 -0
- data/lib/custom_elements_manifest_parser/structs/class_like_struct.rb +92 -0
- data/lib/custom_elements_manifest_parser/structs/custom_element_like_struct.rb +64 -0
- data/lib/custom_elements_manifest_parser/structs/declarable_node_struct.rb +19 -0
- data/lib/custom_elements_manifest_parser/structs/function_like_struct.rb +40 -0
- data/lib/custom_elements_manifest_parser/structs/property_like_struct.rb +47 -0
- data/lib/custom_elements_manifest_parser/types.rb +13 -0
- data/lib/custom_elements_manifest_parser/version.rb +5 -0
- data/lib/custom_elements_manifest_parser.rb +12 -0
- data/sig/custom_elements_manifest_parser.rbs +4 -0
- metadata +133 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative "../base_struct.rb"
|
2
|
+
require_relative "../types.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
module Nodes
|
6
|
+
# Document a JS module
|
7
|
+
class JavaScriptModule < BaseStruct
|
8
|
+
# @!attribute kind
|
9
|
+
# @return ["javascript-module"]
|
10
|
+
attribute :kind, Types.Value("javascript-module")
|
11
|
+
|
12
|
+
# @return ["javascript-module"]
|
13
|
+
def self.kind; "javascript-module"; end
|
14
|
+
|
15
|
+
# @!attribute path
|
16
|
+
# @return [String] -
|
17
|
+
# Path to the javascript file needed to be imported.
|
18
|
+
# (not the path for example to a typescript file.)
|
19
|
+
attribute :path, Types::Strict::String
|
20
|
+
|
21
|
+
# @!attribute summary
|
22
|
+
# @return [String, nil] - A markdown summary suitable for display in a listing.
|
23
|
+
attribute :summary, Types::Strict::String.optional.meta(required: false)
|
24
|
+
|
25
|
+
# @!attribute declarations
|
26
|
+
# @return[nil, Array<
|
27
|
+
# Nodes::ClassDeclaration,
|
28
|
+
# Nodes::FunctionDeclaration,
|
29
|
+
# Nodes::MixinDeclaration,
|
30
|
+
# Nodes::VariableDeclaration>] -
|
31
|
+
# The declarations of a module.
|
32
|
+
# For documentation purposes, all declarations that are reachable from
|
33
|
+
# exports should be described here. Ie, functions and objects that may be
|
34
|
+
# properties of exported objects, or passed as arguments to functions.
|
35
|
+
attribute :declarations, Types::Strict::Array.optional.meta(required: false)
|
36
|
+
|
37
|
+
# @!attribute exports
|
38
|
+
# @return [nil, Array<CustomElementExport, JavaScriptExport>] -
|
39
|
+
# The exports of a module. This includes JavaScript exports and
|
40
|
+
# custom element definitions.
|
41
|
+
attribute :exports, Types::Strict::Array.optional.meta(required: false)
|
42
|
+
|
43
|
+
# @!attribute deprecated
|
44
|
+
# @return [String, nil, Boolean] -
|
45
|
+
# Whether the module is deprecated.
|
46
|
+
# If the value is a string, it's the reason for the deprecation.
|
47
|
+
attribute :deprecated, Types::Strict::String.optional | Types::Strict::Bool.optional.meta(required: false)
|
48
|
+
|
49
|
+
def visit(parser:)
|
50
|
+
hash = {}
|
51
|
+
hash[:declarations] = declarations.map { |declaration| parser.visit_node(declaration.merge(parent_module: self)) } unless declarations.nil?
|
52
|
+
hash[:exports] = exports.map { |export| parser.visit_node(export.merge(parent_module: self)) } unless exports.nil?
|
53
|
+
|
54
|
+
new(hash)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative "../base_struct.rb"
|
2
|
+
require_relative "../types.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
module Nodes
|
6
|
+
# top level of a custom elements manifest. This technically isn't a "ParseableNode". its a top level "root" of a custom-elements.json.
|
7
|
+
class Manifest < BaseStruct
|
8
|
+
# @!attribute schemaVersion
|
9
|
+
# @return [String] - Version of the schema.
|
10
|
+
attribute :schemaVersion, Types::Strict::String
|
11
|
+
|
12
|
+
# @!attribute modules
|
13
|
+
# @return [Array<Nodes::JavaScriptModule>] - An array of the modules this package contains..
|
14
|
+
attribute :modules, Types::Strict::Array
|
15
|
+
|
16
|
+
# @!attribute readme
|
17
|
+
# @return [String, nil] - The Markdown to use for the main readme of this package.
|
18
|
+
attribute :readme, Types::Strict::String.optional.meta(required: false)
|
19
|
+
|
20
|
+
# @!attribute deprecated
|
21
|
+
# @return [String, Boolean, nil] - if nil or false, not deprecated. If true, deprecated. If string, why it's deprecated.
|
22
|
+
attribute :deprecated, Types::Bool.optional | Types::String.optional.meta(required: false)
|
23
|
+
|
24
|
+
def visit(parser:)
|
25
|
+
hash = {}
|
26
|
+
|
27
|
+
hash[:modules] = modules.map do |mod|
|
28
|
+
parser.visit_node(mod)
|
29
|
+
end
|
30
|
+
|
31
|
+
hash[:modules]
|
32
|
+
new(hash)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require_relative "../structs/function_like_struct.rb"
|
2
|
+
require_relative "../structs/declarable_node_struct.rb"
|
3
|
+
require_relative "../structs/custom_element_like_struct.rb"
|
4
|
+
|
5
|
+
require_relative "../types.rb"
|
6
|
+
require_relative "../base_struct.rb"
|
7
|
+
|
8
|
+
module CustomElementsManifestParser
|
9
|
+
module Nodes
|
10
|
+
# A description of a class mixin.
|
11
|
+
#
|
12
|
+
# Mixins are functions which generate a new subclass of a given superclass.
|
13
|
+
# This interfaces describes the class and custom element features that
|
14
|
+
# are added by the mixin. As such, it extends the CustomElement interface and
|
15
|
+
# ClassLike interface.
|
16
|
+
#
|
17
|
+
# Since mixins are functions, it also extends the FunctionLike interface. This
|
18
|
+
# means a mixin is callable, and has parameters and a return type.
|
19
|
+
#
|
20
|
+
# The return type is often hard or impossible to accurately describe in type
|
21
|
+
# systems like TypeScript. It requires generics and an `extends` operator
|
22
|
+
# that TypeScript lacks. Therefore it's recommended that the return type is
|
23
|
+
# left empty. The most common form of a mixin function takes a single
|
24
|
+
# argument, so consumers of this interface should assume that the return type
|
25
|
+
# is the single argument subclassed by this declaration.
|
26
|
+
#
|
27
|
+
# A mixin should not have a superclass. If a mixins composes other mixins,
|
28
|
+
# they should be listed in the `mixins` field.
|
29
|
+
#
|
30
|
+
# See <https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/>
|
31
|
+
# for more information on the classmixin pattern in JavaScript.
|
32
|
+
#
|
33
|
+
# This JavaScript mixin declaration:
|
34
|
+
# ```javascript
|
35
|
+
# const MyMixin = (base) => class extends base {
|
36
|
+
# foo() { ... }
|
37
|
+
# }
|
38
|
+
# ```
|
39
|
+
#
|
40
|
+
# Is described by this JSON:
|
41
|
+
# ```json
|
42
|
+
# {
|
43
|
+
# "kind": "mixin",
|
44
|
+
# "name": "MyMixin",
|
45
|
+
# "parameters": [
|
46
|
+
# {
|
47
|
+
# "name": "base",
|
48
|
+
# }
|
49
|
+
# ],
|
50
|
+
# "members": [
|
51
|
+
# {
|
52
|
+
# "kind": "method",
|
53
|
+
# "name": "foo",
|
54
|
+
# }
|
55
|
+
# ]
|
56
|
+
# }
|
57
|
+
# ```
|
58
|
+
class MixinDeclaration < BaseStruct
|
59
|
+
# @!parse Structs::CustomElementLikeStruct
|
60
|
+
attributes_from Structs::CustomElementLikeStruct
|
61
|
+
|
62
|
+
# @!parse Structs::FunctionLikeStruct
|
63
|
+
Structs::FunctionLikeStruct.schema.each do |attr|
|
64
|
+
names = Structs::CustomElementLikeStruct.schema.keys.map { |obj| obj.name }
|
65
|
+
|
66
|
+
next if names.include?(attr.name)
|
67
|
+
|
68
|
+
attribute attr.name, attr.type
|
69
|
+
end
|
70
|
+
|
71
|
+
attributes_from Structs::DeclarableNodeStruct
|
72
|
+
|
73
|
+
# @!attribute kind
|
74
|
+
# @return ["mixin"]
|
75
|
+
attribute :kind, Types.Value("mixin")
|
76
|
+
|
77
|
+
# @return ["mixin"]
|
78
|
+
def self.kind; 'mixin'; end
|
79
|
+
|
80
|
+
def visit(parser:)
|
81
|
+
hash = {}
|
82
|
+
|
83
|
+
hash = hash.merge(
|
84
|
+
# Structs::FunctionLikeStruct.build_hash(parser: parser, struct: self),
|
85
|
+
Structs::CustomElementLikeStruct.build_hash(parser: parser, struct: self),
|
86
|
+
Structs::DeclarableNodeStruct.build_hash(parser: parser, struct: self),
|
87
|
+
)
|
88
|
+
|
89
|
+
new(hash)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative "../structs/declarable_node_struct.rb"
|
2
|
+
require_relative "../structs/property_like_struct.rb"
|
3
|
+
|
4
|
+
require_relative "../base_struct.rb"
|
5
|
+
require_relative "../types.rb"
|
6
|
+
|
7
|
+
module CustomElementsManifestParser
|
8
|
+
module Nodes
|
9
|
+
# Documents a variable
|
10
|
+
class VariableDeclaration < BaseStruct
|
11
|
+
# @!parse include Structs::DeclarableNodeStruct
|
12
|
+
attributes_from Structs::DeclarableNodeStruct
|
13
|
+
|
14
|
+
# @!parse include Structs::PropertyLikeStruct
|
15
|
+
attributes_from Structs::PropertyLikeStruct
|
16
|
+
|
17
|
+
# @return ["variable"]
|
18
|
+
def self.kind; "variable"; end
|
19
|
+
|
20
|
+
# @!attribute kind
|
21
|
+
# @return ["variable"]
|
22
|
+
attribute :kind, Types.Value("variable")
|
23
|
+
|
24
|
+
# @!attribute source
|
25
|
+
# @return [Nodes::SourceReference, nil]
|
26
|
+
attribute :source, Types::Nominal::Any.optional.meta(required: false)
|
27
|
+
|
28
|
+
def visit(parser:)
|
29
|
+
hash = {}
|
30
|
+
hash[:source] = parser.data_types[:source].new(source).visit(parser: parser) unless source.nil?
|
31
|
+
|
32
|
+
hash = hash.merge(
|
33
|
+
Structs::DeclarableNodeStruct.build_hash(parser: parser, struct: self),
|
34
|
+
Structs::PropertyLikeStruct.build_hash(parser: parser, struct: self),
|
35
|
+
)
|
36
|
+
|
37
|
+
new(hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require_relative "./base_struct.rb"
|
2
|
+
require_relative "./types.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
Dir["#{__dir__}/**/*.rb"].each { |file| require_relative file if file != __FILE__ }
|
6
|
+
|
7
|
+
# Top level interface that users will interact with when reading custom elements JSON.
|
8
|
+
# @example
|
9
|
+
# ::CustomElementsManifestParser::Parser.new(JSON.parse("custom-elements.json"))
|
10
|
+
#
|
11
|
+
class Parser
|
12
|
+
attr_accessor :visitable_nodes, :manifest, :data_types
|
13
|
+
|
14
|
+
# @param hash [Hash{String => any}]
|
15
|
+
def initialize(hash)
|
16
|
+
type_check = Types::Strict::Hash
|
17
|
+
type_check[hash]
|
18
|
+
|
19
|
+
@visitable_nodes = {}
|
20
|
+
@visitable_nodes[Nodes::JavaScriptModule.kind] = Nodes::JavaScriptModule
|
21
|
+
@visitable_nodes[Nodes::CustomElementField.kind] = Nodes::CustomElementField
|
22
|
+
@visitable_nodes[Nodes::JavaScriptExport.kind] = Nodes::JavaScriptExport
|
23
|
+
@visitable_nodes[Nodes::CustomElementExport.kind] = Nodes::CustomElementExport
|
24
|
+
@visitable_nodes[Nodes::ClassMethod.kind] = Nodes::ClassMethod
|
25
|
+
|
26
|
+
# Top level declarations
|
27
|
+
@visitable_nodes[Nodes::ClassDeclaration.kind] = Nodes::ClassDeclaration
|
28
|
+
@visitable_nodes[Nodes::FunctionDeclaration.kind] = Nodes::FunctionDeclaration
|
29
|
+
@visitable_nodes[Nodes::VariableDeclaration.kind] = Nodes::VariableDeclaration
|
30
|
+
|
31
|
+
## This is equivalent to MixinDeclaration | CustomElementDeclaration | CustomElementMixinDeclaration;
|
32
|
+
@visitable_nodes[Nodes::MixinDeclaration.kind] = Nodes::MixinDeclaration
|
33
|
+
|
34
|
+
# data_types are different from @visitable_nodes. They serialize data, but do not represent a physical node in the Custom Elements JSON.
|
35
|
+
@data_types = {
|
36
|
+
attribute: DataTypes::Attribute,
|
37
|
+
css_part: DataTypes::CssPart,
|
38
|
+
css_custom_property: DataTypes::CssCustomProperty,
|
39
|
+
demo: DataTypes::Demo,
|
40
|
+
declaration: DataTypes::Reference,
|
41
|
+
event: DataTypes::Event,
|
42
|
+
function_return_type: DataTypes::FunctionReturnType,
|
43
|
+
mixin: DataTypes::Reference,
|
44
|
+
parameter: DataTypes::Parameter,
|
45
|
+
superclass: DataTypes::Reference,
|
46
|
+
source: DataTypes::SourceReference,
|
47
|
+
slot: DataTypes::Slot,
|
48
|
+
type: DataTypes::Type,
|
49
|
+
type_reference: DataTypes::TypeReference,
|
50
|
+
inheritedFrom: DataTypes::Reference,
|
51
|
+
resolve_initializer: DataTypes::ResolveInitializer,
|
52
|
+
reference: DataTypes::Reference
|
53
|
+
}
|
54
|
+
|
55
|
+
# @return [Nodes::Manifest]
|
56
|
+
@manifest = Nodes::Manifest.new(hash)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Builds the fully parsed tree
|
60
|
+
# @return [Parser]
|
61
|
+
def parse
|
62
|
+
@manifest = manifest.visit(parser: self)
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
# def array_fields
|
67
|
+
# [
|
68
|
+
# "declarations",
|
69
|
+
# "exports",
|
70
|
+
# "members",
|
71
|
+
# "mixins",
|
72
|
+
# "attributes",
|
73
|
+
# "events",
|
74
|
+
# "slots",
|
75
|
+
# "cssParts",
|
76
|
+
# "cssProperties",
|
77
|
+
# "demos",
|
78
|
+
# "parameters",
|
79
|
+
# "references",
|
80
|
+
# "modules",
|
81
|
+
# ]
|
82
|
+
# end
|
83
|
+
|
84
|
+
# Hash{String, symbol => unknown}
|
85
|
+
def visit_node(node)
|
86
|
+
kind = node["kind"] || node[:kind]
|
87
|
+
@visitable_nodes[kind].new(node).visit(parser: self)
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_custom_elements(tag_names = [])
|
91
|
+
custom_elements = []
|
92
|
+
|
93
|
+
manifest.modules.flatten.each do |mod|
|
94
|
+
mod.declarations.flatten.each do |dec|
|
95
|
+
next if dec.attributes[:customElement] != true
|
96
|
+
|
97
|
+
if tag_names.empty?
|
98
|
+
custom_elements << dec
|
99
|
+
next
|
100
|
+
end
|
101
|
+
|
102
|
+
if tag_names.include?(dec.attributes[:tagName])
|
103
|
+
custom_elements << dec
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
custom_elements
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative "../types.rb"
|
2
|
+
require_relative "../base_struct.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
module Structs
|
6
|
+
# The common interface of classes and mixins.
|
7
|
+
class ClassLikeStruct < BaseStruct
|
8
|
+
# @!attribute name
|
9
|
+
# @return [String] - Name of the class
|
10
|
+
attribute :name, Types::Strict::String
|
11
|
+
|
12
|
+
# @!attribute summary
|
13
|
+
# @return [String, nil] - A markdown summary suitable for display in a listing.
|
14
|
+
attribute :summary, Types::Strict::String.optional.meta(required: false)
|
15
|
+
|
16
|
+
# @!attribute description
|
17
|
+
# @return [String, nil] - A markdown description of the class.
|
18
|
+
attribute :description, Types::Strict::String.optional.meta(required: false)
|
19
|
+
|
20
|
+
# @!attribute superclass
|
21
|
+
# @return [Reference, nil] -
|
22
|
+
# The superclass of this class.
|
23
|
+
#
|
24
|
+
# If this class is defined with mixin applications, the prototype chain
|
25
|
+
# includes the mixin applications and the true superclass is computed
|
26
|
+
# from them.
|
27
|
+
#
|
28
|
+
# Any class mixins applied in the extends clause of this class.
|
29
|
+
attribute :superclass, Types::Nominal::Any.optional.meta(required: false)
|
30
|
+
|
31
|
+
# @param mixins [Array<Reference>, nil] -
|
32
|
+
# If mixins are applied in the class definition, then the true superclass
|
33
|
+
# of this class is the result of applying mixins in order to the superclass.
|
34
|
+
#
|
35
|
+
# Mixins must be listed in order of their application to the superclass or
|
36
|
+
# previous mixin application. This means that the innermost mixin is listed
|
37
|
+
# first. This may read backwards from the common order in JavaScript, but
|
38
|
+
# matches the order of language used to describe mixin application, like
|
39
|
+
# "S with A, B".
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
#
|
43
|
+
# ```javascript
|
44
|
+
# class T extends B(A(S)) {}
|
45
|
+
# ```
|
46
|
+
#
|
47
|
+
# is described by:
|
48
|
+
# ```json
|
49
|
+
# {
|
50
|
+
# "kind": "class",
|
51
|
+
# "superclass": {
|
52
|
+
# "name": "S"
|
53
|
+
# },
|
54
|
+
# "mixins": [
|
55
|
+
# {
|
56
|
+
# "name": "A"
|
57
|
+
# },
|
58
|
+
# {
|
59
|
+
# "name": "B"
|
60
|
+
# },
|
61
|
+
# ]
|
62
|
+
# }
|
63
|
+
# ```
|
64
|
+
#
|
65
|
+
attribute :mixins, Types::Strict::Array.optional.meta(required: false)
|
66
|
+
|
67
|
+
# @!attribute members
|
68
|
+
# @return [Array<ClassField, ClassMethod>, nil]
|
69
|
+
attribute :members, Types::Strict::Array.optional.meta(required: false)
|
70
|
+
|
71
|
+
# @!attribute source
|
72
|
+
# @return [SourceReference, nil]
|
73
|
+
attribute :source, Types::Nominal::Any.optional.meta(required: false)
|
74
|
+
|
75
|
+
# @!attribute deprecated
|
76
|
+
# @return [nil, boolean, string]
|
77
|
+
# Whether the class or mixin is deprecated.
|
78
|
+
# If the value is a string, it's the reason for the deprecation.
|
79
|
+
attribute :deprecated, Types::Strict::Bool | Types::Strict::String.optional.meta(required: false)
|
80
|
+
|
81
|
+
def self.build_hash(parser:, struct:)
|
82
|
+
hash = {}
|
83
|
+
hash[:superclass] = struct.parser.data_types[:superclass].new(superclass).visit(parser: parser) unless struct.superclass.nil?
|
84
|
+
hash[:mixins] = struct.mixins.map { |mixin| parser.data_types[:mixin].new(mixin).visit(parser: parser) } unless struct.mixins.nil?
|
85
|
+
hash[:source] = struct.parser.data_types[:source].new(source).visit(parser: parser) unless struct.source.nil?
|
86
|
+
|
87
|
+
hash[:members] = struct.members.map { |member| parser.visit_node(member) } unless struct.members.nil?
|
88
|
+
hash
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative "./class_like_struct.rb"
|
2
|
+
require_relative "../types.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
module Structs
|
6
|
+
# The additional fields that a custom element adds to classes and mixins.
|
7
|
+
class CustomElementLikeStruct < BaseStruct
|
8
|
+
# @!parse include Structs::ClassLikeStruct
|
9
|
+
attributes_from ClassLikeStruct
|
10
|
+
|
11
|
+
# @!attribute customElement
|
12
|
+
# @return [True] - Distinguishes a regular JavaScript class from a custom element class
|
13
|
+
attribute :customElement, Types::Strict::True
|
14
|
+
|
15
|
+
# @!attribute tagName
|
16
|
+
# @return [String, nil] -
|
17
|
+
# An optional tag name that should be specified if this is a
|
18
|
+
# self-registering element.
|
19
|
+
#
|
20
|
+
# Self-registering elements must also include a CustomElementExport
|
21
|
+
# in the module's exports.
|
22
|
+
attribute :tagName, Types::Strict::String.optional.meta(required: false)
|
23
|
+
|
24
|
+
# @!attribute attributes
|
25
|
+
# @return [Array<Attribute>, nil] - The attributes that this element is known to understand.
|
26
|
+
attribute :attributes, Types::Strict::Array.optional.meta(required: false)
|
27
|
+
|
28
|
+
# @param demos [Array<Demo>, nil]
|
29
|
+
attribute :demos, Types::Strict::Array.optional.meta(required: false)
|
30
|
+
|
31
|
+
# @!attribute cssProperties
|
32
|
+
# @return [Array<CssCustomProperty>, nil]
|
33
|
+
attribute :cssProperties, Types::Strict::Array.optional.meta(required: false)
|
34
|
+
|
35
|
+
# @!attribute cssParts
|
36
|
+
# @return [Array<CssPart>, nil] - Array of CSS Parts
|
37
|
+
attribute :cssParts, Types::Strict::Array.optional.meta(required: false)
|
38
|
+
|
39
|
+
# @!attribute slots
|
40
|
+
# @return [Array<Slot>, nil] - The shadow dom content slots that this element accepts.
|
41
|
+
attribute :slots, Types::Strict::Array.optional.meta(required: false)
|
42
|
+
|
43
|
+
# @!attribute events
|
44
|
+
# @return [Array<Event>, nil] - The events that this element fires.
|
45
|
+
attribute :events, Types::Strict::Array.optional.meta(required: false)
|
46
|
+
|
47
|
+
def self.build_hash(parser:, struct:)
|
48
|
+
hash = {}
|
49
|
+
|
50
|
+
# This is a special case because DryStruct reserves the `attributes` namespace.
|
51
|
+
hash[:attributes] = struct.attributes[:attributes].map { |attr| parser.data_types[:attribute].new(attr).visit(parser: parser) } unless struct.attributes[:attributes].nil?
|
52
|
+
|
53
|
+
hash[:cssProperties] = struct.cssProperties.map { |css_custom_property| parser.data_types[:css_custom_property].new(css_custom_property).visit(parser: parser) } unless struct.cssProperties.nil?
|
54
|
+
|
55
|
+
hash[:cssParts] = struct.cssParts.map { |css_part| parser.data_types[:css_part].new(css_part).visit(parser: parser) } unless struct.cssParts.nil?
|
56
|
+
hash[:demos] = struct.demos.map { |demo| parser.data_types[:demo].new(demo).visit(parser: parser) } unless struct.demos.nil?
|
57
|
+
hash[:slots] = struct.slots.map { |slot| parser.data_types[:slot].new(slot).visit(parser: parser) } unless struct.slots.nil?
|
58
|
+
hash[:events] = struct.events.map { |event| parser.data_types[:event].new(event).visit(parser: parser) } unless struct.events.nil?
|
59
|
+
|
60
|
+
hash
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "../types.rb"
|
2
|
+
require_relative "../base_struct.rb"
|
3
|
+
|
4
|
+
# DeclarableNode is a Node that has a parent JavaScript module.
|
5
|
+
module CustomElementsManifestParser
|
6
|
+
module Structs
|
7
|
+
class DeclarableNodeStruct < BaseStruct
|
8
|
+
# @!attribute parent_module
|
9
|
+
# @return [JavaScriptModule, nil] -
|
10
|
+
# A convenience helper so you don't need to manually traverse the manifest and always go top -> bottom.
|
11
|
+
# By using this you can grab the "path" and "exports" of a custom element.
|
12
|
+
attribute :parent_module, Types::Nominal::Any.optional.meta(required: false)
|
13
|
+
|
14
|
+
def self.build_hash(parser:, struct:)
|
15
|
+
{}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative "../types.rb"
|
2
|
+
require_relative "../base_struct.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
module Structs
|
6
|
+
# An interface for functions / methods.
|
7
|
+
class FunctionLikeStruct < BaseStruct
|
8
|
+
# @!attribute name
|
9
|
+
# @return [String, nil] - Name of the function
|
10
|
+
attribute :name, Types::Strict::String.optional.meta(required: false)
|
11
|
+
|
12
|
+
# @!attribute summary
|
13
|
+
# @return [String, nil] - A markdown summary suitable for display in a listing.
|
14
|
+
attribute :summary, Types::Strict::String.optional.meta(required: false)
|
15
|
+
|
16
|
+
# @!attribute description
|
17
|
+
# @return [String, nil] - A markdown description.
|
18
|
+
attribute :description, Types::Strict::String.optional.meta(required: false)
|
19
|
+
|
20
|
+
# @!attribute deprecated
|
21
|
+
# @return [Boolean, String, nil]
|
22
|
+
# Whether the function is deprecated.
|
23
|
+
# If the value is a string, it's the reason for the deprecation.
|
24
|
+
attribute :deprecated, Types::Strict::String.optional | Types::Strict::Bool.optional.meta(required: false)
|
25
|
+
|
26
|
+
# @param parameters [nil, Array<Parameter>]
|
27
|
+
attribute :parameters, Types::Strict::Array.optional | Types::Strict::Nil.optional.meta(required: false)
|
28
|
+
|
29
|
+
# @param return [nil, FunctionReturnType]
|
30
|
+
attribute :return, Types::Nominal::Any.optional.meta(required: false)
|
31
|
+
|
32
|
+
def self.build_hash(parser:, struct:)
|
33
|
+
hash = {}
|
34
|
+
hash[:parameters] = struct.parameters.map { |parameter| parser.data_types[:parameter].new(parameter).visit(parser: parser) } if struct.parameters
|
35
|
+
hash[:return] = parser.data_types[:function_return_type].new(struct.return).visit(parser: parser) if struct.return
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative "../types.rb"
|
2
|
+
require_relative "../base_struct.rb"
|
3
|
+
|
4
|
+
module CustomElementsManifestParser
|
5
|
+
module Structs
|
6
|
+
# The common interface of variables, class fields, and function
|
7
|
+
# parameters.
|
8
|
+
class PropertyLikeStruct < BaseStruct
|
9
|
+
# @!attribute name
|
10
|
+
# @return [String] - Name of the property
|
11
|
+
attribute :name, Types::Strict::String
|
12
|
+
|
13
|
+
# @!attribute summary
|
14
|
+
# @return [String, nil] - A markdown summary suitable for display in a listing.
|
15
|
+
attribute :summary, Types::Strict::String.optional.meta(required: false)
|
16
|
+
|
17
|
+
# @!attribute description
|
18
|
+
# @return [String, nil] - A markdown description of the field.
|
19
|
+
attribute :description, Types::Strict::String.optional.meta(required: false)
|
20
|
+
|
21
|
+
# @!attribute type
|
22
|
+
# @return [nil, Type] - The type serializer IE: "Object", "String", etc.
|
23
|
+
attribute :type, Types::Nominal::Any.optional.meta(required: false)
|
24
|
+
|
25
|
+
# @!attribute default
|
26
|
+
# @return [String, nil] - Default value
|
27
|
+
attribute :default, Types::Strict::String.optional.meta(required: false)
|
28
|
+
|
29
|
+
# @!attribute deprecated
|
30
|
+
# @return [nil, Boolean, String] -
|
31
|
+
# Whether the property is deprecated.
|
32
|
+
# If the value is a string, it's the reason for the deprecation.
|
33
|
+
attribute :deprecated, Types::Strict::Bool.optional | Types::Strict::String.optional.meta(required: false)
|
34
|
+
|
35
|
+
# @!attribute readonly
|
36
|
+
# @return [nil, Boolean] - Whether the property is read-only.
|
37
|
+
attribute :readonly, Types::Strict::Bool.optional.meta(required: false)
|
38
|
+
|
39
|
+
def self.build_hash(parser:, struct:)
|
40
|
+
hash = {}
|
41
|
+
hash[:type] = parser.data_types[:type].new(struct.type).visit(parser: parser) if struct.type
|
42
|
+
hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "dry-types"
|
2
|
+
|
3
|
+
module CustomElementsManifestParser
|
4
|
+
# Dry types
|
5
|
+
module Types
|
6
|
+
include Dry.Types
|
7
|
+
|
8
|
+
# @return [Types::String.enum("private", "protected", "public"]
|
9
|
+
def self.privacy
|
10
|
+
Types::String.enum("private", "protected", "public")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Top level parser
|
5
|
+
module CustomElementsManifestParser
|
6
|
+
Dir["#{__dir__}/custom_elements_manifest_parser/**/*.rb"].each { |file| require file }
|
7
|
+
|
8
|
+
# Shortuct for `CustomElementsManifestParser::Parser.new().parse()`
|
9
|
+
def self.parse(hash)
|
10
|
+
Parser.new(hash).parse
|
11
|
+
end
|
12
|
+
end
|