actiontext5 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 %>
|