formalist 0.3.0 → 0.4.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 +5 -5
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.travis.yml +21 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +62 -0
- data/Gemfile +1 -2
- data/bin/console +13 -0
- data/formalist.gemspec +33 -0
- data/lib/formalist/definition.rb +65 -0
- data/lib/formalist/element/class_interface.rb +7 -59
- data/lib/formalist/element.rb +37 -19
- data/lib/formalist/elements/attr.rb +8 -20
- data/lib/formalist/elements/compound_field.rb +5 -4
- data/lib/formalist/elements/field.rb +5 -12
- data/lib/formalist/elements/group.rb +6 -5
- data/lib/formalist/elements/many.rb +28 -29
- data/lib/formalist/elements/section.rb +6 -10
- data/lib/formalist/elements/standard/multi_upload_field.rb +8 -0
- data/lib/formalist/elements/standard/rich_text_area.rb +40 -0
- data/lib/formalist/elements/standard/search_multi_selection_field.rb +20 -0
- data/lib/formalist/elements/standard/search_selection_field.rb +20 -0
- data/lib/formalist/elements/standard/tags_field.rb +16 -0
- data/lib/formalist/elements/standard/upload_field.rb +8 -0
- data/lib/formalist/elements/standard.rb +4 -0
- data/lib/formalist/form/validity_check.rb +54 -0
- data/lib/formalist/form.rb +49 -17
- data/lib/formalist/rich_text/embedded_form_compiler.rb +86 -0
- data/lib/formalist/rich_text/embedded_forms_container/mixin.rb +42 -0
- data/lib/formalist/rich_text/embedded_forms_container/registration.rb +30 -0
- data/lib/formalist/rich_text/embedded_forms_container.rb +9 -0
- data/lib/formalist/rich_text/rendering/embedded_form_renderer.rb +25 -0
- data/lib/formalist/rich_text/rendering/html_compiler.rb +100 -0
- data/lib/formalist/rich_text/rendering/html_renderer.rb +186 -0
- data/lib/formalist/rich_text/validity_check.rb +48 -0
- data/lib/formalist/types.rb +8 -7
- data/lib/formalist/version.rb +1 -1
- metadata +54 -31
- data/Gemfile.lock +0 -105
- data/lib/formalist/element/definition.rb +0 -55
- data/lib/formalist/element/permitted_children.rb +0 -46
- data/lib/formalist/form/definition_context.rb +0 -69
- data/lib/formalist/form/result.rb +0 -24
- data/spec/examples.txt +0 -8
- data/spec/integration/dependency_injection_spec.rb +0 -54
- data/spec/integration/form_spec.rb +0 -104
- data/spec/spec_helper.rb +0 -109
- data/spec/support/constants.rb +0 -11
- data/spec/unit/elements/standard/check_box_spec.rb +0 -33
@@ -0,0 +1,186 @@
|
|
1
|
+
module Formalist
|
2
|
+
module RichText
|
3
|
+
module Rendering
|
4
|
+
class HTMLRenderer
|
5
|
+
# A DraftJS HTML renderer must have the following rendering methods implemented:
|
6
|
+
# 1. inline
|
7
|
+
# 2. block
|
8
|
+
# 3. entity
|
9
|
+
# 4. wrapper
|
10
|
+
# 5. nodes
|
11
|
+
|
12
|
+
# block and entity must iterate over the children and yield each of the children back to the compiler
|
13
|
+
|
14
|
+
BLOCK_ELEMENTS_MAP = {
|
15
|
+
"header-one" => "h1",
|
16
|
+
"header-two" => "h2",
|
17
|
+
"header-three" => "h3",
|
18
|
+
"header-four" => "h4",
|
19
|
+
"header-five" => "h5",
|
20
|
+
"header-six" => "h6",
|
21
|
+
"unordered-list-item" => "li",
|
22
|
+
"ordered-list-item" => "li",
|
23
|
+
"blockquote" => "blockquote",
|
24
|
+
"pullquote" => "aside",
|
25
|
+
"code-block" => "pre",
|
26
|
+
"horizontal-rule" => "hr",
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
DEFAULT_BLOCK_ELEMENT = "p".freeze
|
30
|
+
|
31
|
+
INLINE_ELEMENTS_MAP = {
|
32
|
+
"bold" => "strong",
|
33
|
+
"italic" => "em",
|
34
|
+
"strikethrough" => "del",
|
35
|
+
"code" => "code",
|
36
|
+
"underline" => "u",
|
37
|
+
}
|
38
|
+
|
39
|
+
DEFAULT_INLINE_ELEMENT = "span".freeze
|
40
|
+
|
41
|
+
def initialize(options = {})
|
42
|
+
@options = options
|
43
|
+
end
|
44
|
+
|
45
|
+
# Defines how to handle a list of nodes
|
46
|
+
def nodes(nodes)
|
47
|
+
nodes = nodes.map { |node| yield(node) } if block_given?
|
48
|
+
nodes.join
|
49
|
+
end
|
50
|
+
|
51
|
+
# Defines how to handle a block node
|
52
|
+
def block(type, key, children)
|
53
|
+
rendered_children = children.map { |child| yield(child) }
|
54
|
+
|
55
|
+
if type == 'atomic'
|
56
|
+
block_atomic(key, rendered_children)
|
57
|
+
else
|
58
|
+
render_block_element(type, rendered_children)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Defines how to handle a list of blocks with a list type
|
63
|
+
def wrapper(type, children)
|
64
|
+
type_for_method = type.gsub("-", "_")
|
65
|
+
|
66
|
+
rendered_children = children.map { |child| yield(child) }
|
67
|
+
|
68
|
+
send(:"wrapper_#{type_for_method}", rendered_children)
|
69
|
+
end
|
70
|
+
|
71
|
+
def inline(styles, content)
|
72
|
+
return content if styles.nil? || styles.empty?
|
73
|
+
out = content
|
74
|
+
styles.each do |style|
|
75
|
+
out = render_inline_element(style, out)
|
76
|
+
end
|
77
|
+
out
|
78
|
+
end
|
79
|
+
|
80
|
+
def entity(type, key, data, children)
|
81
|
+
rendered_children = children.map { |child| yield(child) }
|
82
|
+
|
83
|
+
handler = :"entity_#{type.downcase}"
|
84
|
+
if respond_to?(handler, _include_private=true)
|
85
|
+
send(handler, data, rendered_children)
|
86
|
+
else
|
87
|
+
rendered_children
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def block_atomic(key, children)
|
94
|
+
children.join
|
95
|
+
end
|
96
|
+
|
97
|
+
def wrapper_unordered_list_item(children)
|
98
|
+
html_tag(:ul) do
|
99
|
+
children.join
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def wrapper_ordered_list_item(children)
|
104
|
+
html_tag(:ol) do
|
105
|
+
children.join
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def entity_link(data, children)
|
110
|
+
link_attrs = {
|
111
|
+
href: data[:url]
|
112
|
+
}
|
113
|
+
link_attrs = link_attrs.merge(
|
114
|
+
target: "_blank",
|
115
|
+
rel: "noopener"
|
116
|
+
) if data[:newWindow]
|
117
|
+
html_tag(:a, link_attrs) do
|
118
|
+
children.join
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def entity_image(data, children)
|
123
|
+
html_tag(:img, src: data[:src])
|
124
|
+
end
|
125
|
+
|
126
|
+
def entity_video(data, children)
|
127
|
+
html_tag(:video, src: data[:src])
|
128
|
+
end
|
129
|
+
|
130
|
+
def entity_default(attrs, children)
|
131
|
+
html_tag(:div, attrs) do
|
132
|
+
children.join
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def render_block_element(type, content)
|
137
|
+
elem = BLOCK_ELEMENTS_MAP.fetch(type.downcase, DEFAULT_BLOCK_ELEMENT)
|
138
|
+
|
139
|
+
html_tag(elem) do
|
140
|
+
if content.is_a?(Array)
|
141
|
+
content.join
|
142
|
+
else
|
143
|
+
content
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def render_inline_element(type, content)
|
149
|
+
elem = INLINE_ELEMENTS_MAP.fetch(type.downcase, DEFAULT_INLINE_ELEMENT)
|
150
|
+
|
151
|
+
html_tag(elem, class: "inline--#{type.downcase}") do
|
152
|
+
if content.is_a?(Array)
|
153
|
+
content.join
|
154
|
+
else
|
155
|
+
content
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def html_tag(tag, options = {})
|
161
|
+
options_string = html_options_string(options)
|
162
|
+
out = "<#{tag} #{options_string}".strip
|
163
|
+
|
164
|
+
content = block_given? ? yield : ""
|
165
|
+
|
166
|
+
if content.nil? || content.empty?
|
167
|
+
out << "/>"
|
168
|
+
else
|
169
|
+
out << ">#{replace_soft_newlines(content)}</#{tag}>"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def html_options_string(options)
|
174
|
+
opts = options.map do |key, val|
|
175
|
+
"#{key}='#{val}'"
|
176
|
+
end
|
177
|
+
opts.join(" ")
|
178
|
+
end
|
179
|
+
|
180
|
+
def replace_soft_newlines(content)
|
181
|
+
content.gsub(/\n/, '<br/>')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "formalist/form/validity_check"
|
2
|
+
|
3
|
+
module Formalist
|
4
|
+
module RichText
|
5
|
+
class ValidityCheck
|
6
|
+
AST = Struct.new(:ast)
|
7
|
+
|
8
|
+
def call(ast)
|
9
|
+
forms = ast.map { |node| visit(node) }.flatten
|
10
|
+
|
11
|
+
form_validity_check = Form::ValidityCheck.new
|
12
|
+
forms.all? { |form_ast| form_validity_check.(form_ast.ast) }
|
13
|
+
end
|
14
|
+
alias_method :[], :call
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def visit(node)
|
19
|
+
name, nodes = node
|
20
|
+
|
21
|
+
handler = :"visit_#{name}"
|
22
|
+
|
23
|
+
if respond_to?(handler, true)
|
24
|
+
send(handler, nodes)
|
25
|
+
else
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# We need to visit blocks in order to get to the formalist entities nested within them
|
31
|
+
def visit_block(node)
|
32
|
+
type, id, children = node
|
33
|
+
|
34
|
+
children.map { |child| visit(child) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def visit_entity(node)
|
38
|
+
type, key, mutability, entity_data, children = node
|
39
|
+
|
40
|
+
if type == "formalist"
|
41
|
+
[AST.new(entity_data["form"])]
|
42
|
+
else
|
43
|
+
[]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/formalist/types.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
2
|
-
require "dry
|
1
|
+
# coding: utf-8
|
2
|
+
require "dry/types"
|
3
3
|
|
4
|
-
|
4
|
+
# TODO: Find a way to avoid registering this globally
|
5
|
+
Dry::Logic::Predicates.predicate :respond_to? do |method_name, value|
|
5
6
|
value.respond_to?(method_name)
|
6
7
|
end
|
7
8
|
|
@@ -9,8 +10,8 @@ module Formalist
|
|
9
10
|
module Types
|
10
11
|
include Dry::Types.module
|
11
12
|
|
12
|
-
ElementName = Types::Strict::Symbol.constrained(min_size: 1)
|
13
|
-
OptionsList = Types::Array.
|
13
|
+
ElementName = Types::Strict::Symbol.constrained(min_size: 1).optional
|
14
|
+
OptionsList = Types::Array.of(Formalist::Types::Array.of(Formalist::Types::Strict::String).constrained(size: 2))
|
14
15
|
|
15
16
|
# The SelectionField and MultiSelectionField require a _somewhat_ specific
|
16
17
|
# data structure:
|
@@ -20,11 +21,11 @@ module Formalist
|
|
20
21
|
# It’s expected that `id` is the relational representation of the object.
|
21
22
|
# And label could/should be optional if the form defines a custom
|
22
23
|
# `render_as` attribute
|
23
|
-
SelectionsList = Formalist::Types::Strict::Array.
|
24
|
+
SelectionsList = Formalist::Types::Strict::Array.of(Formalist::Types::Strict::Hash)
|
24
25
|
|
25
26
|
Validation = Types::Strict::Hash
|
26
27
|
|
27
|
-
Dependency =
|
28
|
+
Dependency = Types::Object
|
28
29
|
Function = Dependency.constrained(respond_to: :call)
|
29
30
|
end
|
30
31
|
end
|
data/lib/formalist/version.rb
CHANGED
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formalist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Riley
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-configurable
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '0.7'
|
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: '0'
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.4'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: dry-container
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- - "
|
45
|
+
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
47
|
+
version: '0.6'
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- - "
|
52
|
+
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
54
|
+
version: '0.6'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: dry-types
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- - "
|
59
|
+
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
61
|
+
version: '0.12'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - "
|
66
|
+
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
68
|
+
version: '0.12'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: inflecto
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +128,14 @@ dependencies:
|
|
114
128
|
requirements:
|
115
129
|
- - "~>"
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
131
|
+
version: 0.13.0
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.
|
138
|
+
version: 0.13.0
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: yard
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,17 +157,22 @@ executables: []
|
|
143
157
|
extensions: []
|
144
158
|
extra_rdoc_files: []
|
145
159
|
files:
|
160
|
+
- ".gitignore"
|
161
|
+
- ".rspec"
|
162
|
+
- ".travis.yml"
|
163
|
+
- ".yardopts"
|
164
|
+
- CHANGELOG.md
|
146
165
|
- Gemfile
|
147
|
-
- Gemfile.lock
|
148
166
|
- LICENSE.md
|
149
167
|
- README.md
|
150
168
|
- Rakefile
|
169
|
+
- bin/console
|
170
|
+
- formalist.gemspec
|
151
171
|
- lib/formalist.rb
|
172
|
+
- lib/formalist/definition.rb
|
152
173
|
- lib/formalist/element.rb
|
153
174
|
- lib/formalist/element/attributes.rb
|
154
175
|
- lib/formalist/element/class_interface.rb
|
155
|
-
- lib/formalist/element/definition.rb
|
156
|
-
- lib/formalist/element/permitted_children.rb
|
157
176
|
- lib/formalist/elements.rb
|
158
177
|
- lib/formalist/elements/attr.rb
|
159
178
|
- lib/formalist/elements/compound_field.rb
|
@@ -170,22 +189,27 @@ files:
|
|
170
189
|
- lib/formalist/elements/standard/multi_upload_field.rb
|
171
190
|
- lib/formalist/elements/standard/number_field.rb
|
172
191
|
- lib/formalist/elements/standard/radio_buttons.rb
|
192
|
+
- lib/formalist/elements/standard/rich_text_area.rb
|
193
|
+
- lib/formalist/elements/standard/search_multi_selection_field.rb
|
194
|
+
- lib/formalist/elements/standard/search_selection_field.rb
|
173
195
|
- lib/formalist/elements/standard/select_box.rb
|
174
196
|
- lib/formalist/elements/standard/selection_field.rb
|
197
|
+
- lib/formalist/elements/standard/tags_field.rb
|
175
198
|
- lib/formalist/elements/standard/text_area.rb
|
176
199
|
- lib/formalist/elements/standard/text_field.rb
|
177
200
|
- lib/formalist/elements/standard/upload_field.rb
|
178
201
|
- lib/formalist/form.rb
|
179
|
-
- lib/formalist/form/
|
180
|
-
- lib/formalist/
|
202
|
+
- lib/formalist/form/validity_check.rb
|
203
|
+
- lib/formalist/rich_text/embedded_form_compiler.rb
|
204
|
+
- lib/formalist/rich_text/embedded_forms_container.rb
|
205
|
+
- lib/formalist/rich_text/embedded_forms_container/mixin.rb
|
206
|
+
- lib/formalist/rich_text/embedded_forms_container/registration.rb
|
207
|
+
- lib/formalist/rich_text/rendering/embedded_form_renderer.rb
|
208
|
+
- lib/formalist/rich_text/rendering/html_compiler.rb
|
209
|
+
- lib/formalist/rich_text/rendering/html_renderer.rb
|
210
|
+
- lib/formalist/rich_text/validity_check.rb
|
181
211
|
- lib/formalist/types.rb
|
182
212
|
- lib/formalist/version.rb
|
183
|
-
- spec/examples.txt
|
184
|
-
- spec/integration/dependency_injection_spec.rb
|
185
|
-
- spec/integration/form_spec.rb
|
186
|
-
- spec/spec_helper.rb
|
187
|
-
- spec/support/constants.rb
|
188
|
-
- spec/unit/elements/standard/check_box_spec.rb
|
189
213
|
homepage: https://github.com/icelab/formalist
|
190
214
|
licenses:
|
191
215
|
- MIT
|
@@ -198,7 +222,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
198
222
|
requirements:
|
199
223
|
- - ">="
|
200
224
|
- !ruby/object:Gem::Version
|
201
|
-
version: 2.
|
225
|
+
version: 2.2.0
|
202
226
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
227
|
requirements:
|
204
228
|
- - ">="
|
@@ -206,9 +230,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
230
|
version: '0'
|
207
231
|
requirements: []
|
208
232
|
rubyforge_project:
|
209
|
-
rubygems_version: 2.
|
233
|
+
rubygems_version: 2.7.5
|
210
234
|
signing_key:
|
211
235
|
specification_version: 4
|
212
236
|
summary: Flexible form builder
|
213
237
|
test_files: []
|
214
|
-
has_rdoc:
|
data/Gemfile.lock
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/dryrb/dry-types
|
3
|
-
revision: 56eba433b066c5f8839e5a81cddc7c955056a71e
|
4
|
-
branch: master
|
5
|
-
specs:
|
6
|
-
dry-types (0.7.1)
|
7
|
-
concurrent-ruby (~> 1.0)
|
8
|
-
dry-configurable (~> 0.1)
|
9
|
-
dry-container (~> 0.3)
|
10
|
-
dry-equalizer (~> 0.2)
|
11
|
-
dry-logic (~> 0.2, >= 0.2.0)
|
12
|
-
inflecto (~> 0.0.0, >= 0.0.2)
|
13
|
-
kleisli (~> 0.2)
|
14
|
-
|
15
|
-
GIT
|
16
|
-
remote: https://github.com/dryrb/dry-validation
|
17
|
-
revision: 2f2ab25b871dde41d4c0f2b259f0c09989f4176b
|
18
|
-
branch: master
|
19
|
-
specs:
|
20
|
-
dry-validation (0.7.4)
|
21
|
-
concurrent-ruby (~> 1.0)
|
22
|
-
dry-configurable (~> 0.1, >= 0.1.3)
|
23
|
-
dry-container (~> 0.2, >= 0.2.8)
|
24
|
-
dry-equalizer (~> 0.2)
|
25
|
-
dry-logic (~> 0.2, >= 0.2.2)
|
26
|
-
dry-types (~> 0.7, >= 0.7.1)
|
27
|
-
|
28
|
-
PATH
|
29
|
-
remote: .
|
30
|
-
specs:
|
31
|
-
formalist (0.3.0)
|
32
|
-
dry-configurable
|
33
|
-
dry-container
|
34
|
-
dry-types
|
35
|
-
inflecto
|
36
|
-
|
37
|
-
GEM
|
38
|
-
remote: https://rubygems.org/
|
39
|
-
specs:
|
40
|
-
byebug (8.2.4)
|
41
|
-
codeclimate-test-reporter (0.5.0)
|
42
|
-
simplecov (>= 0.7.1, < 1.0.0)
|
43
|
-
coderay (1.1.1)
|
44
|
-
concurrent-ruby (1.0.1)
|
45
|
-
diff-lcs (1.2.5)
|
46
|
-
docile (1.1.5)
|
47
|
-
dry-auto_inject (0.2.0)
|
48
|
-
dry-configurable (0.1.4)
|
49
|
-
concurrent-ruby (~> 1.0)
|
50
|
-
dry-container (0.3.1)
|
51
|
-
concurrent-ruby (~> 1.0)
|
52
|
-
dry-configurable (~> 0.1, >= 0.1.3)
|
53
|
-
dry-equalizer (0.2.0)
|
54
|
-
dry-logic (0.2.2)
|
55
|
-
dry-container (~> 0.2, >= 0.2.6)
|
56
|
-
dry-equalizer (~> 0.2)
|
57
|
-
inflecto (0.0.2)
|
58
|
-
json (1.8.3)
|
59
|
-
kleisli (0.2.7)
|
60
|
-
method_source (0.8.2)
|
61
|
-
pry (0.10.3)
|
62
|
-
coderay (~> 1.1.0)
|
63
|
-
method_source (~> 0.8.1)
|
64
|
-
slop (~> 3.4)
|
65
|
-
rake (10.4.2)
|
66
|
-
rspec (3.3.0)
|
67
|
-
rspec-core (~> 3.3.0)
|
68
|
-
rspec-expectations (~> 3.3.0)
|
69
|
-
rspec-mocks (~> 3.3.0)
|
70
|
-
rspec-core (3.3.2)
|
71
|
-
rspec-support (~> 3.3.0)
|
72
|
-
rspec-expectations (3.3.1)
|
73
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
74
|
-
rspec-support (~> 3.3.0)
|
75
|
-
rspec-mocks (3.3.2)
|
76
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
77
|
-
rspec-support (~> 3.3.0)
|
78
|
-
rspec-support (3.3.0)
|
79
|
-
simplecov (0.10.0)
|
80
|
-
docile (~> 1.1.0)
|
81
|
-
json (~> 1.8)
|
82
|
-
simplecov-html (~> 0.10.0)
|
83
|
-
simplecov-html (0.10.0)
|
84
|
-
slop (3.6.0)
|
85
|
-
yard (0.8.7.6)
|
86
|
-
|
87
|
-
PLATFORMS
|
88
|
-
ruby
|
89
|
-
|
90
|
-
DEPENDENCIES
|
91
|
-
bundler (~> 1.10)
|
92
|
-
byebug
|
93
|
-
codeclimate-test-reporter
|
94
|
-
dry-auto_inject
|
95
|
-
dry-types!
|
96
|
-
dry-validation!
|
97
|
-
formalist!
|
98
|
-
pry
|
99
|
-
rake (~> 10.4.2)
|
100
|
-
rspec (~> 3.3.0)
|
101
|
-
simplecov (~> 0.10.0)
|
102
|
-
yard
|
103
|
-
|
104
|
-
BUNDLED WITH
|
105
|
-
1.10.6
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require "formalist/types"
|
2
|
-
|
3
|
-
module Formalist
|
4
|
-
class Element
|
5
|
-
class Definition
|
6
|
-
Deferred = Struct.new(:name)
|
7
|
-
|
8
|
-
attr_reader :type
|
9
|
-
attr_reader :args
|
10
|
-
attr_reader :attributes
|
11
|
-
attr_reader :children
|
12
|
-
|
13
|
-
def initialize(type, *args, attributes, children)
|
14
|
-
@type = type
|
15
|
-
@args = args
|
16
|
-
@attributes = attributes
|
17
|
-
@children = children
|
18
|
-
end
|
19
|
-
|
20
|
-
def ==(other)
|
21
|
-
# Require a matching type.
|
22
|
-
return false if type != other.type
|
23
|
-
|
24
|
-
# If there are no primary args, it means that the element has no real
|
25
|
-
# "identifier" that requires uniqueness, so it's safe to say they don't
|
26
|
-
# match here.
|
27
|
-
return false if args.empty?
|
28
|
-
|
29
|
-
# Otherwise, use the primary args as a marker of a definitions
|
30
|
-
# uniqueness. With the current set of base form elements, the primary
|
31
|
-
# args only ever contains a name, so this is effectively a uniqueness
|
32
|
-
# check on the element's name.
|
33
|
-
args == other.args
|
34
|
-
end
|
35
|
-
|
36
|
-
def resolve(scope)
|
37
|
-
resolved_args = args.map { |arg|
|
38
|
-
arg.is_a?(Deferred) ? scope.send(arg.name) : arg
|
39
|
-
}
|
40
|
-
|
41
|
-
resolved_attributes = attributes.each_with_object({}) { |(key, val), hsh|
|
42
|
-
hsh[key] = val.is_a?(Deferred) ? scope.send(val.name) : val
|
43
|
-
}
|
44
|
-
|
45
|
-
resolved_children = children.map { |c| c.resolve(scope) }
|
46
|
-
|
47
|
-
self.class.new(type, *resolved_args, resolved_attributes, resolved_children)
|
48
|
-
end
|
49
|
-
|
50
|
-
def call(input, messages)
|
51
|
-
type.new(*args, attributes, children, input, messages)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require "inflecto"
|
2
|
-
|
3
|
-
module Formalist
|
4
|
-
class Element
|
5
|
-
class PermittedChildren
|
6
|
-
All = Class.new do
|
7
|
-
def permitted?(*)
|
8
|
-
true
|
9
|
-
end
|
10
|
-
end.new
|
11
|
-
|
12
|
-
None = Class.new do
|
13
|
-
def permitted?(*)
|
14
|
-
false
|
15
|
-
end
|
16
|
-
end.new
|
17
|
-
|
18
|
-
class Some
|
19
|
-
attr_reader :permitted_children
|
20
|
-
|
21
|
-
def initialize(children)
|
22
|
-
@permitted_children = children
|
23
|
-
end
|
24
|
-
|
25
|
-
def permitted?(child)
|
26
|
-
permitted_children.any? { |permitted_child|
|
27
|
-
permitted_child_class = Elements.const_get(Inflecto.camelize(permitted_child))
|
28
|
-
child.ancestors.include?(permitted_child_class)
|
29
|
-
}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.all
|
34
|
-
All
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.none
|
38
|
-
None
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.[](children)
|
42
|
-
Some.new(children)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|