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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +2 -0
  3. data/.gitignore +13 -0
  4. data/.travis.yml +17 -0
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +140 -0
  7. data/LICENSE +21 -0
  8. data/README.md +1 -0
  9. data/Rakefile +27 -0
  10. data/actiontext.gemspec +29 -0
  11. data/app/helpers/action_text/content_helper.rb +30 -0
  12. data/app/helpers/action_text/tag_helper.rb +75 -0
  13. data/app/javascript/actiontext/attachment_upload.js +45 -0
  14. data/app/javascript/actiontext/index.js +11 -0
  15. data/app/models/action_text/rich_text.rb +25 -0
  16. data/app/views/action_text/attachables/_missing_attachable.html.erb +1 -0
  17. data/app/views/action_text/attachables/_remote_image.html.erb +8 -0
  18. data/app/views/action_text/attachment_galleries/_attachment_gallery.html.erb +3 -0
  19. data/app/views/action_text/content/_layout.html.erb +3 -0
  20. data/app/views/active_storage/blobs/_blob.html.erb +14 -0
  21. data/bin/test +6 -0
  22. data/bin/webpack +29 -0
  23. data/bin/webpack-dev-server +29 -0
  24. data/db/migrate/201805281641_create_action_text_tables.rb +14 -0
  25. data/lib/action_text/attachable.rb +82 -0
  26. data/lib/action_text/attachables/content_attachment.rb +38 -0
  27. data/lib/action_text/attachables/missing_attachable.rb +11 -0
  28. data/lib/action_text/attachables/remote_image.rb +46 -0
  29. data/lib/action_text/attachment.rb +103 -0
  30. data/lib/action_text/attachment_gallery.rb +65 -0
  31. data/lib/action_text/attachments/caching.rb +16 -0
  32. data/lib/action_text/attachments/minification.rb +17 -0
  33. data/lib/action_text/attachments/trix_conversion.rb +34 -0
  34. data/lib/action_text/attribute.rb +48 -0
  35. data/lib/action_text/content.rb +126 -0
  36. data/lib/action_text/engine.rb +45 -0
  37. data/lib/action_text/fragment.rb +57 -0
  38. data/lib/action_text/html_conversion.rb +24 -0
  39. data/lib/action_text/plain_text_conversion.rb +81 -0
  40. data/lib/action_text/serialization.rb +34 -0
  41. data/lib/action_text/trix_attachment.rb +92 -0
  42. data/lib/action_text/version.rb +5 -0
  43. data/lib/action_text.rb +38 -0
  44. data/lib/actiontext5.rb +1 -0
  45. data/lib/tasks/actiontext.rake +20 -0
  46. data/lib/templates/actiontext.scss +36 -0
  47. data/lib/templates/fixtures.yml +4 -0
  48. data/lib/templates/installer.rb +22 -0
  49. data/package.json +21 -0
  50. data/test/dummy/.babelrc +18 -0
  51. data/test/dummy/.postcssrc.yml +3 -0
  52. data/test/dummy/Rakefile +6 -0
  53. data/test/dummy/app/assets/config/manifest.js +3 -0
  54. data/test/dummy/app/assets/images/.keep +0 -0
  55. data/test/dummy/app/assets/stylesheets/application.css +16 -0
  56. data/test/dummy/app/assets/stylesheets/messages.css +4 -0
  57. data/test/dummy/app/assets/stylesheets/scaffold.css +80 -0
  58. data/test/dummy/app/channels/application_cable/channel.rb +4 -0
  59. data/test/dummy/app/channels/application_cable/connection.rb +4 -0
  60. data/test/dummy/app/controllers/application_controller.rb +2 -0
  61. data/test/dummy/app/controllers/concerns/.keep +0 -0
  62. data/test/dummy/app/controllers/messages_controller.rb +58 -0
  63. data/test/dummy/app/helpers/application_helper.rb +2 -0
  64. data/test/dummy/app/helpers/messages_helper.rb +2 -0
  65. data/test/dummy/app/javascript/packs/application.js +1 -0
  66. data/test/dummy/app/jobs/application_job.rb +2 -0
  67. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  68. data/test/dummy/app/models/application_record.rb +3 -0
  69. data/test/dummy/app/models/concerns/.keep +0 -0
  70. data/test/dummy/app/models/message.rb +4 -0
  71. data/test/dummy/app/models/person.rb +7 -0
  72. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  73. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  74. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  75. data/test/dummy/app/views/messages/_form.html.erb +27 -0
  76. data/test/dummy/app/views/messages/edit.html.erb +6 -0
  77. data/test/dummy/app/views/messages/index.html.erb +29 -0
  78. data/test/dummy/app/views/messages/new.html.erb +5 -0
  79. data/test/dummy/app/views/messages/show.html.erb +13 -0
  80. data/test/dummy/app/views/people/_trix_content_attachment.html.erb +3 -0
  81. data/test/dummy/bin/bundle +3 -0
  82. data/test/dummy/bin/rails +4 -0
  83. data/test/dummy/bin/rake +4 -0
  84. data/test/dummy/bin/setup +36 -0
  85. data/test/dummy/bin/update +31 -0
  86. data/test/dummy/bin/yarn +11 -0
  87. data/test/dummy/config/application.rb +19 -0
  88. data/test/dummy/config/boot.rb +5 -0
  89. data/test/dummy/config/cable.yml +10 -0
  90. data/test/dummy/config/database.yml +25 -0
  91. data/test/dummy/config/environment.rb +5 -0
  92. data/test/dummy/config/environments/development.rb +63 -0
  93. data/test/dummy/config/environments/production.rb +96 -0
  94. data/test/dummy/config/environments/test.rb +46 -0
  95. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  96. data/test/dummy/config/initializers/assets.rb +14 -0
  97. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  98. data/test/dummy/config/initializers/content_security_policy.rb +22 -0
  99. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  100. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  101. data/test/dummy/config/initializers/inflections.rb +16 -0
  102. data/test/dummy/config/initializers/mime_types.rb +4 -0
  103. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  104. data/test/dummy/config/locales/en.yml +33 -0
  105. data/test/dummy/config/puma.rb +34 -0
  106. data/test/dummy/config/routes.rb +4 -0
  107. data/test/dummy/config/spring.rb +6 -0
  108. data/test/dummy/config/storage.yml +35 -0
  109. data/test/dummy/config/webpack/development.js +3 -0
  110. data/test/dummy/config/webpack/environment.js +3 -0
  111. data/test/dummy/config/webpack/production.js +3 -0
  112. data/test/dummy/config/webpack/test.js +3 -0
  113. data/test/dummy/config/webpacker.yml +65 -0
  114. data/test/dummy/config.ru +5 -0
  115. data/test/dummy/db/migrate/20180208205311_create_messages.rb +8 -0
  116. data/test/dummy/db/migrate/20180212164506_create_active_storage_tables.active_storage.rb +26 -0
  117. data/test/dummy/db/migrate/2018052816_create_action_text_tables.rb +14 -0
  118. data/test/dummy/db/migrate/20181003185713_create_people.rb +9 -0
  119. data/test/dummy/db/schema.rb +58 -0
  120. data/test/dummy/lib/assets/.keep +0 -0
  121. data/test/dummy/log/.keep +0 -0
  122. data/test/dummy/package.json +11 -0
  123. data/test/dummy/public/404.html +67 -0
  124. data/test/dummy/public/422.html +67 -0
  125. data/test/dummy/public/500.html +66 -0
  126. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  127. data/test/dummy/public/apple-touch-icon.png +0 -0
  128. data/test/dummy/public/favicon.ico +0 -0
  129. data/test/dummy/storage/.keep +0 -0
  130. data/test/dummy/tmp/.keep +0 -0
  131. data/test/dummy/tmp/storage/.keep +0 -0
  132. data/test/dummy/yarn.lock +6071 -0
  133. data/test/fixtures/files/racecar.jpg +0 -0
  134. data/test/template/form_helper_test.rb +71 -0
  135. data/test/test_helper.rb +30 -0
  136. data/test/unit/attachment_test.rb +60 -0
  137. data/test/unit/content_test.rb +116 -0
  138. data/test/unit/model_test.rb +47 -0
  139. data/test/unit/plain_text_conversion_test.rb +94 -0
  140. data/test/unit/trix_attachment_test.rb +83 -0
  141. data/yarn.lock +11 -0
  142. 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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionText
4
+ VERSION = '5.2.0'
5
+ end
@@ -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
@@ -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,4 @@
1
+ # one:
2
+ # record: name_of_fixture (ClassOfFixture)
3
+ # name: content
4
+ # body: <p>In a <i>million</i> stars!</p>
@@ -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
+ }
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ plugins:
2
+ postcss-import: {}
3
+ postcss-cssnext: {}
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
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,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -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
+ }
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
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,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module MessagesHelper
2
+ end
@@ -0,0 +1 @@
1
+ import "actiontext"
@@ -0,0 +1,2 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: 'from@example.com'
3
+ layout 'mailer'
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ class Message < ApplicationRecord
2
+ has_rich_text :content
3
+ has_rich_text :body
4
+ end
@@ -0,0 +1,7 @@
1
+ class Person < ApplicationRecord
2
+ include ActionText::Attachable
3
+
4
+ def to_trix_content_attachment_partial_path
5
+ "people/trix_content_attachment"
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= csrf_meta_tags %>
6
+
7
+ <%= stylesheet_link_tag 'application', media: 'all' %>
8
+ <%= javascript_pack_tag 'application' %>
9
+ </head>
10
+
11
+ <body>
12
+ <%= yield %>
13
+ </body>
14
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>