pakyow-presenter 1.0.0.rc2 → 1.0.0.rc3
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/lib/pakyow/{presenter/actions → actions/presenter}/auto_render.rb +2 -2
- data/lib/pakyow/plugin/helpers/rendering.rb +15 -2
- data/lib/pakyow/presenter.rb +1 -1
- data/lib/pakyow/presenter/attributes.rb +8 -0
- data/lib/pakyow/presenter/attributes/attribute.rb +0 -1
- data/lib/pakyow/presenter/attributes/boolean.rb +0 -1
- data/lib/pakyow/presenter/behavior/error_rendering.rb +1 -0
- data/lib/pakyow/presenter/behavior/initializing.rb +1 -1
- data/lib/pakyow/presenter/behavior/modes.rb +1 -0
- data/lib/pakyow/presenter/binder.rb +2 -0
- data/lib/pakyow/presenter/binding_parts.rb +1 -0
- data/lib/pakyow/presenter/component.rb +1 -4
- data/lib/pakyow/presenter/composers/component.rb +1 -0
- data/lib/pakyow/presenter/composers/view.rb +1 -0
- data/lib/pakyow/presenter/errors.rb +2 -2
- data/lib/pakyow/presenter/framework.rb +22 -25
- data/lib/pakyow/presenter/presenter.rb +5 -0
- data/lib/pakyow/presenter/presenters/endpoint.rb +3 -3
- data/lib/pakyow/presenter/presenters/form.rb +5 -5
- data/lib/pakyow/presenter/processor.rb +42 -38
- data/lib/pakyow/presenter/renderer.rb +6 -1
- data/lib/pakyow/presenter/renderer/behavior/cleanup_prototype_nodes.rb +23 -0
- data/lib/pakyow/presenter/renderer/behavior/cleanup_unbound_bindings.rb +37 -0
- data/lib/pakyow/presenter/renderer/behavior/create_template_nodes.rb +29 -0
- data/lib/pakyow/presenter/renderer/behavior/insert_prototype_bar.rb +103 -0
- data/lib/pakyow/presenter/renderer/behavior/install_authenticity.rb +44 -0
- data/lib/pakyow/presenter/renderer/behavior/place_in_mode.rb +58 -0
- data/lib/pakyow/presenter/renderer/behavior/render_components.rb +281 -0
- data/lib/pakyow/presenter/renderer/behavior/set_page_title.rb +37 -0
- data/lib/pakyow/presenter/renderer/behavior/setup_endpoints.rb +64 -0
- data/lib/pakyow/presenter/renderer/behavior/setup_forms.rb +176 -0
- data/lib/pakyow/presenter/significant_nodes.rb +2 -2
- data/lib/pakyow/presenter/templates.rb +24 -15
- data/lib/pakyow/presenter/versioned_view.rb +1 -0
- data/lib/pakyow/presenter/view.rb +11 -9
- data/lib/pakyow/presenter/views/form.rb +39 -35
- data/lib/pakyow/presenter/views/layout.rb +20 -18
- data/lib/pakyow/presenter/views/page.rb +47 -45
- data/lib/pakyow/presenter/views/partial.rb +17 -15
- data/lib/string_doc.rb +3 -1
- data/lib/string_doc/attributes.rb +1 -0
- data/lib/string_doc/meta_attributes.rb +1 -0
- data/lib/string_doc/meta_node.rb +1 -0
- data/lib/string_doc/node.rb +1 -0
- metadata +19 -20
- data/lib/pakyow/presenter/presentable_error.rb +0 -19
- data/lib/pakyow/presenter/rendering/actions/cleanup_prototype_nodes.rb +0 -21
- data/lib/pakyow/presenter/rendering/actions/cleanup_unbound_bindings.rb +0 -35
- data/lib/pakyow/presenter/rendering/actions/create_template_nodes.rb +0 -27
- data/lib/pakyow/presenter/rendering/actions/insert_prototype_bar.rb +0 -101
- data/lib/pakyow/presenter/rendering/actions/install_authenticity.rb +0 -42
- data/lib/pakyow/presenter/rendering/actions/place_in_mode.rb +0 -56
- data/lib/pakyow/presenter/rendering/actions/render_components.rb +0 -279
- data/lib/pakyow/presenter/rendering/actions/set_page_title.rb +0 -35
- data/lib/pakyow/presenter/rendering/actions/setup_endpoints.rb +0 -62
- data/lib/pakyow/presenter/rendering/actions/setup_forms.rb +0 -174
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Presenter
|
7
|
-
module Actions
|
8
|
-
module CleanupPrototypeNodes
|
9
|
-
extend Support::Extension
|
10
|
-
|
11
|
-
apply_extension do
|
12
|
-
build do |view|
|
13
|
-
unless Pakyow.env?(:prototype)
|
14
|
-
view.object.each_significant_node(:prototype, descend: true).map(&:itself).each(&:remove)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Presenter
|
7
|
-
module Actions
|
8
|
-
module CleanupUnboundBindings
|
9
|
-
extend Support::Extension
|
10
|
-
|
11
|
-
apply_extension do
|
12
|
-
attach do |presenter|
|
13
|
-
unless Pakyow.env?(:prototype)
|
14
|
-
# Cleanup unbound bindings. We don't do this in prototype mode because it's important
|
15
|
-
# for the prototype to be complete, showing everything to the designer.
|
16
|
-
#
|
17
|
-
presenter.render node: -> {
|
18
|
-
object.find_significant_nodes(:binding, descend: true).map { |node|
|
19
|
-
View.from_object(node)
|
20
|
-
}
|
21
|
-
}, priority: :low do
|
22
|
-
# We check that the node is still labeled as a binding in case the node was replaced
|
23
|
-
# during a previous transformation with a node that isn't a binding.
|
24
|
-
#
|
25
|
-
unless !view.object.labeled?(:binding) || view.object.labeled?(:bound) || view.object.labeled?(:failed) || view.object.label(:version) == :empty
|
26
|
-
remove
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Presenter
|
7
|
-
module Actions
|
8
|
-
module CreateTemplateNodes
|
9
|
-
extend Support::Extension
|
10
|
-
|
11
|
-
apply_extension do
|
12
|
-
build do |view|
|
13
|
-
unless Pakyow.env?(:prototype)
|
14
|
-
view.each_binding_scope(descend: true) do |node_with_binding|
|
15
|
-
attributes = node_with_binding.attributes.attributes_hash.each_with_object({}) do |(attribute, value), acc|
|
16
|
-
acc[attribute] = value if attribute.to_s.start_with?("data")
|
17
|
-
end
|
18
|
-
|
19
|
-
node_with_binding.after("<script type=\"text/template\"#{StringDoc::Attributes.new(attributes).to_s}>#{node_with_binding.render}</script>")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Presenter
|
7
|
-
module Actions
|
8
|
-
module InsertPrototypeBar
|
9
|
-
extend Support::Extension
|
10
|
-
|
11
|
-
apply_extension do
|
12
|
-
attach do |presenter|
|
13
|
-
if Pakyow.env?(:prototype)
|
14
|
-
presenter.render node: -> {
|
15
|
-
if body = object.find_first_significant_node(:body)
|
16
|
-
View.from_object(body)
|
17
|
-
end
|
18
|
-
} do
|
19
|
-
view.object.append_html <<~HTML
|
20
|
-
<style>
|
21
|
-
.pw-prototype {
|
22
|
-
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
23
|
-
display:flex;
|
24
|
-
align-items: center;
|
25
|
-
position: fixed;
|
26
|
-
z-index: 1000;
|
27
|
-
right: 0;
|
28
|
-
bottom: 0;
|
29
|
-
background: #156eed;
|
30
|
-
color: #fff;
|
31
|
-
font-size: 11px;
|
32
|
-
line-height: 11px;
|
33
|
-
font-weight: 500;
|
34
|
-
border-top-left-radius: 1px;
|
35
|
-
padding-left: 5px;
|
36
|
-
}
|
37
|
-
|
38
|
-
.pw-prototype-tag {
|
39
|
-
background: #ff8b6c;
|
40
|
-
color: #fff;
|
41
|
-
text-transform: uppercase;
|
42
|
-
font-size: 10px;
|
43
|
-
line-height: 12px;
|
44
|
-
font-weight: 600;
|
45
|
-
padding: 5px 5px 4px 5px;
|
46
|
-
margin-left: 10px;
|
47
|
-
}
|
48
|
-
</style>
|
49
|
-
|
50
|
-
<div class="pw-prototype">
|
51
|
-
#{InsertPrototypeBar.ui_modes_html(view, __modes || [:default])}
|
52
|
-
|
53
|
-
<div class="pw-prototype-tag">
|
54
|
-
Prototype
|
55
|
-
</div>
|
56
|
-
</div>
|
57
|
-
HTML
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
expose do |connection|
|
63
|
-
if Pakyow.env?(:prototype)
|
64
|
-
connection.set(:__modes, connection.params[:modes])
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# @api private
|
70
|
-
def self.ui_modes_html(view, current_modes)
|
71
|
-
current_modes = current_modes.map(&:to_sym)
|
72
|
-
|
73
|
-
modes = view.object.each_significant_node(:mode).map { |node|
|
74
|
-
node.label(:mode)
|
75
|
-
}
|
76
|
-
|
77
|
-
modes.unshift(
|
78
|
-
(view.info(:mode) || :default).to_sym
|
79
|
-
).uniq!
|
80
|
-
|
81
|
-
options = modes.map { |each_mode|
|
82
|
-
selected = if current_modes.include?(each_mode)
|
83
|
-
" selected=\"selected\""
|
84
|
-
else
|
85
|
-
""
|
86
|
-
end
|
87
|
-
|
88
|
-
nice_mode = Support.inflector.humanize(Support.inflector.underscore(each_mode))
|
89
|
-
"<option value=\"#{each_mode}\"#{selected}>#{nice_mode}</option>"
|
90
|
-
}.join
|
91
|
-
|
92
|
-
<<~HTML
|
93
|
-
UI Mode: <select onchange="document.location = window.location.pathname + '?modes[]=' + this.value " style="-webkit-appearance: none; -moz-appearance: none; -ms-appearance: none; -o-appearance: none; appearance: none; font-size: 11px; font-weight: 500; line-height: 20px; background: none; border: none; color: #fff; outline: none; margin: 0; margin-left: 5px;">
|
94
|
-
#{options}
|
95
|
-
</select>
|
96
|
-
HTML
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
require "pakyow/support/message_verifier"
|
5
|
-
require "pakyow/support/safe_string"
|
6
|
-
|
7
|
-
module Pakyow
|
8
|
-
module Presenter
|
9
|
-
module Actions
|
10
|
-
module InstallAuthenticity
|
11
|
-
extend Support::Extension
|
12
|
-
|
13
|
-
apply_extension do
|
14
|
-
build do |view, app:|
|
15
|
-
if app.config.presenter.embed_authenticity_token && head = view.head
|
16
|
-
head.append(Support::SafeStringHelpers.html_safe("<meta name=\"pw-authenticity-token\">"))
|
17
|
-
head.append(Support::SafeStringHelpers.html_safe("<meta name=\"pw-authenticity-param\" content=\"#{app.config.security.csrf.param}\">"))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
attach do |presenter|
|
22
|
-
presenter.render node: -> {
|
23
|
-
node = object.each_significant_node(:meta).find { |meta_node|
|
24
|
-
meta_node.attributes[:name] == "pw-authenticity-token"
|
25
|
-
}
|
26
|
-
|
27
|
-
unless node.nil?
|
28
|
-
View.from_object(node)
|
29
|
-
end
|
30
|
-
} do
|
31
|
-
attributes[:content] = @presentables[:__verifier].sign(Support::MessageVerifier.key)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
expose do |connection|
|
36
|
-
connection.set(:__verifier, connection.verifier)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Presenter
|
7
|
-
module Actions
|
8
|
-
module PlaceInMode
|
9
|
-
extend Support::Extension
|
10
|
-
|
11
|
-
apply_extension do
|
12
|
-
build do |view, modes:|
|
13
|
-
unless Pakyow.env?(:prototype)
|
14
|
-
PlaceInMode.perform(view, modes)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
attach do |presenter|
|
19
|
-
if Pakyow.env?(:prototype)
|
20
|
-
presenter.render node: -> {
|
21
|
-
object.find_significant_nodes(:mode, descend: true).map { |node|
|
22
|
-
View.from_object(node)
|
23
|
-
}
|
24
|
-
} do
|
25
|
-
PlaceInMode.perform(view, __modes)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
expose do |connection|
|
31
|
-
if Pakyow.env?(:prototype)
|
32
|
-
connection.set(:__modes, connection.params[:modes] || [:default])
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# @api private
|
38
|
-
def self.perform(view, modes)
|
39
|
-
if modes.length == 1 && modes.first.to_sym == :default
|
40
|
-
modes = view.info(:modes) || modes
|
41
|
-
end
|
42
|
-
|
43
|
-
modes.map!(&:to_sym)
|
44
|
-
|
45
|
-
if view.object.is_a?(StringDoc::Node) && view.object.significant?(:mode) && !modes.include?(view.object.label(:mode))
|
46
|
-
view.remove
|
47
|
-
else
|
48
|
-
view.object.each_significant_node(:mode, descend: true).select { |node|
|
49
|
-
!modes.include?(node.label(:mode))
|
50
|
-
}.each(&:remove)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,279 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
require "pakyow/presenter/composers/component"
|
6
|
-
|
7
|
-
module Pakyow
|
8
|
-
module Presenter
|
9
|
-
module Actions
|
10
|
-
module RenderComponents
|
11
|
-
extend Support::Extension
|
12
|
-
|
13
|
-
apply_extension do
|
14
|
-
build do |view, app:, composer:, modes:|
|
15
|
-
unless Pakyow.env?(:prototype)
|
16
|
-
initial_path = case composer
|
17
|
-
when Composers::Component
|
18
|
-
composer.component_path
|
19
|
-
else
|
20
|
-
[]
|
21
|
-
end
|
22
|
-
|
23
|
-
component_view = case composer
|
24
|
-
when Composers::Component
|
25
|
-
composer.class.follow_path(composer.component_path, view)
|
26
|
-
else
|
27
|
-
view
|
28
|
-
end
|
29
|
-
|
30
|
-
RenderComponents.initialize_renderable_components(
|
31
|
-
component_view, app: app, composer: composer, modes: modes, path: initial_path
|
32
|
-
)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
expose do |connection|
|
37
|
-
# Prevent state from leaking from the component to the rest of the app.
|
38
|
-
#
|
39
|
-
component_connection = connection.dup
|
40
|
-
|
41
|
-
# Expose the component connection for performing from each component.
|
42
|
-
#
|
43
|
-
connection.set(:__component_connection, component_connection)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# @api private
|
48
|
-
def self.initialize_renderable_components(view, app:, composer:, modes:, path: [])
|
49
|
-
view.components.each_with_index do |component_view, i|
|
50
|
-
current_path = path.dup
|
51
|
-
current_path << i
|
52
|
-
|
53
|
-
# If view will be rendered from the app, look for the component on the app.
|
54
|
-
#
|
55
|
-
component_state = if app.is_a?(Plugin) && app.parent.view?(composer.view_path)
|
56
|
-
app.parent.state(:component)
|
57
|
-
else
|
58
|
-
app.state(:component)
|
59
|
-
end
|
60
|
-
|
61
|
-
components = component_view.object.label(:components).each_with_object([]) { |component_label, arr|
|
62
|
-
component_class = component_state.find { |component|
|
63
|
-
component.__object_name.name == component_label[:name]
|
64
|
-
}
|
65
|
-
|
66
|
-
if component_class
|
67
|
-
# Turn the component into a renderable component. Once an instance is attached on the
|
68
|
-
# backend, the component will not be traversed by renders from its parent instead being
|
69
|
-
# rendered by its own renderer instance.
|
70
|
-
#
|
71
|
-
# We don't want the same restriction for non-renderable components because a change to
|
72
|
-
# the view should not affect how things work on the backend.
|
73
|
-
#
|
74
|
-
component_label[:renderable] = true
|
75
|
-
|
76
|
-
arr << {
|
77
|
-
class: component_class,
|
78
|
-
config: component_label[:config]
|
79
|
-
}
|
80
|
-
end
|
81
|
-
}
|
82
|
-
|
83
|
-
if components.any?
|
84
|
-
# Since one or more attached components is renderable, we no longer want to descend.
|
85
|
-
#
|
86
|
-
component_view.object.set_label(:descend, false)
|
87
|
-
|
88
|
-
# Define the render function that calls the component and renders it at render time.
|
89
|
-
#
|
90
|
-
component_render = app.isolated(:Presenter).send(:render_proc, component_view) { |node, _context, string|
|
91
|
-
presentable_component_connection = presentables[:__component_connection]
|
92
|
-
component_connection = presentable_component_connection.dup
|
93
|
-
|
94
|
-
components.each do |component|
|
95
|
-
presentables.each do |key, value|
|
96
|
-
if key.to_s.start_with?("__")
|
97
|
-
component_connection.set(key, value)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# If the component was defined in an app but being called inside a plugin, set the app to the app instead of the plugin.
|
102
|
-
#
|
103
|
-
if component_connection.app.is_a?(Plugin) && component[:class].ancestors.include?(component_connection.app.parent.isolated(:Component))
|
104
|
-
component_connection = component_connection.class.from_connection(component_connection, :@app => component_connection.app.parent)
|
105
|
-
end
|
106
|
-
|
107
|
-
component_instance = component[:class].new(
|
108
|
-
connection: component_connection,
|
109
|
-
config: component[:config]
|
110
|
-
)
|
111
|
-
|
112
|
-
# Call the component.
|
113
|
-
#
|
114
|
-
component_instance.perform
|
115
|
-
end
|
116
|
-
|
117
|
-
# Build a compound component presenter.
|
118
|
-
#
|
119
|
-
component_presenter = if components.length > 1
|
120
|
-
RenderComponents.find_compound_presenter(
|
121
|
-
app, components.map { |c| c[:class] }
|
122
|
-
)
|
123
|
-
else
|
124
|
-
components.first[:class].__presenter_class
|
125
|
-
end
|
126
|
-
|
127
|
-
# Setup the renderer for the component.
|
128
|
-
#
|
129
|
-
renderer = app.isolated(:Renderer).new(
|
130
|
-
app: app,
|
131
|
-
presentables: component_connection.values,
|
132
|
-
presenter_class: component_presenter,
|
133
|
-
composer: Composers::Component.new(
|
134
|
-
composer.view_path, current_path, app: app, labels: node.labels
|
135
|
-
),
|
136
|
-
modes: modes
|
137
|
-
)
|
138
|
-
|
139
|
-
# Render to the main buffer.
|
140
|
-
#
|
141
|
-
renderer.perform(string)
|
142
|
-
|
143
|
-
# Return nil so nothing else gets written.
|
144
|
-
#
|
145
|
-
nil
|
146
|
-
}
|
147
|
-
|
148
|
-
# Attach the above render function to the render node.
|
149
|
-
#
|
150
|
-
component_view.object.transform do |node, context, string|
|
151
|
-
component_render.call(node, context, string); nil
|
152
|
-
end
|
153
|
-
else
|
154
|
-
initialize_renderable_components(
|
155
|
-
component_view, app: app, composer: composer, modes: modes, path: current_path
|
156
|
-
)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
# @api private
|
162
|
-
def self.find_renderable_components(view, components = [])
|
163
|
-
view.components.each do |component_view|
|
164
|
-
find_renderable_components(component_view, components)
|
165
|
-
|
166
|
-
if component_view.object.label(:components).any? { |c| c[:renderable] }
|
167
|
-
components << component_view
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
components
|
172
|
-
end
|
173
|
-
|
174
|
-
# @api private
|
175
|
-
def self.wrap_block(block, context_class)
|
176
|
-
Proc.new do
|
177
|
-
@app.presenter_for_context(
|
178
|
-
context_class.__presenter_class, self
|
179
|
-
).instance_eval(&block)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# @api private
|
184
|
-
def self.find_compound_presenter(app, component_classes)
|
185
|
-
compound_name = component_classes.map { |component_class|
|
186
|
-
component_class.__object_name.name.to_s
|
187
|
-
}.join("_")
|
188
|
-
|
189
|
-
object_name = Support::ObjectName.namespace(
|
190
|
-
app.class.__object_name.namespace.parts[0], :components, compound_name, :presenter
|
191
|
-
)
|
192
|
-
|
193
|
-
if const_defined?(object_name.constant)
|
194
|
-
const_get(object_name.constant)
|
195
|
-
else
|
196
|
-
nil
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
# @api private
|
201
|
-
#
|
202
|
-
def self.find_or_build_compound_presenter(app, component_classes)
|
203
|
-
compound_name = component_classes.map { |component_class|
|
204
|
-
component_class.__object_name.name.to_s
|
205
|
-
}.join("_")
|
206
|
-
|
207
|
-
object_name = Support::ObjectName.namespace(
|
208
|
-
app.class.__object_name.namespace.parts[0], :components, compound_name, :presenter
|
209
|
-
)
|
210
|
-
|
211
|
-
if const_defined?(object_name.constant)
|
212
|
-
const_get(object_name.constant)
|
213
|
-
else
|
214
|
-
component_presenter = Class.new(app.isolated(:Presenter))
|
215
|
-
Support::ObjectMaker.define_const_for_object_with_name(component_presenter, object_name)
|
216
|
-
|
217
|
-
component_classes.each do |component_class|
|
218
|
-
# Copy unique attached renders.
|
219
|
-
#
|
220
|
-
component_class.__presenter_class.__attached_renders.each_with_index do |attached_render, i|
|
221
|
-
component_presenter.__attached_renders.insert(i, {
|
222
|
-
binding_path: attached_render[:binding_path],
|
223
|
-
channel: attached_render[:channel],
|
224
|
-
node: attached_render[:node],
|
225
|
-
priority: attached_render[:priority],
|
226
|
-
block: wrap_block(attached_render[:block], component_class),
|
227
|
-
})
|
228
|
-
end
|
229
|
-
|
230
|
-
# Copy unique global options.
|
231
|
-
#
|
232
|
-
component_class.__presenter_class.__global_options.each do |form_binding, field_binding_values|
|
233
|
-
field_binding_values.each do |field_binding, field_binding_value|
|
234
|
-
component_presenter.options_for(
|
235
|
-
form_binding,
|
236
|
-
field_binding,
|
237
|
-
field_binding_value[:options],
|
238
|
-
&wrap_block(field_binding_value[:block], component_class)
|
239
|
-
)
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# Copy unique presentation logic.
|
244
|
-
#
|
245
|
-
component_class.__presenter_class.__presentation_logic.each do |binding_name, logic_arr|
|
246
|
-
unless component_presenter.__presentation_logic.include?(binding_name)
|
247
|
-
component_presenter.__presentation_logic[binding_name] = []
|
248
|
-
end
|
249
|
-
|
250
|
-
logic_arr.each_with_index do |logic, i|
|
251
|
-
component_presenter.__presentation_logic[binding_name].insert(i, {
|
252
|
-
block: wrap_block(logic[:block], component_class),
|
253
|
-
channel: logic[:channel]
|
254
|
-
})
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
# Copy unique versioning logic.
|
259
|
-
#
|
260
|
-
component_class.__presenter_class.__versioning_logic.each do |binding_name, logic_arr|
|
261
|
-
unless component_presenter.__versioning_logic.include?(binding_name)
|
262
|
-
component_presenter.__versioning_logic[binding_name] = []
|
263
|
-
end
|
264
|
-
|
265
|
-
logic_arr.each_with_index do |logic, i|
|
266
|
-
component_presenter.__versioning_logic[binding_name].insert(i, {
|
267
|
-
block: wrap_block(logic[:block], component_class)
|
268
|
-
})
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
component_presenter
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|