dynamic_text 0.0.5 → 0.0.6
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/Rakefile +6 -8
- data/app/assets/javascripts/dynamic_text/dynamic_text.js +7 -76
- data/app/assets/javascripts/dynamic_text/dynamic_text_preparer.js +62 -0
- data/app/assets/javascripts/dynamic_text/js.js +6 -0
- data/app/helpers/dynamic_text/view_helper.rb +6 -92
- data/app/views/dynamic_text/_dynamic_text.html.erb +4 -0
- data/app/views/dynamic_text/_editable_text.html.erb +20 -0
- data/lib/dynamic_text/configuration.rb +4 -4
- data/lib/dynamic_text/locals_setter.rb +70 -0
- data/lib/dynamic_text/version.rb +1 -1
- data/lib/dynamic_text/view_renderer.rb +39 -0
- data/lib/dynamic_text.rb +2 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +4 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +36 -0
- data/spec/dummy/bin/update +31 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config/application.rb +18 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +26 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +61 -0
- data/spec/dummy/config/environments/production.rb +94 -0
- data/spec/dummy/config/environments/test.rb +46 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +34 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/db/schema.rb +18 -0
- data/spec/dummy/log/development.log +38 -0
- data/spec/dummy/log/test.log +1646 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/helpers/view_helper_spec.rb +8 -0
- data/spec/integration/navigation_test.rb +7 -0
- data/spec/lib/locals_setter_spec.rb +114 -0
- data/spec/lib/view_renderer.rb +3 -0
- data/spec/rails_helper.rb +63 -0
- data/spec/spec_helper.rb +81 -0
- metadata +185 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc355787a78ea70e6728fb425360773d10a6a964478a551213a525a029153fa5
|
4
|
+
data.tar.gz: 400c9191e052f31835e86a1d3575cf82ff1c78bfd5240c7a3d46cf76502143e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 578a1f7541b9d99e46753eb26ee1e0a9f053629931ab30421a1d93ef9640058a963c56809f47ee4e0589c9f2d1f1a50f9355a948b6b5c2906f102e90e1562dfc
|
7
|
+
data.tar.gz: a38e4ea970e6808367e52c552b8b8b7a00014db566e2874cb156df239cfece7897808d4978d4b2563c0aa17c7fca8fe678c01c0d06bcc329e0565cbb8a4f099c
|
data/Rakefile
CHANGED
@@ -14,19 +14,17 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
14
14
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
15
|
end
|
16
16
|
|
17
|
-
APP_RAKEFILE = File.expand_path("
|
17
|
+
APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
|
18
18
|
load 'rails/tasks/engine.rake'
|
19
19
|
|
20
20
|
load 'rails/tasks/statistics.rake'
|
21
21
|
|
22
22
|
require 'bundler/gem_tasks'
|
23
23
|
|
24
|
-
require '
|
24
|
+
require 'rspec/core'
|
25
|
+
require 'rspec/core/rake_task'
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
t.pattern = 'test/**/*_test.rb'
|
29
|
-
t.verbose = false
|
30
|
-
end
|
27
|
+
# desc "Run all specs in spec directory (excluding plugin specs)"
|
28
|
+
RSpec::Core::RakeTask.new(:spec)
|
31
29
|
|
32
|
-
task default: :
|
30
|
+
task default: :spec
|
@@ -54,13 +54,13 @@ const DynamicText = {
|
|
54
54
|
this.ajaxResponses['default'] = func;
|
55
55
|
},
|
56
56
|
|
57
|
-
// Set response for specific
|
58
|
-
handleAjaxResponseFor(
|
59
|
-
this.ajaxResponses[
|
57
|
+
// Set response for specific js key
|
58
|
+
handleAjaxResponseFor(jsKey, func) {
|
59
|
+
this.ajaxResponses[jsKey] = func;
|
60
60
|
},
|
61
61
|
|
62
62
|
// Build ajax request for patch resource function.
|
63
|
-
sendPatchRequest(url, resourceType, attribute, updatedValue,
|
63
|
+
sendPatchRequest(url, resourceType, attribute, updatedValue, jsKey) {
|
64
64
|
const CSRF_TOKEN =
|
65
65
|
document.querySelector('meta[name="csrf-token"]')
|
66
66
|
.getAttribute('content');
|
@@ -78,7 +78,7 @@ const DynamicText = {
|
|
78
78
|
xhr.onload = () => {
|
79
79
|
if (xhr.status === 200) {
|
80
80
|
successCallback =
|
81
|
-
this.ajaxResponses[
|
81
|
+
this.ajaxResponses[jsKey] || this.ajaxResponses['default']
|
82
82
|
successCallback(JSON.parse(xhr.responseText), resourceType)
|
83
83
|
}
|
84
84
|
};
|
@@ -98,78 +98,9 @@ const DynamicText = {
|
|
98
98
|
const url = action.getAttribute('url');
|
99
99
|
const resourceType = action.getAttribute('resource-type');
|
100
100
|
const attribute = action.getAttribute('attribute');
|
101
|
-
const
|
101
|
+
const jsKey = action.getAttribute('js-key');
|
102
102
|
const updatedValue = editableText.innerText;
|
103
103
|
|
104
|
-
this.sendPatchRequest(url, resourceType, attribute, updatedValue,
|
104
|
+
this.sendPatchRequest(url, resourceType, attribute, updatedValue, jsKey)
|
105
105
|
}
|
106
106
|
}
|
107
|
-
|
108
|
-
const prepareDynamicText = () => {
|
109
|
-
document.querySelectorAll('.editable-text').forEach((editableText) => {
|
110
|
-
// Exit editable text editor mode (focus) on enter instead of adding a new line.
|
111
|
-
editableText.addEventListener('keydown', (e) => {
|
112
|
-
if (e.keyCode === 13) {
|
113
|
-
e.preventDefault();
|
114
|
-
e.currentTarget.blur();
|
115
|
-
}
|
116
|
-
});
|
117
|
-
|
118
|
-
// Properly paste text into editable text
|
119
|
-
editableText.addEventListener('paste', (e) => {
|
120
|
-
e.preventDefault();
|
121
|
-
DynamicText.handleContentEditablePaste(e)
|
122
|
-
});
|
123
|
-
|
124
|
-
// Disable dragging and dropping text/images into editable text.
|
125
|
-
["dragover", "drop"].forEach((evt) => {
|
126
|
-
editableText.addEventListener(evt, (e) => {
|
127
|
-
e.preventDefault();
|
128
|
-
return false;
|
129
|
-
});
|
130
|
-
});
|
131
|
-
|
132
|
-
// Store original value when focusing in on specific editable text (used to determine if text was changed and patch request should be sent on focusout.)
|
133
|
-
editableText.addEventListener('focus', (e) => {
|
134
|
-
const target = e.currentTarget;
|
135
|
-
target.setAttribute('data-original-value', target.innerText);
|
136
|
-
});
|
137
|
-
|
138
|
-
// Send patch request for resource if content was changed.
|
139
|
-
editableText.addEventListener('focusout', (e) => {
|
140
|
-
const target = e.currentTarget
|
141
|
-
|
142
|
-
// Empty all content of text if editable text is empty (otherwise certain browsers fill in a default <br> or <p> value.)
|
143
|
-
if (!target.innerText.trim().length) {
|
144
|
-
target.innerText = null;
|
145
|
-
}
|
146
|
-
|
147
|
-
// Send patch request if text was changed.
|
148
|
-
if (target.getAttribute('data-original-value') != target.innerText) {
|
149
|
-
DynamicText.patchResource(e);
|
150
|
-
}
|
151
|
-
|
152
|
-
target.removeAttribute('data-original-value')
|
153
|
-
});
|
154
|
-
|
155
|
-
// Update all other divs tagged with the same dynamic-tag as the current text being edited. (So if you have two elements on one page that display the same title property of a resource, both will be updated in real time when you edit the text of one.)
|
156
|
-
editableText.addEventListener('input', (e) => {
|
157
|
-
const target = e.currentTarget;
|
158
|
-
const newValue = target.innerText;
|
159
|
-
const dynamicTag = target.getAttribute('data-dynamic-tag');
|
160
|
-
|
161
|
-
document.querySelectorAll(`[data-dynamic-tag='${dynamicTag}']`)
|
162
|
-
.forEach((dynamicTextElement) => {
|
163
|
-
if(dynamicTextElement !== target) {
|
164
|
-
dynamicTextElement.innerText = newValue;
|
165
|
-
}
|
166
|
-
});
|
167
|
-
});
|
168
|
-
})
|
169
|
-
}
|
170
|
-
|
171
|
-
const events = ["turbolinks:load", "page:change"];
|
172
|
-
|
173
|
-
events.forEach((evt) => {
|
174
|
-
document.addEventListener(evt, prepareDynamicText)
|
175
|
-
});
|
@@ -0,0 +1,62 @@
|
|
1
|
+
const prepareDynamicText = () => {
|
2
|
+
document.querySelectorAll('.editable-text').forEach((editableText) => {
|
3
|
+
// Exit editable text editor mode (focus) on enter instead of adding a new line.
|
4
|
+
editableText.addEventListener('keydown', (e) => {
|
5
|
+
if (e.keyCode === 13) {
|
6
|
+
e.preventDefault();
|
7
|
+
e.currentTarget.blur();
|
8
|
+
}
|
9
|
+
});
|
10
|
+
|
11
|
+
// Properly paste text into editable text
|
12
|
+
editableText.addEventListener('paste', (e) => {
|
13
|
+
e.preventDefault();
|
14
|
+
DynamicText.handleContentEditablePaste(e)
|
15
|
+
});
|
16
|
+
|
17
|
+
// Disable dragging and dropping text/images into editable text.
|
18
|
+
["dragover", "drop"].forEach((evt) => {
|
19
|
+
editableText.addEventListener(evt, (e) => {
|
20
|
+
e.preventDefault();
|
21
|
+
return false;
|
22
|
+
});
|
23
|
+
});
|
24
|
+
|
25
|
+
// Store original value when focusing in on specific editable text (used to determine if text was changed and patch request should be sent on focusout.)
|
26
|
+
editableText.addEventListener('focus', (e) => {
|
27
|
+
const target = e.currentTarget;
|
28
|
+
target.setAttribute('data-original-value', target.innerText);
|
29
|
+
});
|
30
|
+
|
31
|
+
// Send patch request for resource if content was changed.
|
32
|
+
editableText.addEventListener('focusout', (e) => {
|
33
|
+
const target = e.currentTarget
|
34
|
+
|
35
|
+
// Empty all content of text if editable text is empty (otherwise certain browsers fill in a default <br> or <p> value.)
|
36
|
+
if (!target.innerText.trim().length) {
|
37
|
+
target.innerText = null;
|
38
|
+
}
|
39
|
+
|
40
|
+
// Send patch request if text was changed.
|
41
|
+
if (target.getAttribute('data-original-value') != target.innerText) {
|
42
|
+
DynamicText.patchResource(e);
|
43
|
+
}
|
44
|
+
|
45
|
+
target.removeAttribute('data-original-value')
|
46
|
+
});
|
47
|
+
|
48
|
+
// Update all other divs tagged with the same dynamic-tag as the current text being edited. (So if you have two elements on one page that display the same property of a resource, both will be updated in real time when you edit the text of one.)
|
49
|
+
editableText.addEventListener('input', (e) => {
|
50
|
+
const target = e.currentTarget;
|
51
|
+
const newValue = target.innerText;
|
52
|
+
const dynamicTag = target.getAttribute('data-dynamic-tag');
|
53
|
+
|
54
|
+
document.querySelectorAll(`[data-dynamic-tag='${dynamicTag}']`)
|
55
|
+
.forEach((dynamicTextElement) => {
|
56
|
+
if(dynamicTextElement !== target) {
|
57
|
+
dynamicTextElement.innerText = newValue;
|
58
|
+
}
|
59
|
+
});
|
60
|
+
});
|
61
|
+
})
|
62
|
+
}
|
@@ -1,99 +1,13 @@
|
|
1
1
|
module DynamicText
|
2
2
|
module ViewHelper
|
3
|
-
def
|
4
|
-
|
5
|
-
|
3
|
+
def dynamic_text_for(resource, attribute, opts={})
|
4
|
+
DynamicText::ViewRenderer.new(self)
|
5
|
+
.render_dynamic_text_for(resource, attribute, opts)
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def dynamic_text_for(resource, attribute, options={})
|
15
|
-
options = dynamic_attributes(resource, attribute, options)
|
16
|
-
dynamic_text_tag(options)
|
17
|
-
end
|
18
|
-
|
19
|
-
def editable_text_for(resource, attribute, options = {})
|
20
|
-
options = editable_attributes(resource, attribute, options)
|
21
|
-
|
22
|
-
content_tag(:span, class: "editable-text-container") do
|
23
|
-
editable_text_tag(options) +
|
24
|
-
patch_request_tag(options)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def dynamic_attributes(resource, attribute, options={})
|
31
|
-
Hash.new.tap do |hash|
|
32
|
-
hash[:resource] = resource
|
33
|
-
hash[:attribute] = attribute
|
34
|
-
hash[:value] = resource.send(attribute)
|
35
|
-
hash[:placeholder] = options[:placeholder] || "Enter #{attribute}..."
|
36
|
-
hash[:resource_type] = expected_resource_type(resource)
|
37
|
-
hash[:dynamic_tag] =
|
38
|
-
default_dynamic_tag(hash[:resource_type], resource.id, attribute)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def editable_attributes(resource, attribute, options={})
|
43
|
-
dynamic_attributes(resource, attribute, options={}).tap do |hash|
|
44
|
-
hash[:url] =
|
45
|
-
options[:url] || send("#{DynamicText.configuration.path_prefix}#{hash[:resource_type]}_path", resource)
|
46
|
-
hash[:ajax_key] =
|
47
|
-
options[:ajax_key] || default_ajax_key(hash[:resource_type], attribute)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def dynamic_text_tag(attributes)
|
52
|
-
text = attributes[:value] || attributes[:placeholder]
|
53
|
-
dynamic_text_attributes = {
|
54
|
-
class: "dynamic-text",
|
55
|
-
data: {"dynamic-tag": attributes[:dynamic_tag]}
|
56
|
-
}
|
57
|
-
|
58
|
-
content_tag(:span, text, dynamic_text_attributes)
|
59
|
-
end
|
60
|
-
|
61
|
-
def editable_text_tag(attributes)
|
62
|
-
editable_text_attributes = {
|
63
|
-
class: "editable-text",
|
64
|
-
contenteditable: true,
|
65
|
-
placeholder: attributes[:placeholder],
|
66
|
-
data: {"dynamic-tag": attributes[:dynamic_tag]}
|
67
|
-
}
|
68
|
-
|
69
|
-
content_tag(:span, attributes[:value], editable_text_attributes)
|
70
|
-
end
|
71
|
-
|
72
|
-
def patch_request_tag(attributes)
|
73
|
-
patch_request_attributes = {
|
74
|
-
'url' => attributes[:url],
|
75
|
-
'attribute' => attributes[:attribute],
|
76
|
-
'resource-type' => attributes[:resource_type],
|
77
|
-
'ajax-key' => attributes[:ajax_key]
|
78
|
-
}
|
79
|
-
|
80
|
-
hidden_field_tag("_action", "patch", patch_request_attributes)
|
81
|
-
end
|
82
|
-
|
83
|
-
def expected_resource_type(resource)
|
84
|
-
resource.class.name.downcase
|
85
|
-
end
|
86
|
-
|
87
|
-
def expected_path(resource, resource_type=expected_type_for(resource))
|
88
|
-
send("#{resource_type}_path", resource)
|
89
|
-
end
|
90
|
-
|
91
|
-
def default_dynamic_tag(resource_type, resource_id, attribute)
|
92
|
-
"#{resource_type}:#{resource_id}:#{attribute}"
|
93
|
-
end
|
94
|
-
|
95
|
-
def default_ajax_key(resource_type, attribute)
|
96
|
-
"#{resource_type}:#{attribute}"
|
8
|
+
def editable_text_for(resource, attribute, opts={})
|
9
|
+
DynamicText::ViewRenderer.new(self)
|
10
|
+
.render_editable_text_for(resource, attribute, opts)
|
97
11
|
end
|
98
12
|
end
|
99
13
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<span class='editable-text-container'>
|
2
|
+
<%= content_tag(:span,
|
3
|
+
class: 'editable-text',
|
4
|
+
contenteditable: true,
|
5
|
+
placeholder: placeholder,
|
6
|
+
data: { 'dynamic-tag': dynamic_tag }
|
7
|
+
) do -%>
|
8
|
+
<%= value -%>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<input id='_action'
|
12
|
+
type='hidden'
|
13
|
+
name='_action'
|
14
|
+
value='patch'
|
15
|
+
url='<%= url %>'
|
16
|
+
attribute='<%= attribute %>'
|
17
|
+
resource-type='<%= resource_type %>'
|
18
|
+
js-key='<%= js_key %>'
|
19
|
+
>
|
20
|
+
</span>
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class DynamicText::Configuration
|
2
|
-
attr_reader :
|
2
|
+
attr_reader :resource_scope
|
3
3
|
|
4
4
|
def initialize
|
5
|
-
@
|
5
|
+
@resource_scope = nil
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
@
|
8
|
+
def resource_scope=(resource_scope)
|
9
|
+
@resource_scope = "/#{resource_scope}"
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class DynamicText::LocalsSetter
|
2
|
+
def get_dynamic_locals(resource, attribute, opts={})
|
3
|
+
locals.merge!(opts).tap do |locals|
|
4
|
+
locals[:resource] = resource
|
5
|
+
locals[:attribute] = attribute
|
6
|
+
locals[:resource_id] = resource.id
|
7
|
+
locals[:value] = resource.send(attribute)
|
8
|
+
locals[:resource_scope] ||= default_resource_scope
|
9
|
+
locals[:placeholder] ||= default_placeholder
|
10
|
+
locals[:resource_type] ||= default_resource_type
|
11
|
+
locals[:resource_route] ||= default_resource_route
|
12
|
+
locals[:dynamic_tag] ||= default_dynamic_tag
|
13
|
+
end
|
14
|
+
end #PT
|
15
|
+
|
16
|
+
def get_editable_locals(resource, attribute, opts={})
|
17
|
+
get_dynamic_locals(resource, attribute, opts).tap do |locals|
|
18
|
+
locals[:url] ||= default_url
|
19
|
+
locals[:js_key] ||= default_js_key
|
20
|
+
end
|
21
|
+
end #PT
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Defaults
|
26
|
+
|
27
|
+
def default_resource_scope
|
28
|
+
DynamicText.configuration.resource_scope
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_placeholder
|
32
|
+
"Enter #{get_local(:attribute)}..."
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_resource_type
|
36
|
+
get_local(:resource).class.name.downcase
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_resource_route
|
40
|
+
get_local(:resource_type).pluralize
|
41
|
+
end
|
42
|
+
|
43
|
+
def default_dynamic_tag
|
44
|
+
get_locals(:resource_type, :resource_id, :attribute).join(":")
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_url
|
48
|
+
get_locals(:resource_scope, :resource_route, :resource_id).join("/")
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_js_key
|
52
|
+
get_locals(:resource_type, :attribute).join(":")
|
53
|
+
end
|
54
|
+
|
55
|
+
# Helpers
|
56
|
+
|
57
|
+
def locals
|
58
|
+
@locals ||= {}
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_local(local_name)
|
62
|
+
locals[local_name]
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_locals(*local_names)
|
66
|
+
local_names.collect do |local_name|
|
67
|
+
get_local(local_name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/dynamic_text/version.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
class DynamicText::ViewRenderer < AbstractController::Base
|
2
|
+
def initialize(controller)
|
3
|
+
@controller = controller
|
4
|
+
end
|
5
|
+
|
6
|
+
def render_dynamic_text_for(resource, attribute, opts={})
|
7
|
+
render_dynamic_text dynamic_locals(resource, attribute, opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def render_editable_text_for(resource, attribute, opts={})
|
11
|
+
render_editable_text editable_locals(resource, attribute, opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def dynamic_locals(resource, attribute, opts={})
|
17
|
+
locals_setter.get_dynamic_locals(resource, attribute, opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def editable_locals(resource, attribute, opts={})
|
21
|
+
locals_setter.get_editable_locals(resource, attribute, opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def locals_setter
|
25
|
+
DynamicText::LocalsSetter.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def render_editable_text(locals)
|
29
|
+
render_partial(:editable_text, **locals)
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_dynamic_text(locals)
|
33
|
+
render_partial(:dynamic_text, **locals)
|
34
|
+
end
|
35
|
+
|
36
|
+
def render_partial(partial, **locals)
|
37
|
+
@controller.render partial: "dynamic_text/#{partial}", locals: locals
|
38
|
+
end
|
39
|
+
end
|
data/lib/dynamic_text.rb
CHANGED
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require rails-ujs
|
14
|
+
//= require activestorage
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
+
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
3
|
+
//
|
4
|
+
//= require action_cable
|
5
|
+
//= require_self
|
6
|
+
//= require_tree ./channels
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
this.App || (this.App = {});
|
10
|
+
|
11
|
+
App.cable = ActionCable.createConsumer();
|
12
|
+
|
13
|
+
}).call(this);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Dummy</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
<%= stylesheet_link_tag 'application', media: 'all' %>
|
9
|
+
<%= javascript_include_tag 'application' %>
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<%= yield %>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
data/spec/dummy/bin/rake
ADDED