actiontext5 5.2.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/.gitattributes +2 -0
- data/.gitignore +13 -0
- data/.travis.yml +17 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +140 -0
- data/LICENSE +21 -0
- data/README.md +1 -0
- data/Rakefile +27 -0
- data/actiontext.gemspec +29 -0
- data/app/helpers/action_text/content_helper.rb +30 -0
- data/app/helpers/action_text/tag_helper.rb +75 -0
- data/app/javascript/actiontext/attachment_upload.js +45 -0
- data/app/javascript/actiontext/index.js +11 -0
- data/app/models/action_text/rich_text.rb +25 -0
- data/app/views/action_text/attachables/_missing_attachable.html.erb +1 -0
- data/app/views/action_text/attachables/_remote_image.html.erb +8 -0
- data/app/views/action_text/attachment_galleries/_attachment_gallery.html.erb +3 -0
- data/app/views/action_text/content/_layout.html.erb +3 -0
- data/app/views/active_storage/blobs/_blob.html.erb +14 -0
- data/bin/test +6 -0
- data/bin/webpack +29 -0
- data/bin/webpack-dev-server +29 -0
- data/db/migrate/201805281641_create_action_text_tables.rb +14 -0
- data/lib/action_text/attachable.rb +82 -0
- data/lib/action_text/attachables/content_attachment.rb +38 -0
- data/lib/action_text/attachables/missing_attachable.rb +11 -0
- data/lib/action_text/attachables/remote_image.rb +46 -0
- data/lib/action_text/attachment.rb +103 -0
- data/lib/action_text/attachment_gallery.rb +65 -0
- data/lib/action_text/attachments/caching.rb +16 -0
- data/lib/action_text/attachments/minification.rb +17 -0
- data/lib/action_text/attachments/trix_conversion.rb +34 -0
- data/lib/action_text/attribute.rb +48 -0
- data/lib/action_text/content.rb +126 -0
- data/lib/action_text/engine.rb +45 -0
- data/lib/action_text/fragment.rb +57 -0
- data/lib/action_text/html_conversion.rb +24 -0
- data/lib/action_text/plain_text_conversion.rb +81 -0
- data/lib/action_text/serialization.rb +34 -0
- data/lib/action_text/trix_attachment.rb +92 -0
- data/lib/action_text/version.rb +5 -0
- data/lib/action_text.rb +38 -0
- data/lib/actiontext5.rb +1 -0
- data/lib/tasks/actiontext.rake +20 -0
- data/lib/templates/actiontext.scss +36 -0
- data/lib/templates/fixtures.yml +4 -0
- data/lib/templates/installer.rb +22 -0
- data/package.json +21 -0
- data/test/dummy/.babelrc +18 -0
- data/test/dummy/.postcssrc.yml +3 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/stylesheets/application.css +16 -0
- data/test/dummy/app/assets/stylesheets/messages.css +4 -0
- data/test/dummy/app/assets/stylesheets/scaffold.css +80 -0
- data/test/dummy/app/channels/application_cable/channel.rb +4 -0
- data/test/dummy/app/channels/application_cable/connection.rb +4 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/controllers/messages_controller.rb +58 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/messages_helper.rb +2 -0
- data/test/dummy/app/javascript/packs/application.js +1 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/application_record.rb +3 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/models/message.rb +4 -0
- data/test/dummy/app/models/person.rb +7 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/app/views/messages/_form.html.erb +27 -0
- data/test/dummy/app/views/messages/edit.html.erb +6 -0
- data/test/dummy/app/views/messages/index.html.erb +29 -0
- data/test/dummy/app/views/messages/new.html.erb +5 -0
- data/test/dummy/app/views/messages/show.html.erb +13 -0
- data/test/dummy/app/views/people/_trix_content_attachment.html.erb +3 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +36 -0
- data/test/dummy/bin/update +31 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config/application.rb +19 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +63 -0
- data/test/dummy/config/environments/production.rb +96 -0
- data/test/dummy/config/environments/test.rb +46 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +14 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/content_security_policy.rb +22 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +34 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/config/storage.yml +35 -0
- data/test/dummy/config/webpack/development.js +3 -0
- data/test/dummy/config/webpack/environment.js +3 -0
- data/test/dummy/config/webpack/production.js +3 -0
- data/test/dummy/config/webpack/test.js +3 -0
- data/test/dummy/config/webpacker.yml +65 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/db/migrate/20180208205311_create_messages.rb +8 -0
- data/test/dummy/db/migrate/20180212164506_create_active_storage_tables.active_storage.rb +26 -0
- data/test/dummy/db/migrate/2018052816_create_action_text_tables.rb +14 -0
- data/test/dummy/db/migrate/20181003185713_create_people.rb +9 -0
- data/test/dummy/db/schema.rb +58 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/package.json +11 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/test/dummy/public/apple-touch-icon.png +0 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/storage/.keep +0 -0
- data/test/dummy/tmp/.keep +0 -0
- data/test/dummy/tmp/storage/.keep +0 -0
- data/test/dummy/yarn.lock +6071 -0
- data/test/fixtures/files/racecar.jpg +0 -0
- data/test/template/form_helper_test.rb +71 -0
- data/test/test_helper.rb +30 -0
- data/test/unit/attachment_test.rb +60 -0
- data/test/unit/content_test.rb +116 -0
- data/test/unit/model_test.rb +47 -0
- data/test/unit/plain_text_conversion_test.rb +94 -0
- data/test/unit/trix_attachment_test.rb +83 -0
- data/yarn.lock +11 -0
- metadata +372 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionText
|
|
4
|
+
module PlainTextConversion
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def node_to_plain_text(node)
|
|
8
|
+
remove_trailing_newlines(plain_text_for_node(node))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
def plain_text_for_node(node, index = 0)
|
|
13
|
+
if respond_to?(plain_text_method_for_node(node), true)
|
|
14
|
+
send(plain_text_method_for_node(node), node, index)
|
|
15
|
+
else
|
|
16
|
+
plain_text_for_node_children(node)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def plain_text_for_node_children(node)
|
|
21
|
+
node.children.each_with_index.map do |child, index|
|
|
22
|
+
plain_text_for_node(child, index)
|
|
23
|
+
end.compact.join("")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def plain_text_method_for_node(node)
|
|
27
|
+
:"plain_text_for_#{node.name}_node"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def plain_text_for_block(node, index = 0)
|
|
31
|
+
"#{remove_trailing_newlines(plain_text_for_node_children(node))}\n\n"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
%i[ h1 p ul ol ].each do |element|
|
|
35
|
+
alias_method :"plain_text_for_#{element}_node", :plain_text_for_block
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def plain_text_for_br_node(node, index)
|
|
39
|
+
"\n"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def plain_text_for_text_node(node, index)
|
|
43
|
+
remove_trailing_newlines(node.text)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def plain_text_for_div_node(node, index)
|
|
47
|
+
"#{remove_trailing_newlines(plain_text_for_node_children(node))}\n"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def plain_text_for_figcaption_node(node, index)
|
|
51
|
+
"[#{remove_trailing_newlines(plain_text_for_node_children(node))}]"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def plain_text_for_blockquote_node(node, index)
|
|
55
|
+
text = plain_text_for_block(node)
|
|
56
|
+
text.sub(/\A(\s*)(.+?)(\s*)\Z/m, '\1“\2”\3')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def plain_text_for_li_node(node, index)
|
|
60
|
+
bullet = bullet_for_li_node(node, index)
|
|
61
|
+
text = remove_trailing_newlines(plain_text_for_node_children(node))
|
|
62
|
+
"#{bullet} #{text}\n"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def remove_trailing_newlines(text)
|
|
66
|
+
text.chomp("")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def bullet_for_li_node(node, index)
|
|
70
|
+
if list_node_name_for_li_node(node) == "ol"
|
|
71
|
+
"#{index + 1}."
|
|
72
|
+
else
|
|
73
|
+
"•"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def list_node_name_for_li_node(node)
|
|
78
|
+
node.ancestors.lazy.map(&:name).grep(/^[uo]l$/).first
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionText
|
|
4
|
+
module Serialization
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
def load(content)
|
|
9
|
+
new(content) if content
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dump(content)
|
|
13
|
+
case content
|
|
14
|
+
when nil
|
|
15
|
+
nil
|
|
16
|
+
when self
|
|
17
|
+
content.to_html
|
|
18
|
+
else
|
|
19
|
+
new(content).to_html
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Marshal compatibility
|
|
25
|
+
|
|
26
|
+
class_methods do
|
|
27
|
+
alias_method :_load, :load
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def _dump(*)
|
|
31
|
+
self.class.dump(self)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionText
|
|
4
|
+
class TrixAttachment
|
|
5
|
+
TAG_NAME = "figure"
|
|
6
|
+
SELECTOR = "[data-trix-attachment]"
|
|
7
|
+
|
|
8
|
+
COMPOSED_ATTRIBUTES = %w( caption presentation )
|
|
9
|
+
ATTRIBUTES = %w( sgid contentType url href filename filesize width height previewable content ) + COMPOSED_ATTRIBUTES
|
|
10
|
+
ATTRIBUTE_TYPES = {
|
|
11
|
+
"previewable" => ->(value) { value.to_s == "true" },
|
|
12
|
+
"filesize" => ->(value) { Integer(value.to_s) rescue value },
|
|
13
|
+
"width" => ->(value) { Integer(value.to_s) rescue nil },
|
|
14
|
+
"height" => ->(value) { Integer(value.to_s) rescue nil },
|
|
15
|
+
:default => ->(value) { value.to_s }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
def from_attributes(attributes)
|
|
20
|
+
attributes = process_attributes(attributes)
|
|
21
|
+
|
|
22
|
+
trix_attachment_attributes = attributes.except(*COMPOSED_ATTRIBUTES)
|
|
23
|
+
trix_attributes = attributes.slice(*COMPOSED_ATTRIBUTES)
|
|
24
|
+
|
|
25
|
+
node = ActionText::HtmlConversion.create_element(TAG_NAME)
|
|
26
|
+
node["data-trix-attachment"] = JSON.generate(trix_attachment_attributes)
|
|
27
|
+
node["data-trix-attributes"] = JSON.generate(trix_attributes) if trix_attributes.any?
|
|
28
|
+
|
|
29
|
+
new(node)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
def process_attributes(attributes)
|
|
34
|
+
typecast_attribute_values(transform_attribute_keys(attributes))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def transform_attribute_keys(attributes)
|
|
38
|
+
attributes.transform_keys { |key| key.to_s.underscore.camelize(:lower) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def typecast_attribute_values(attributes)
|
|
42
|
+
attributes.map do |key, value|
|
|
43
|
+
typecast = ATTRIBUTE_TYPES[key] || ATTRIBUTE_TYPES[:default]
|
|
44
|
+
[key, typecast.call(value)]
|
|
45
|
+
end.to_h
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
attr_reader :node
|
|
50
|
+
|
|
51
|
+
def initialize(node)
|
|
52
|
+
@node = node
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def attributes
|
|
56
|
+
@attributes ||= attachment_attributes.merge(composed_attributes).slice(*ATTRIBUTES)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def to_html
|
|
60
|
+
ActionText::HtmlConversion.node_to_html(node)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_s
|
|
64
|
+
to_html
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
def attachment_attributes
|
|
69
|
+
read_json_object_attribute("data-trix-attachment")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def composed_attributes
|
|
73
|
+
read_json_object_attribute("data-trix-attributes")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def read_json_object_attribute(name)
|
|
77
|
+
read_json_attribute(name) || {}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def read_json_attribute(name)
|
|
81
|
+
if value = node[name]
|
|
82
|
+
begin
|
|
83
|
+
JSON.parse(value)
|
|
84
|
+
rescue => e
|
|
85
|
+
Rails.logger.error "[#{self.class.name}] Couldn't parse JSON #{value} from NODE #{node.inspect}"
|
|
86
|
+
Rails.logger.error "[#{self.class.name}] Failed with #{e.class}: #{e.backtrace}"
|
|
87
|
+
nil
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
data/lib/action_text.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_record"
|
|
4
|
+
require "action_text/engine"
|
|
5
|
+
require "nokogiri"
|
|
6
|
+
|
|
7
|
+
module ActionText
|
|
8
|
+
extend ActiveSupport::Autoload
|
|
9
|
+
|
|
10
|
+
mattr_accessor(:renderer)
|
|
11
|
+
|
|
12
|
+
autoload :Attachable
|
|
13
|
+
autoload :AttachmentGallery
|
|
14
|
+
autoload :Attachment
|
|
15
|
+
autoload :Attribute
|
|
16
|
+
autoload :Content
|
|
17
|
+
autoload :Fragment
|
|
18
|
+
autoload :HtmlConversion
|
|
19
|
+
autoload :PlainTextConversion
|
|
20
|
+
autoload :Serialization
|
|
21
|
+
autoload :TrixAttachment
|
|
22
|
+
|
|
23
|
+
module Attachables
|
|
24
|
+
extend ActiveSupport::Autoload
|
|
25
|
+
|
|
26
|
+
autoload :ContentAttachment
|
|
27
|
+
autoload :MissingAttachable
|
|
28
|
+
autoload :RemoteImage
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module Attachments
|
|
32
|
+
extend ActiveSupport::Autoload
|
|
33
|
+
|
|
34
|
+
autoload :Caching
|
|
35
|
+
autoload :Minification
|
|
36
|
+
autoload :TrixConversion
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/actiontext5.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative "action_text"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :action_text do
|
|
4
|
+
# Prevent migration installation task from showing up twice.
|
|
5
|
+
Rake::Task["install:migrations"].clear_comments
|
|
6
|
+
|
|
7
|
+
desc "Copy over the migration, stylesheet, and JavaScript files"
|
|
8
|
+
task install: %w( environment run_installer copy_migrations )
|
|
9
|
+
|
|
10
|
+
task :run_installer do
|
|
11
|
+
installer_template = File.expand_path("../templates/installer.rb", __dir__)
|
|
12
|
+
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{installer_template}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
task :copy_migrations do
|
|
16
|
+
Rake::Task["active_storage:install:migrations"].invoke
|
|
17
|
+
Rake::Task["railties:install:migrations"].reenable # Otherwise you can't run 2 migration copy tasks in one invocation
|
|
18
|
+
Rake::Task["action_text:install:migrations"].invoke
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
|
|
3
|
+
// the trix-editor content (whether displayed or under editing). Feel free to incorporate this
|
|
4
|
+
// inclusion directly in any other asset bundle and remove this file.
|
|
5
|
+
//
|
|
6
|
+
//= require trix/dist/trix
|
|
7
|
+
|
|
8
|
+
// We need to override trix.css’s image gallery styles to accommodate the
|
|
9
|
+
// <action-text-attachment> element we wrap around attachments. Otherwise,
|
|
10
|
+
// images in galleries will be squished by the max-width: 33%; rule.
|
|
11
|
+
.trix-content {
|
|
12
|
+
.attachment-gallery {
|
|
13
|
+
> action-text-attachment,
|
|
14
|
+
> .attachment {
|
|
15
|
+
flex: 1 0 33%;
|
|
16
|
+
padding: 0 0.5em;
|
|
17
|
+
max-width: 33%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&.attachment-gallery--2,
|
|
21
|
+
&.attachment-gallery--4 {
|
|
22
|
+
> action-text-attachment,
|
|
23
|
+
> .attachment {
|
|
24
|
+
flex-basis: 50%;
|
|
25
|
+
max-width: 50%;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
action-text-attachment {
|
|
31
|
+
.attachment {
|
|
32
|
+
padding: 0 !important;
|
|
33
|
+
max-width: 100% !important;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
say "Copying actiontext.scss to app/assets/stylesheets"
|
|
2
|
+
copy_file "#{__dir__}/actiontext.scss", "app/assets/stylesheets/actiontext.scss"
|
|
3
|
+
|
|
4
|
+
say "Copying fixtures to test/fixtures/action_text/rich_texts.yml"
|
|
5
|
+
copy_file "#{__dir__}/fixtures.yml", "test/fixtures/action_text/rich_texts.yml"
|
|
6
|
+
|
|
7
|
+
say "Copying blob rendering partial to app/views/active_storage/blobs/_blob.html.erb"
|
|
8
|
+
copy_file "#{__dir__}/../../app/views/active_storage/blobs/_blob.html.erb",
|
|
9
|
+
"app/views/active_storage/blobs/_blob.html.erb"
|
|
10
|
+
|
|
11
|
+
# FIXME: Replace with release version on release
|
|
12
|
+
say "Installing JavaScript dependency"
|
|
13
|
+
run "yarn add https://github.com/BenoitMC/actiontext5"
|
|
14
|
+
|
|
15
|
+
APPLICATION_PACK_PATH = "app/javascript/packs/application.js"
|
|
16
|
+
|
|
17
|
+
if File.exists?(APPLICATION_PACK_PATH) && File.read(APPLICATION_PACK_PATH) !~ /import "actiontext"/
|
|
18
|
+
say "Adding import to default JavaScript pack"
|
|
19
|
+
append_to_file APPLICATION_PACK_PATH, <<-EOS
|
|
20
|
+
import "actiontext"
|
|
21
|
+
EOS
|
|
22
|
+
end
|
data/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "actiontext",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Edit and display rich text in Rails applications",
|
|
5
|
+
"main": "app/javascript/actiontext/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"app/javascript/actiontext/*.js"
|
|
8
|
+
],
|
|
9
|
+
"repository": "https://github.com/BenoitMC/actiontext5",
|
|
10
|
+
"author": "Basecamp, LLC",
|
|
11
|
+
"contributors": [
|
|
12
|
+
"Javan Makhmali <javan@javan.us>",
|
|
13
|
+
"Sam Stephenson <sstephenson@gmail.com>"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"trix": ">=1.0.0",
|
|
18
|
+
"activestorage": ">=5.2.0"
|
|
19
|
+
},
|
|
20
|
+
"private": true
|
|
21
|
+
}
|
data/test/dummy/.babelrc
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"presets": [
|
|
3
|
+
["env", {
|
|
4
|
+
"modules": false,
|
|
5
|
+
"targets": {
|
|
6
|
+
"browsers": "> 1%",
|
|
7
|
+
"uglify": true
|
|
8
|
+
},
|
|
9
|
+
"useBuiltIns": true
|
|
10
|
+
}]
|
|
11
|
+
],
|
|
12
|
+
|
|
13
|
+
"plugins": [
|
|
14
|
+
"syntax-dynamic-import",
|
|
15
|
+
"transform-object-rest-spread",
|
|
16
|
+
["transform-class-properties", { "spec": true }]
|
|
17
|
+
]
|
|
18
|
+
}
|
data/test/dummy/Rakefile
ADDED
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
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 trix/dist/trix.css
|
|
14
|
+
*= require_tree .
|
|
15
|
+
*= require_self
|
|
16
|
+
*/
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
body {
|
|
2
|
+
background-color: #fff;
|
|
3
|
+
color: #333;
|
|
4
|
+
margin: 33px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body, p, ol, ul, td {
|
|
8
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
|
9
|
+
font-size: 13px;
|
|
10
|
+
line-height: 18px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
pre {
|
|
14
|
+
background-color: #eee;
|
|
15
|
+
padding: 10px;
|
|
16
|
+
font-size: 11px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
a {
|
|
20
|
+
color: #000;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
a:visited {
|
|
24
|
+
color: #666;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
a:hover {
|
|
28
|
+
color: #fff;
|
|
29
|
+
background-color: #000;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
th {
|
|
33
|
+
padding-bottom: 5px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
td {
|
|
37
|
+
padding: 0 5px 7px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
div.field,
|
|
41
|
+
div.actions {
|
|
42
|
+
margin-bottom: 10px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
#notice {
|
|
46
|
+
color: green;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.field_with_errors {
|
|
50
|
+
padding: 2px;
|
|
51
|
+
background-color: red;
|
|
52
|
+
display: table;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#error_explanation {
|
|
56
|
+
width: 450px;
|
|
57
|
+
border: 2px solid red;
|
|
58
|
+
padding: 7px 7px 0;
|
|
59
|
+
margin-bottom: 20px;
|
|
60
|
+
background-color: #f0f0f0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#error_explanation h2 {
|
|
64
|
+
text-align: left;
|
|
65
|
+
font-weight: bold;
|
|
66
|
+
padding: 5px 5px 5px 15px;
|
|
67
|
+
font-size: 12px;
|
|
68
|
+
margin: -7px -7px 0;
|
|
69
|
+
background-color: #c00;
|
|
70
|
+
color: #fff;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#error_explanation ul li {
|
|
74
|
+
font-size: 12px;
|
|
75
|
+
list-style: square;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
label {
|
|
79
|
+
display: block;
|
|
80
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class MessagesController < ApplicationController
|
|
2
|
+
before_action :set_message, only: [:show, :edit, :update, :destroy]
|
|
3
|
+
|
|
4
|
+
# GET /messages
|
|
5
|
+
def index
|
|
6
|
+
@messages = Message.all
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# GET /messages/1
|
|
10
|
+
def show
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# GET /messages/new
|
|
14
|
+
def new
|
|
15
|
+
@message = Message.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# GET /messages/1/edit
|
|
19
|
+
def edit
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# POST /messages
|
|
23
|
+
def create
|
|
24
|
+
@message = Message.new(message_params)
|
|
25
|
+
|
|
26
|
+
if @message.save
|
|
27
|
+
redirect_to @message, notice: 'Message was successfully created.'
|
|
28
|
+
else
|
|
29
|
+
render :new
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# PATCH/PUT /messages/1
|
|
34
|
+
def update
|
|
35
|
+
if @message.update(message_params)
|
|
36
|
+
redirect_to @message, notice: 'Message was successfully updated.'
|
|
37
|
+
else
|
|
38
|
+
render :edit
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# DELETE /messages/1
|
|
43
|
+
def destroy
|
|
44
|
+
@message.destroy
|
|
45
|
+
redirect_to messages_url, notice: 'Message was successfully destroyed.'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
50
|
+
def set_message
|
|
51
|
+
@message = Message.find(params[:id])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Only allow a trusted parameter "white list" through.
|
|
55
|
+
def message_params
|
|
56
|
+
params.require(:message).permit(:subject, :content)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "actiontext"
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= yield %>
|