actiontext 7.0.8.1 → 7.2.2.1
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/CHANGELOG.md +43 -124
- data/MIT-LICENSE +1 -1
- data/README.md +2 -2
- data/app/assets/javascripts/actiontext.esm.js +889 -0
- data/app/assets/javascripts/actiontext.js +55 -73
- data/app/assets/javascripts/trix.js +13612 -5170
- data/app/assets/stylesheets/trix.css +67 -30
- data/app/helpers/action_text/content_helper.rb +28 -4
- data/app/helpers/action_text/tag_helper.rb +44 -30
- data/app/models/action_text/encrypted_rich_text.rb +4 -2
- data/app/models/action_text/record.rb +2 -0
- data/app/models/action_text/rich_text.rb +66 -6
- data/app/views/action_text/attachables/_content_attachment.html.erb +3 -0
- data/db/migrate/20180528164100_create_action_text_tables.rb +1 -1
- data/lib/action_text/attachable.rb +71 -5
- data/lib/action_text/attachables/content_attachment.rb +22 -18
- data/lib/action_text/attachables/missing_attachable.rb +19 -3
- data/lib/action_text/attachables/remote_image.rb +2 -0
- data/lib/action_text/attachment.rb +45 -2
- data/lib/action_text/attachment_gallery.rb +2 -0
- data/lib/action_text/attachments/caching.rb +2 -0
- data/lib/action_text/attachments/minification.rb +2 -0
- data/lib/action_text/attachments/trix_conversion.rb +2 -0
- data/lib/action_text/attribute.rb +40 -21
- data/lib/action_text/content.rb +68 -3
- data/lib/action_text/deprecator.rb +9 -0
- data/lib/action_text/encryption.rb +2 -0
- data/lib/action_text/engine.rb +17 -9
- data/lib/action_text/fixture_set.rb +35 -33
- data/lib/action_text/fragment.rb +8 -3
- data/lib/action_text/gem_version.rb +5 -3
- data/lib/action_text/html_conversion.rb +3 -1
- data/lib/action_text/plain_text_conversion.rb +8 -1
- data/lib/action_text/rendering.rb +7 -2
- data/lib/action_text/serialization.rb +2 -0
- data/lib/action_text/system_test_helper.rb +20 -17
- data/lib/action_text/trix_attachment.rb +4 -2
- data/lib/action_text/version.rb +3 -1
- data/lib/action_text.rb +19 -0
- data/lib/generators/action_text/install/install_generator.rb +29 -5
- data/lib/generators/action_text/install/templates/actiontext.css +0 -4
- data/lib/rails/generators/test_unit/install_generator.rb +2 -0
- data/package.json +7 -7
- metadata +21 -18
@@ -1,8 +1,3 @@
|
|
1
|
-
@charset "UTF-8";
|
2
|
-
/*
|
3
|
-
Trix 1.3.1
|
4
|
-
Copyright © 2020 Basecamp, LLC
|
5
|
-
http://trix-editor.org/*/
|
6
1
|
trix-editor {
|
7
2
|
border: 1px solid #bbb;
|
8
3
|
border-radius: 3px;
|
@@ -10,13 +5,16 @@ trix-editor {
|
|
10
5
|
padding: 0.4em 0.6em;
|
11
6
|
min-height: 5em;
|
12
7
|
outline: none; }
|
8
|
+
|
13
9
|
trix-toolbar * {
|
14
10
|
box-sizing: border-box; }
|
11
|
+
|
15
12
|
trix-toolbar .trix-button-row {
|
16
13
|
display: flex;
|
17
14
|
flex-wrap: nowrap;
|
18
15
|
justify-content: space-between;
|
19
16
|
overflow-x: auto; }
|
17
|
+
|
20
18
|
trix-toolbar .trix-button-group {
|
21
19
|
display: flex;
|
22
20
|
margin-bottom: 10px;
|
@@ -26,14 +24,16 @@ trix-toolbar .trix-button-group {
|
|
26
24
|
border-radius: 3px; }
|
27
25
|
trix-toolbar .trix-button-group:not(:first-child) {
|
28
26
|
margin-left: 1.5vw; }
|
29
|
-
@media (max-
|
27
|
+
@media (max-width: 768px) {
|
30
28
|
trix-toolbar .trix-button-group:not(:first-child) {
|
31
29
|
margin-left: 0; } }
|
30
|
+
|
32
31
|
trix-toolbar .trix-button-group-spacer {
|
33
32
|
flex-grow: 1; }
|
34
|
-
@media (max-
|
33
|
+
@media (max-width: 768px) {
|
35
34
|
trix-toolbar .trix-button-group-spacer {
|
36
35
|
display: none; } }
|
36
|
+
|
37
37
|
trix-toolbar .trix-button {
|
38
38
|
position: relative;
|
39
39
|
float: left;
|
@@ -57,17 +57,18 @@ trix-toolbar .trix-button {
|
|
57
57
|
cursor: pointer; }
|
58
58
|
trix-toolbar .trix-button:disabled {
|
59
59
|
color: rgba(0, 0, 0, 0.125); }
|
60
|
-
@media (max-
|
60
|
+
@media (max-width: 768px) {
|
61
61
|
trix-toolbar .trix-button {
|
62
62
|
letter-spacing: -0.01em;
|
63
63
|
padding: 0 0.3em; } }
|
64
|
+
|
64
65
|
trix-toolbar .trix-button--icon {
|
65
66
|
font-size: inherit;
|
66
67
|
width: 2.6em;
|
67
68
|
height: 1.6em;
|
68
69
|
max-width: calc(0.8em + 4vw);
|
69
70
|
text-indent: -9999px; }
|
70
|
-
@media (max-
|
71
|
+
@media (max-width: 768px) {
|
71
72
|
trix-toolbar .trix-button--icon {
|
72
73
|
height: 2em;
|
73
74
|
max-width: calc(0.8em + 3.5vw); } }
|
@@ -83,7 +84,7 @@ trix-toolbar .trix-button--icon {
|
|
83
84
|
background-position: center;
|
84
85
|
background-repeat: no-repeat;
|
85
86
|
background-size: contain; }
|
86
|
-
@media (max-
|
87
|
+
@media (max-width: 768px) {
|
87
88
|
trix-toolbar .trix-button--icon::before {
|
88
89
|
right: 6%;
|
89
90
|
left: 6%; } }
|
@@ -91,38 +92,54 @@ trix-toolbar .trix-button--icon {
|
|
91
92
|
opacity: 1; }
|
92
93
|
trix-toolbar .trix-button--icon:disabled::before {
|
93
94
|
opacity: 0.125; }
|
95
|
+
|
94
96
|
trix-toolbar .trix-button--icon-attach::before {
|
95
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
97
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M10.5%2018V7.5c0-2.25%203-2.25%203%200V18c0%204.125-6%204.125-6%200V7.5c0-6.375%209-6.375%209%200V18%22%20stroke%3D%22%23000%22%20stroke-width%3D%222%22%20stroke-miterlimit%3D%2210%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E");
|
96
98
|
top: 8%;
|
97
99
|
bottom: 4%; }
|
100
|
+
|
98
101
|
trix-toolbar .trix-button--icon-bold::before {
|
99
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
102
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M6.522%2019.242a.5.5%200%200%201-.5-.5V5.35a.5.5%200%200%201%20.5-.5h5.783c1.347%200%202.46.345%203.24.982.783.64%201.216%201.562%201.216%202.683%200%201.13-.587%202.129-1.476%202.71a.35.35%200%200%200%20.049.613c1.259.56%202.101%201.742%202.101%203.22%200%201.282-.483%202.334-1.363%203.063-.876.726-2.132%201.12-3.66%201.12h-5.89ZM9.27%207.347v3.362h1.97c.766%200%201.347-.17%201.733-.464.38-.291.587-.716.587-1.27%200-.53-.183-.928-.513-1.198-.334-.273-.838-.43-1.505-.43H9.27Zm0%205.606v3.791h2.389c.832%200%201.448-.177%201.853-.497.399-.315.614-.786.614-1.423%200-.62-.22-1.077-.63-1.385-.418-.313-1.053-.486-1.905-.486H9.27Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
103
|
+
|
100
104
|
trix-toolbar .trix-button--icon-italic::before {
|
101
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
105
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M9%205h6.5v2h-2.23l-2.31%2010H13v2H6v-2h2.461l2.306-10H9V5Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
106
|
+
|
102
107
|
trix-toolbar .trix-button--icon-link::before {
|
103
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
108
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M18.948%205.258a4.337%204.337%200%200%200-6.108%200L11.217%206.87a.993.993%200%200%200%200%201.41c.392.39%201.027.39%201.418%200l1.623-1.613a2.323%202.323%200%200%201%203.271%200%202.29%202.29%200%200%201%200%203.251l-2.393%202.38a3.021%203.021%200%200%201-4.255%200l-.05-.049a1.007%201.007%200%200%200-1.418%200%20.993.993%200%200%200%200%201.41l.05.049a5.036%205.036%200%200%200%207.091%200l2.394-2.38a4.275%204.275%200%200%200%200-6.072Zm-13.683%2013.6a4.337%204.337%200%200%200%206.108%200l1.262-1.255a.993.993%200%200%200%200-1.41%201.007%201.007%200%200%200-1.418%200L9.954%2017.45a2.323%202.323%200%200%201-3.27%200%202.29%202.29%200%200%201%200-3.251l2.344-2.331a2.579%202.579%200%200%201%203.631%200c.392.39%201.027.39%201.419%200a.993.993%200%200%200%200-1.41%204.593%204.593%200%200%200-6.468%200l-2.345%202.33a4.275%204.275%200%200%200%200%206.072Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
109
|
+
|
104
110
|
trix-toolbar .trix-button--icon-strike::before {
|
105
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
111
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M6%2014.986c.088%202.647%202.246%204.258%205.635%204.258%203.496%200%205.713-1.728%205.713-4.463%200-.275-.02-.536-.062-.781h-3.461c.398.293.573.654.573%201.123%200%201.035-1.074%201.787-2.646%201.787-1.563%200-2.773-.762-2.91-1.924H6ZM6.432%2010h3.763c-.632-.314-.914-.715-.914-1.273%200-1.045.977-1.739%202.432-1.739%201.475%200%202.52.723%202.617%201.914h2.764c-.05-2.548-2.11-4.238-5.39-4.238-3.145%200-5.392%201.719-5.392%204.316%200%20.363.04.703.12%201.02ZM4%2011a1%201%200%201%200%200%202h15a1%201%200%201%200%200-2H4Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
112
|
+
|
106
113
|
trix-toolbar .trix-button--icon-quote::before {
|
107
|
-
background-image: url(data:image/svg+xml,%3Csvg%
|
114
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M4.581%208.471c.44-.5%201.056-.834%201.758-.995C8.074%207.17%209.201%207.822%2010%208.752c1.354%201.578%201.33%203.555.394%205.277-.941%201.731-2.788%203.163-4.988%203.56a.622.622%200%200%201-.653-.317c-.113-.205-.121-.49.16-.764.294-.286.567-.566.791-.835.222-.266.413-.54.524-.815.113-.28.156-.597.026-.908-.128-.303-.39-.524-.72-.69a3.02%203.02%200%200%201-1.674-2.7c0-.905.283-1.59.72-2.088Zm9.419%200c.44-.5%201.055-.834%201.758-.995%201.734-.306%202.862.346%203.66%201.276%201.355%201.578%201.33%203.555.395%205.277-.941%201.731-2.789%203.163-4.988%203.56a.622.622%200%200%201-.653-.317c-.113-.205-.122-.49.16-.764.294-.286.567-.566.791-.835.222-.266.412-.54.523-.815.114-.28.157-.597.026-.908-.127-.303-.39-.524-.72-.69a3.02%203.02%200%200%201-1.672-2.701c0-.905.283-1.59.72-2.088Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
115
|
+
|
108
116
|
trix-toolbar .trix-button--icon-heading-1::before {
|
109
|
-
background-image: url(data:image/svg+xml,%3Csvg%
|
117
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M21.5%207.5v-3h-12v3H14v13h3v-13h4.5ZM9%2013.5h3.5v-3h-10v3H6v7h3v-7Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
118
|
+
|
110
119
|
trix-toolbar .trix-button--icon-code::before {
|
111
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
120
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M3.293%2011.293a1%201%200%200%200%200%201.414l4%204a1%201%200%201%200%201.414-1.414L5.414%2012l3.293-3.293a1%201%200%200%200-1.414-1.414l-4%204Zm13.414%205.414%204-4a1%201%200%200%200%200-1.414l-4-4a1%201%200%201%200-1.414%201.414L18.586%2012l-3.293%203.293a1%201%200%200%200%201.414%201.414Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
121
|
+
|
112
122
|
trix-toolbar .trix-button--icon-bullet-list::before {
|
113
|
-
background-image: url(data:image/svg+xml,%3Csvg%
|
123
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M5%207.5a1.5%201.5%200%201%200%200-3%201.5%201.5%200%200%200%200%203ZM8%206a1%201%200%200%201%201-1h11a1%201%200%201%201%200%202H9a1%201%200%200%201-1-1Zm1%205a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm0%206a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm-2.5-5a1.5%201.5%200%201%201-3%200%201.5%201.5%200%200%201%203%200ZM5%2019.5a1.5%201.5%200%201%200%200-3%201.5%201.5%200%200%200%200%203Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
124
|
+
|
114
125
|
trix-toolbar .trix-button--icon-number-list::before {
|
115
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
126
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M3%204h2v4H4V5H3V4Zm5%202a1%201%200%200%201%201-1h11a1%201%200%201%201%200%202H9a1%201%200%200%201-1-1Zm1%205a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm0%206a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm-3.5-7H6v1l-1.5%202H6v1H3v-1l1.667-2H3v-1h2.5ZM3%2017v-1h3v4H3v-1h2v-.5H4v-1h1V17H3Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
127
|
+
|
116
128
|
trix-toolbar .trix-button--icon-undo::before {
|
117
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
129
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M3%2014a1%201%200%200%200%201%201h6a1%201%200%201%200%200-2H6.257c2.247-2.764%205.151-3.668%207.579-3.264%202.589.432%204.739%202.356%205.174%205.405a1%201%200%200%200%201.98-.283c-.564-3.95-3.415-6.526-6.825-7.095C11.084%207.25%207.63%208.377%205%2011.39V8a1%201%200%200%200-2%200v6Zm2-1Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
130
|
+
|
118
131
|
trix-toolbar .trix-button--icon-redo::before {
|
119
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
132
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M21%2014a1%201%200%200%201-1%201h-6a1%201%200%201%201%200-2h3.743c-2.247-2.764-5.151-3.668-7.579-3.264-2.589.432-4.739%202.356-5.174%205.405a1%201%200%200%201-1.98-.283c.564-3.95%203.415-6.526%206.826-7.095%203.08-.513%206.534.614%209.164%203.626V8a1%201%200%201%201%202%200v6Zm-2-1Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
133
|
+
|
120
134
|
trix-toolbar .trix-button--icon-decrease-nesting-level::before {
|
121
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
135
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M5%206a1%201%200%200%201%201-1h12a1%201%200%201%201%200%202H6a1%201%200%200%201-1-1Zm4%205a1%201%200%201%200%200%202h9a1%201%200%201%200%200-2H9Zm-3%206a1%201%200%201%200%200%202h12a1%201%200%201%200%200-2H6Zm-3.707-5.707a1%201%200%200%200%200%201.414l2%202a1%201%200%201%200%201.414-1.414L4.414%2012l1.293-1.293a1%201%200%200%200-1.414-1.414l-2%202Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
136
|
+
|
122
137
|
trix-toolbar .trix-button--icon-increase-nesting-level::before {
|
123
|
-
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%
|
138
|
+
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M5%206a1%201%200%200%201%201-1h12a1%201%200%201%201%200%202H6a1%201%200%200%201-1-1Zm4%205a1%201%200%201%200%200%202h9a1%201%200%201%200%200-2H9Zm-3%206a1%201%200%201%200%200%202h12a1%201%200%201%200%200-2H6Zm-2.293-2.293%202-2a1%201%200%200%200%200-1.414l-2-2a1%201%200%201%200-1.414%201.414L3.586%2012l-1.293%201.293a1%201%200%201%200%201.414%201.414Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
|
139
|
+
|
124
140
|
trix-toolbar .trix-dialogs {
|
125
141
|
position: relative; }
|
142
|
+
|
126
143
|
trix-toolbar .trix-dialog {
|
127
144
|
position: absolute;
|
128
145
|
top: 0;
|
@@ -135,6 +152,7 @@ trix-toolbar .trix-dialog {
|
|
135
152
|
border-top: 2px solid #888;
|
136
153
|
border-radius: 5px;
|
137
154
|
z-index: 5; }
|
155
|
+
|
138
156
|
trix-toolbar .trix-input--dialog {
|
139
157
|
font-size: inherit;
|
140
158
|
font-weight: normal;
|
@@ -149,12 +167,15 @@ trix-toolbar .trix-input--dialog {
|
|
149
167
|
-moz-appearance: none; }
|
150
168
|
trix-toolbar .trix-input--dialog.validate:invalid {
|
151
169
|
box-shadow: #F00 0px 0px 1.5px 1px; }
|
170
|
+
|
152
171
|
trix-toolbar .trix-button--dialog {
|
153
172
|
font-size: inherit;
|
154
173
|
padding: 0.5em;
|
155
174
|
border-bottom: none; }
|
175
|
+
|
156
176
|
trix-toolbar .trix-dialog--link {
|
157
177
|
max-width: 600px; }
|
178
|
+
|
158
179
|
trix-toolbar .trix-dialog__link-fields {
|
159
180
|
display: flex;
|
160
181
|
align-items: baseline; }
|
@@ -163,6 +184,7 @@ trix-toolbar .trix-dialog__link-fields {
|
|
163
184
|
trix-toolbar .trix-dialog__link-fields .trix-button-group {
|
164
185
|
flex: 0 0 content;
|
165
186
|
margin: 0; }
|
187
|
+
|
166
188
|
trix-editor [data-trix-mutable]:not(.attachment__caption-editor) {
|
167
189
|
-webkit-user-select: none;
|
168
190
|
-moz-user-select: none;
|
@@ -172,26 +194,32 @@ trix-editor [data-trix-mutable]:not(.attachment__caption-editor) {
|
|
172
194
|
trix-editor [data-trix-mutable]::-moz-selection,
|
173
195
|
trix-editor [data-trix-cursor-target]::-moz-selection, trix-editor [data-trix-mutable] ::-moz-selection {
|
174
196
|
background: none; }
|
197
|
+
|
175
198
|
trix-editor [data-trix-mutable]::selection,
|
176
199
|
trix-editor [data-trix-cursor-target]::selection, trix-editor [data-trix-mutable] ::selection {
|
177
200
|
background: none; }
|
178
201
|
|
179
|
-
trix-editor [data-trix-mutable]
|
202
|
+
trix-editor .attachment__caption-editor:focus[data-trix-mutable]::-moz-selection {
|
180
203
|
background: highlight; }
|
181
|
-
|
204
|
+
|
205
|
+
trix-editor .attachment__caption-editor:focus[data-trix-mutable]::selection {
|
182
206
|
background: highlight; }
|
183
207
|
|
184
208
|
trix-editor [data-trix-mutable].attachment.attachment--file {
|
185
209
|
box-shadow: 0 0 0 2px highlight;
|
186
210
|
border-color: transparent; }
|
211
|
+
|
187
212
|
trix-editor [data-trix-mutable].attachment img {
|
188
213
|
box-shadow: 0 0 0 2px highlight; }
|
214
|
+
|
189
215
|
trix-editor .attachment {
|
190
216
|
position: relative; }
|
191
217
|
trix-editor .attachment:hover {
|
192
218
|
cursor: default; }
|
219
|
+
|
193
220
|
trix-editor .attachment--preview .attachment__caption:hover {
|
194
221
|
cursor: text; }
|
222
|
+
|
195
223
|
trix-editor .attachment__progress {
|
196
224
|
position: absolute;
|
197
225
|
z-index: 1;
|
@@ -203,6 +231,7 @@ trix-editor .attachment__progress {
|
|
203
231
|
transition: opacity 200ms ease-in; }
|
204
232
|
trix-editor .attachment__progress[value="100"] {
|
205
233
|
opacity: 0; }
|
234
|
+
|
206
235
|
trix-editor .attachment__caption-editor {
|
207
236
|
display: inline-block;
|
208
237
|
width: 100%;
|
@@ -218,6 +247,7 @@ trix-editor .attachment__caption-editor {
|
|
218
247
|
outline: none;
|
219
248
|
-webkit-appearance: none;
|
220
249
|
-moz-appearance: none; }
|
250
|
+
|
221
251
|
trix-editor .attachment__toolbar {
|
222
252
|
position: absolute;
|
223
253
|
z-index: 1;
|
@@ -225,8 +255,10 @@ trix-editor .attachment__toolbar {
|
|
225
255
|
left: 0;
|
226
256
|
width: 100%;
|
227
257
|
text-align: center; }
|
258
|
+
|
228
259
|
trix-editor .trix-button-group {
|
229
260
|
display: inline-flex; }
|
261
|
+
|
230
262
|
trix-editor .trix-button {
|
231
263
|
position: relative;
|
232
264
|
float: left;
|
@@ -245,6 +277,7 @@ trix-editor .trix-button {
|
|
245
277
|
background: #cbeefa; }
|
246
278
|
trix-editor .trix-button:not(:disabled) {
|
247
279
|
cursor: pointer; }
|
280
|
+
|
248
281
|
trix-editor .trix-button--remove {
|
249
282
|
text-indent: -9999px;
|
250
283
|
display: inline-block;
|
@@ -266,7 +299,7 @@ trix-editor .trix-button--remove {
|
|
266
299
|
left: 0;
|
267
300
|
opacity: 0.7;
|
268
301
|
content: "";
|
269
|
-
background-image: url(data:image/svg+xml,%3Csvg%20height%3D%2224%22%20width%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M19%206.
|
302
|
+
background-image: url("data:image/svg+xml,%3Csvg%20height%3D%2224%22%20width%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M19%206.41%2017.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22%2F%3E%3Cpath%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%3C%2Fsvg%3E");
|
270
303
|
background-position: center;
|
271
304
|
background-repeat: no-repeat;
|
272
305
|
background-size: 90%; }
|
@@ -274,8 +307,10 @@ trix-editor .trix-button--remove {
|
|
274
307
|
border-color: #333; }
|
275
308
|
trix-editor .trix-button--remove:hover::before {
|
276
309
|
opacity: 1; }
|
310
|
+
|
277
311
|
trix-editor .attachment__metadata-container {
|
278
312
|
position: relative; }
|
313
|
+
|
279
314
|
trix-editor .attachment__metadata {
|
280
315
|
position: absolute;
|
281
316
|
left: 50%;
|
@@ -297,9 +332,11 @@ trix-editor .attachment__metadata {
|
|
297
332
|
trix-editor .attachment__metadata .attachment__size {
|
298
333
|
margin-left: 0.2em;
|
299
334
|
white-space: nowrap; }
|
300
|
-
|
335
|
+
|
301
336
|
.trix-content {
|
302
|
-
line-height: 1.5;
|
337
|
+
line-height: 1.5;
|
338
|
+
overflow-wrap: break-word;
|
339
|
+
word-break: break-word; }
|
303
340
|
.trix-content * {
|
304
341
|
box-sizing: border-box;
|
305
342
|
margin: 0;
|
@@ -347,7 +384,7 @@ trix-editor .attachment__metadata {
|
|
347
384
|
.trix-content .attachment__caption {
|
348
385
|
text-align: center; }
|
349
386
|
.trix-content .attachment__caption .attachment__name + .attachment__size::before {
|
350
|
-
content: '
|
387
|
+
content: ' \2022 '; }
|
351
388
|
.trix-content .attachment--preview {
|
352
389
|
width: 100%;
|
353
390
|
text-align: center; }
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "rails-html-sanitizer"
|
4
6
|
|
5
7
|
module ActionText
|
6
8
|
module ContentHelper
|
7
|
-
mattr_accessor(:sanitizer
|
8
|
-
mattr_accessor(:allowed_tags)
|
9
|
-
mattr_accessor(:allowed_attributes)
|
9
|
+
mattr_accessor(:sanitizer, default: Rails::HTML4::Sanitizer.safe_list_sanitizer.new)
|
10
|
+
mattr_accessor(:allowed_tags)
|
11
|
+
mattr_accessor(:allowed_attributes)
|
10
12
|
mattr_accessor(:scrubber)
|
11
13
|
|
12
14
|
def render_action_text_content(content)
|
@@ -14,8 +16,22 @@ module ActionText
|
|
14
16
|
sanitize_action_text_content(render_action_text_attachments(content))
|
15
17
|
end
|
16
18
|
|
19
|
+
def sanitize_content_attachment(content_attachment)
|
20
|
+
sanitizer.sanitize(
|
21
|
+
content_attachment,
|
22
|
+
tags: sanitizer_allowed_tags,
|
23
|
+
attributes: sanitizer_allowed_attributes,
|
24
|
+
scrubber: scrubber,
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
17
28
|
def sanitize_action_text_content(content)
|
18
|
-
sanitizer.sanitize(
|
29
|
+
sanitizer.sanitize(
|
30
|
+
content.to_html,
|
31
|
+
tags: sanitizer_allowed_tags,
|
32
|
+
attributes: sanitizer_allowed_attributes,
|
33
|
+
scrubber: scrubber,
|
34
|
+
).html_safe
|
19
35
|
end
|
20
36
|
|
21
37
|
def render_action_text_attachments(content)
|
@@ -48,5 +64,13 @@ module ActionText
|
|
48
64
|
|
49
65
|
render(**options).chomp
|
50
66
|
end
|
67
|
+
|
68
|
+
def sanitizer_allowed_tags
|
69
|
+
allowed_tags || (sanitizer.class.allowed_tags + [ ActionText::Attachment.tag_name, "figure", "figcaption" ])
|
70
|
+
end
|
71
|
+
|
72
|
+
def sanitizer_allowed_attributes
|
73
|
+
allowed_attributes || (sanitizer.class.allowed_attributes + ActionText::Attachment::ATTRIBUTES)
|
74
|
+
end
|
51
75
|
end
|
52
76
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/object/try"
|
4
6
|
require "action_view/helpers/tags/placeholderable"
|
5
7
|
|
@@ -7,20 +9,24 @@ module ActionText
|
|
7
9
|
module TagHelper
|
8
10
|
cattr_accessor(:id, instance_accessor: false) { 0 }
|
9
11
|
|
10
|
-
# Returns a
|
11
|
-
# that Trix will write to on changes, so the content will
|
12
|
+
# Returns a `trix-editor` tag that instantiates the Trix JavaScript editor as
|
13
|
+
# well as a hidden field that Trix will write to on changes, so the content will
|
14
|
+
# be sent on form submissions.
|
15
|
+
#
|
16
|
+
# #### Options
|
17
|
+
# * `:class` - Defaults to "trix-content" so that default styles will be
|
18
|
+
# applied. Setting this to a different value will prevent default styles
|
19
|
+
# from being applied.
|
20
|
+
# * `[:data][:direct_upload_url]` - Defaults to `rails_direct_uploads_url`.
|
21
|
+
# * `[:data][:blob_url_template]` - Defaults to
|
22
|
+
# `rails_service_blob_url(":signed_id", ":filename")`.
|
12
23
|
#
|
13
|
-
# ==== Options
|
14
|
-
# * <tt>:class</tt> - Defaults to "trix-content" so that default styles will be applied.
|
15
|
-
# Setting this to a different value will prevent default styles from being applied.
|
16
|
-
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
17
|
-
# * <tt>[:data][:blob_url_template]</tt> - Defaults to <tt>rails_service_blob_url(":signed_id", ":filename")</tt>.
|
18
24
|
#
|
19
|
-
#
|
25
|
+
# #### Example
|
20
26
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
27
|
+
# rich_text_area_tag "content", message.content
|
28
|
+
# # <input type="hidden" name="content" id="trix_input_post_1">
|
29
|
+
# # <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>
|
24
30
|
def rich_text_area_tag(name, value = nil, options = {})
|
25
31
|
options = options.symbolize_keys
|
26
32
|
form = options.delete(:form)
|
@@ -50,38 +56,46 @@ module ActionView::Helpers
|
|
50
56
|
options = @options.stringify_keys
|
51
57
|
add_default_name_and_id(options)
|
52
58
|
options["input"] ||= dom_id(object, [options["id"], :trix_input].compact.join("_")) if object
|
53
|
-
@template_object.rich_text_area_tag(options.delete("name"), options.fetch("value") { value }, options.except("value"))
|
59
|
+
html_tag = @template_object.rich_text_area_tag(options.delete("name"), options.fetch("value") { value }, options.except("value"))
|
60
|
+
error_wrapping(html_tag)
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
57
64
|
module FormHelper
|
58
|
-
# Returns a
|
59
|
-
# that Trix will write to on changes, so the content will
|
65
|
+
# Returns a `trix-editor` tag that instantiates the Trix JavaScript editor as
|
66
|
+
# well as a hidden field that Trix will write to on changes, so the content will
|
67
|
+
# be sent on form submissions.
|
68
|
+
#
|
69
|
+
# #### Options
|
70
|
+
# * `:class` - Defaults to "trix-content" which ensures default styling is
|
71
|
+
# applied.
|
72
|
+
# * `:value` - Adds a default value to the HTML input tag.
|
73
|
+
# * `[:data][:direct_upload_url]` - Defaults to `rails_direct_uploads_url`.
|
74
|
+
# * `[:data][:blob_url_template]` - Defaults to
|
75
|
+
# `rails_service_blob_url(":signed_id", ":filename")`.
|
60
76
|
#
|
61
|
-
# ==== Options
|
62
|
-
# * <tt>:class</tt> - Defaults to "trix-content" which ensures default styling is applied.
|
63
|
-
# * <tt>:value</tt> - Adds a default value to the HTML input tag.
|
64
|
-
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
65
|
-
# * <tt>[:data][:blob_url_template]</tt> - Defaults to <tt>rails_service_blob_url(":signed_id", ":filename")</tt>.
|
66
77
|
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
|
72
|
-
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
78
|
+
# #### Example
|
79
|
+
# rich_text_area :message, :content
|
80
|
+
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
|
81
|
+
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
73
82
|
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
|
78
|
-
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
83
|
+
# rich_text_area :message, :content, value: "<h1>Default message</h1>"
|
84
|
+
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
|
85
|
+
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
79
86
|
def rich_text_area(object_name, method, options = {})
|
80
87
|
Tags::ActionText.new(object_name, method, self, options).render
|
81
88
|
end
|
82
89
|
end
|
83
90
|
|
84
91
|
class FormBuilder
|
92
|
+
# Wraps ActionView::Helpers::FormHelper#rich_text_area for form builders:
|
93
|
+
#
|
94
|
+
# <%= form_with model: @message do |f| %>
|
95
|
+
# <%= f.rich_text_area :content %>
|
96
|
+
# <% end %>
|
97
|
+
#
|
98
|
+
# Please refer to the documentation of the base helper for details.
|
85
99
|
def rich_text_area(method, options = {})
|
86
100
|
@template.rich_text_area(@object_name, method, objectify_options(options))
|
87
101
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionText
|
4
6
|
class EncryptedRichText < RichText
|
5
|
-
self.table_name = "action_text_rich_texts"
|
6
|
-
|
7
7
|
encrypts :body
|
8
8
|
end
|
9
9
|
end
|
10
|
+
|
11
|
+
ActiveSupport.run_load_hooks :action_text_encrypted_rich_text, ActionText::EncryptedRichText
|
@@ -1,27 +1,87 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionText
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# # Action Text RichText
|
7
|
+
#
|
8
|
+
# The RichText record holds the content produced by the Trix editor in a
|
9
|
+
# serialized `body` attribute. It also holds all the references to the embedded
|
10
|
+
# files, which are stored using Active Storage. This record is then associated
|
11
|
+
# with the Active Record model the application desires to have rich text content
|
12
|
+
# using the `has_rich_text` class method.
|
13
|
+
#
|
14
|
+
# class Message < ActiveRecord::Base
|
15
|
+
# has_rich_text :content
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
19
|
+
# message.content #=> #<ActionText::RichText....
|
20
|
+
# message.content.to_s # => "<h1>Funny times!</h1>"
|
21
|
+
# message.content.to_plain_text # => "Funny times!"
|
22
|
+
#
|
23
|
+
# message = Message.create!(content: "<div onclick='action()'>safe<script>unsafe</script></div>")
|
24
|
+
# message.content #=> #<ActionText::RichText....
|
25
|
+
# message.content.to_s # => "<div>safeunsafe</div>"
|
26
|
+
# message.content.to_plain_text # => "safeunsafe"
|
8
27
|
class RichText < Record
|
9
|
-
|
28
|
+
##
|
29
|
+
# :method: to_s
|
30
|
+
#
|
31
|
+
# Safely transforms RichText into an HTML String.
|
32
|
+
#
|
33
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
34
|
+
# message.content.to_s # => "<h1>Funny times!</h1>"
|
35
|
+
#
|
36
|
+
# message = Message.create!(content: "<div onclick='action()'>safe<script>unsafe</script></div>")
|
37
|
+
# message.content.to_s # => "<div>safeunsafe</div>"
|
10
38
|
|
11
|
-
serialize :body, ActionText::Content
|
39
|
+
serialize :body, coder: ActionText::Content
|
12
40
|
delegate :to_s, :nil?, to: :body
|
13
41
|
|
42
|
+
##
|
43
|
+
# :method: record
|
44
|
+
#
|
45
|
+
# Returns the associated record.
|
14
46
|
belongs_to :record, polymorphic: true, touch: true
|
47
|
+
|
48
|
+
##
|
49
|
+
# :method: embeds
|
50
|
+
#
|
51
|
+
# Returns the `ActiveStorage::Blob`s of the embedded files.
|
15
52
|
has_many_attached :embeds
|
16
53
|
|
17
54
|
before_save do
|
18
55
|
self.embeds = body.attachables.grep(ActiveStorage::Blob).uniq if body.present?
|
19
56
|
end
|
20
57
|
|
58
|
+
# Returns a plain-text version of the markup contained by the `body` attribute,
|
59
|
+
# with tags removed but HTML entities encoded.
|
60
|
+
#
|
61
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
62
|
+
# message.content.to_plain_text # => "Funny times!"
|
63
|
+
#
|
64
|
+
# NOTE: that the returned string is not HTML safe and should not be rendered in
|
65
|
+
# browsers.
|
66
|
+
#
|
67
|
+
# message = Message.create!(content: "<script>alert()</script>")
|
68
|
+
# message.content.to_plain_text # => "<script>alert()</script>"
|
21
69
|
def to_plain_text
|
22
70
|
body&.to_plain_text.to_s
|
23
71
|
end
|
24
72
|
|
73
|
+
# Returns the `body` attribute in a format that makes it editable in the Trix
|
74
|
+
# editor. Previews of attachments are rendered inline.
|
75
|
+
#
|
76
|
+
# content = "<h1>Funny Times!</h1><figure data-trix-attachment='{\"sgid\":\"..."\}'></figure>"
|
77
|
+
# message = Message.create!(content: content)
|
78
|
+
# message.content.to_trix_html # =>
|
79
|
+
# # <div class="trix-content">
|
80
|
+
# # <h1>Funny times!</h1>
|
81
|
+
# # <figure data-trix-attachment='{\"sgid\":\"..."\}'>
|
82
|
+
# # <img src="http://example.org/rails/active_storage/.../funny.jpg">
|
83
|
+
# # </figure>
|
84
|
+
# # </div>
|
25
85
|
def to_trix_html
|
26
86
|
body&.to_trix_html
|
27
87
|
end
|
@@ -20,6 +20,6 @@ class CreateActionTextTables < ActiveRecord::Migration[6.0]
|
|
20
20
|
setting = config.options[config.orm][:primary_key_type]
|
21
21
|
primary_key_type = setting || :primary_key
|
22
22
|
foreign_key_type = setting || :bigint
|
23
|
-
[primary_key_type, foreign_key_type]
|
23
|
+
[ primary_key_type, foreign_key_type ]
|
24
24
|
end
|
25
25
|
end
|