marksmith 0.0.15 → 0.1.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 +4 -4
- data/README.md +7 -2
- data/app/assets/images/marksmith/svgs/gallery.svg +1 -0
- data/app/assets/images/marksmith/svgs/markdown.svg +1 -1
- data/app/assets/images/marksmith/svgs/paperclip.svg +1 -1
- data/app/assets/javascripts/list_continuation_controller-full.esm.js +1 -1
- data/app/assets/javascripts/list_continuation_controller-no-stimulus.esm.js +1 -1
- data/app/assets/javascripts/marksmith_controller-full.esm.js +36 -16
- data/app/assets/javascripts/marksmith_controller-no-stimulus.esm.js +36 -16
- data/app/assets/stylesheets/marksmith.css +11 -11
- data/app/components/marksmith/markdown_field/edit_component.html.erb +14 -0
- data/app/components/marksmith/markdown_field/edit_component.rb +3 -0
- data/app/frontend/entrypoints/application.css +5 -0
- data/app/frontend/entrypoints/javascript/controllers/index.js +2 -0
- data/app/frontend/entrypoints/javascript/controllers/marksmith_controller.js +35 -15
- data/app/views/marksmith/markdown_previews/create.turbo_stream.erb +1 -3
- data/app/views/marksmith/shared/_editor.html.erb +27 -9
- data/app/views/marksmith/shared/_rendered_body.html.erb +1 -1
- data/config/locales/marksmith.en.yml +2 -1
- data/lib/marksmith/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e75eb38c87cf55bb17635627ebf0c3fa043e8f936d13e36faa997c311a81767a
|
4
|
+
data.tar.gz: 6817d10490f87128ef997c34b1ffb666af6feb433bdde8a2f817b3f831995985
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04f4b63bc45ad9ac1012aee2841e403678b6ef9ae7198e51c2bfeca355dbf04f97ec64220fd513a9bdc7455d46c79e33036f738c9449b0056d20baebc8bbe27d
|
7
|
+
data.tar.gz: 93db1009535a17a459f69cf34a93febe2505fa68aefc29adb8559bd626cd1d48c32c7578ba857b8b74ea26e3e74691b3c51ce64152d4092e5f81ad7a53c8841d
|
data/README.md
CHANGED
@@ -4,7 +4,9 @@ Marksmith is a GitHub-style markdown editor for Rails apps.
|
|
4
4
|
|
5
5
|
It supports Active Storage attachments and comes with a built-in mardown preview renderer.
|
6
6
|
|
7
|
-
|
7
|
+

|
8
|
+
|
9
|
+

|
8
10
|
|
9
11
|
## Usage
|
10
12
|
|
@@ -107,7 +109,10 @@ bin/importmap pin @avo-hq/marksmith
|
|
107
109
|
|
108
110
|
## Active Storage
|
109
111
|
|
110
|
-
The
|
112
|
+
The editor supports [ActiveStorage](https://guides.rubyonrails.org/active_storage_overview.html) uploads using drag and drop and pasting files into the field.
|
113
|
+
|
114
|
+
Whe used in Avo it supports injecting assets using the [Media Library feature](http://docs.avohq.io/3.0/media-library.html).
|
115
|
+
|
111
116
|
|
112
117
|
## List Continuation
|
113
118
|
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-images"><path d="M18 22H4a2 2 0 0 1-2-2V6"/><path d="m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18"/><circle cx="12" cy="8" r="2"/><rect width="16" height="16" x="6" y="2" rx="2"/></svg>
|
@@ -1 +1 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" role="img"><script xmlns="" src="chrome-extension://hoklmmgfnpapgjgcpechhaamimifchmp/frame_ant/frame_ant.js"/><title>Markdown icon</title><path d="M22.269 19.385H1.731a1.73 1.73 0 0 1-1.73-1.73V6.345a1.73 1.73 0 0 1 1.73-1.73h20.538a1.73 1.73 0 0 1 1.73 1.73v11.308a1.73 1.73 0 0 1-1.73 1.731zm-16.5-3.462v-4.5l2.308 2.885 2.307-2.885v4.5h2.308V8.078h-2.308l-2.307 2.885-2.308-2.885H3.461v7.847zM21.231 12h-2.308V8.077h-2.307V12h-2.308l3.461 4.039z"/></svg>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
2
2
|
<path stroke-linecap="round" stroke-linejoin="round" d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" />
|
3
3
|
</svg>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
Marksmith 0.0
|
2
|
+
Marksmith 0.1.0
|
3
3
|
*/
|
4
4
|
var MarksmithController = (function () {
|
5
5
|
'use strict';
|
@@ -2825,6 +2825,8 @@ var MarksmithController = (function () {
|
|
2825
2825
|
previewUrl: String,
|
2826
2826
|
extraPreviewParams: { type: Object, default: {} },
|
2827
2827
|
fieldId: String,
|
2828
|
+
galleryEnabled: { type: Boolean, default: false },
|
2829
|
+
galleryOpenPath: String,
|
2828
2830
|
}
|
2829
2831
|
|
2830
2832
|
static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']
|
@@ -2877,14 +2879,14 @@ var MarksmithController = (function () {
|
|
2877
2879
|
|
2878
2880
|
dropUpload(event) {
|
2879
2881
|
event.preventDefault();
|
2880
|
-
this
|
2882
|
+
this.#uploadFiles(event.dataTransfer.files);
|
2881
2883
|
}
|
2882
2884
|
|
2883
2885
|
pasteUpload(event) {
|
2884
2886
|
if (!event.clipboardData.files.length) return
|
2885
2887
|
|
2886
2888
|
event.preventDefault();
|
2887
|
-
this
|
2889
|
+
this.#uploadFiles(event.clipboardData.files);
|
2888
2890
|
}
|
2889
2891
|
|
2890
2892
|
buttonUpload(event) {
|
@@ -2896,40 +2898,58 @@ var MarksmithController = (function () {
|
|
2896
2898
|
fileInput.accept = 'image/*,.pdf,.doc,.docx,.txt';
|
2897
2899
|
|
2898
2900
|
fileInput.addEventListener('change', (e) => {
|
2899
|
-
this
|
2901
|
+
this.#uploadFiles(e.target.files);
|
2900
2902
|
});
|
2901
2903
|
|
2902
2904
|
fileInput.click();
|
2903
2905
|
}
|
2904
2906
|
|
2905
|
-
|
2906
|
-
|
2907
|
+
// Invoked by the other controllers (media-library)
|
2908
|
+
insertAttachments(attachments, event) {
|
2909
|
+
const editorAttachments = attachments.map((attachment) => {
|
2910
|
+
const { blob, path, url } = attachment;
|
2911
|
+
const link = this.#markdownLinkFromUrl(blob.filename, path, blob.content_type);
|
2912
|
+
|
2913
|
+
this.#injectLink(link);
|
2914
|
+
});
|
2915
|
+
|
2916
|
+
this.editor?.chain().focus().setAttachment(editorAttachments).run();
|
2917
|
+
}
|
2918
|
+
|
2919
|
+
#uploadFiles(files) {
|
2920
|
+
Array.from(files).forEach((file) => this.#uploadFile(file));
|
2907
2921
|
}
|
2908
2922
|
|
2909
|
-
uploadFile(file) {
|
2923
|
+
#uploadFile(file) {
|
2910
2924
|
const upload = new DirectUpload(file, this.attachUrlValue);
|
2911
2925
|
|
2912
2926
|
upload.create((error, blob) => {
|
2913
2927
|
if (error) {
|
2914
2928
|
console.log('Error', error);
|
2915
2929
|
} else {
|
2916
|
-
const
|
2917
|
-
|
2918
|
-
const end = this.fieldElementTarget.selectionEnd;
|
2919
|
-
this.fieldElementTarget.setRangeText(text, start, end);
|
2930
|
+
const link = this.#markdownLinkFromUrl(blob.filename, this.#pathFromBlob(blob), blob.content_type);
|
2931
|
+
this.#injectLink(link);
|
2920
2932
|
}
|
2921
2933
|
});
|
2922
2934
|
}
|
2923
2935
|
|
2924
|
-
|
2925
|
-
const
|
2926
|
-
const
|
2927
|
-
|
2936
|
+
#injectLink(link) {
|
2937
|
+
const start = this.fieldElementTarget.selectionStart;
|
2938
|
+
const end = this.fieldElementTarget.selectionEnd;
|
2939
|
+
this.fieldElementTarget.setRangeText(link, start, end);
|
2940
|
+
}
|
2941
|
+
|
2942
|
+
#pathFromBlob(blob) {
|
2943
|
+
return `/rails/active_storage/blobs/redirect/${blob.signed_id}/${blob.filename}`
|
2944
|
+
}
|
2945
|
+
|
2946
|
+
#markdownLinkFromUrl(filename, url, contentType) {
|
2947
|
+
const prefix = (this.#isImage(contentType) ? '!' : '');
|
2928
2948
|
|
2929
2949
|
return `${prefix}[${filename}](${url})\n`
|
2930
2950
|
}
|
2931
2951
|
|
2932
|
-
isImage(contentType) {
|
2952
|
+
#isImage(contentType) {
|
2933
2953
|
return ['image/jpeg', 'image/gif', 'image/png'].includes(contentType)
|
2934
2954
|
}
|
2935
2955
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
Marksmith 0.0
|
2
|
+
Marksmith 0.1.0
|
3
3
|
*/
|
4
4
|
var MarksmithController = (function (stimulus) {
|
5
5
|
'use strict';
|
@@ -2335,6 +2335,8 @@ var MarksmithController = (function (stimulus) {
|
|
2335
2335
|
previewUrl: String,
|
2336
2336
|
extraPreviewParams: { type: Object, default: {} },
|
2337
2337
|
fieldId: String,
|
2338
|
+
galleryEnabled: { type: Boolean, default: false },
|
2339
|
+
galleryOpenPath: String,
|
2338
2340
|
}
|
2339
2341
|
|
2340
2342
|
static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']
|
@@ -2387,14 +2389,14 @@ var MarksmithController = (function (stimulus) {
|
|
2387
2389
|
|
2388
2390
|
dropUpload(event) {
|
2389
2391
|
event.preventDefault();
|
2390
|
-
this
|
2392
|
+
this.#uploadFiles(event.dataTransfer.files);
|
2391
2393
|
}
|
2392
2394
|
|
2393
2395
|
pasteUpload(event) {
|
2394
2396
|
if (!event.clipboardData.files.length) return
|
2395
2397
|
|
2396
2398
|
event.preventDefault();
|
2397
|
-
this
|
2399
|
+
this.#uploadFiles(event.clipboardData.files);
|
2398
2400
|
}
|
2399
2401
|
|
2400
2402
|
buttonUpload(event) {
|
@@ -2406,40 +2408,58 @@ var MarksmithController = (function (stimulus) {
|
|
2406
2408
|
fileInput.accept = 'image/*,.pdf,.doc,.docx,.txt';
|
2407
2409
|
|
2408
2410
|
fileInput.addEventListener('change', (e) => {
|
2409
|
-
this
|
2411
|
+
this.#uploadFiles(e.target.files);
|
2410
2412
|
});
|
2411
2413
|
|
2412
2414
|
fileInput.click();
|
2413
2415
|
}
|
2414
2416
|
|
2415
|
-
|
2416
|
-
|
2417
|
+
// Invoked by the other controllers (media-library)
|
2418
|
+
insertAttachments(attachments, event) {
|
2419
|
+
const editorAttachments = attachments.map((attachment) => {
|
2420
|
+
const { blob, path, url } = attachment;
|
2421
|
+
const link = this.#markdownLinkFromUrl(blob.filename, path, blob.content_type);
|
2422
|
+
|
2423
|
+
this.#injectLink(link);
|
2424
|
+
});
|
2425
|
+
|
2426
|
+
this.editor?.chain().focus().setAttachment(editorAttachments).run();
|
2427
|
+
}
|
2428
|
+
|
2429
|
+
#uploadFiles(files) {
|
2430
|
+
Array.from(files).forEach((file) => this.#uploadFile(file));
|
2417
2431
|
}
|
2418
2432
|
|
2419
|
-
uploadFile(file) {
|
2433
|
+
#uploadFile(file) {
|
2420
2434
|
const upload = new DirectUpload(file, this.attachUrlValue);
|
2421
2435
|
|
2422
2436
|
upload.create((error, blob) => {
|
2423
2437
|
if (error) {
|
2424
2438
|
console.log('Error', error);
|
2425
2439
|
} else {
|
2426
|
-
const
|
2427
|
-
|
2428
|
-
const end = this.fieldElementTarget.selectionEnd;
|
2429
|
-
this.fieldElementTarget.setRangeText(text, start, end);
|
2440
|
+
const link = this.#markdownLinkFromUrl(blob.filename, this.#pathFromBlob(blob), blob.content_type);
|
2441
|
+
this.#injectLink(link);
|
2430
2442
|
}
|
2431
2443
|
});
|
2432
2444
|
}
|
2433
2445
|
|
2434
|
-
|
2435
|
-
const
|
2436
|
-
const
|
2437
|
-
|
2446
|
+
#injectLink(link) {
|
2447
|
+
const start = this.fieldElementTarget.selectionStart;
|
2448
|
+
const end = this.fieldElementTarget.selectionEnd;
|
2449
|
+
this.fieldElementTarget.setRangeText(link, start, end);
|
2450
|
+
}
|
2451
|
+
|
2452
|
+
#pathFromBlob(blob) {
|
2453
|
+
return `/rails/active_storage/blobs/redirect/${blob.signed_id}/${blob.filename}`
|
2454
|
+
}
|
2455
|
+
|
2456
|
+
#markdownLinkFromUrl(filename, url, contentType) {
|
2457
|
+
const prefix = (this.#isImage(contentType) ? '!' : '');
|
2438
2458
|
|
2439
2459
|
return `${prefix}[${filename}](${url})\n`
|
2440
2460
|
}
|
2441
2461
|
|
2442
|
-
isImage(contentType) {
|
2462
|
+
#isImage(contentType) {
|
2443
2463
|
return ['image/jpeg', 'image/gif', 'image/png'].includes(contentType)
|
2444
2464
|
}
|
2445
2465
|
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
/*! tailwindcss v4.0.
|
2
|
-
:root {
|
1
|
+
/*! tailwindcss v4.0.1 | MIT License | https://tailwindcss.com */
|
2
|
+
:root, :host {
|
3
3
|
--ms-font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
4
4
|
'Segoe UI Symbol', 'Noto Color Emoji';
|
5
5
|
--ms-font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
|
@@ -788,6 +788,9 @@
|
|
788
788
|
margin-bottom: 0;
|
789
789
|
}
|
790
790
|
}
|
791
|
+
.ms\:mr-1 {
|
792
|
+
margin-right: calc(var(--ms-spacing) * 1);
|
793
|
+
}
|
791
794
|
.ms\:block {
|
792
795
|
display: block;
|
793
796
|
}
|
@@ -841,9 +844,6 @@
|
|
841
844
|
.ms\:items-center {
|
842
845
|
align-items: center;
|
843
846
|
}
|
844
|
-
.ms\:gap-x-2 {
|
845
|
-
column-gap: calc(var(--ms-spacing) * 2);
|
846
|
-
}
|
847
847
|
.ms\:gap-y-1 {
|
848
848
|
row-gap: calc(var(--ms-spacing) * 1);
|
849
849
|
}
|
@@ -854,6 +854,9 @@
|
|
854
854
|
margin-inline-end: calc(calc(var(--ms-spacing) * 2) * calc(1 - var(--tw-space-x-reverse)));
|
855
855
|
}
|
856
856
|
}
|
857
|
+
.ms\:overflow-auto {
|
858
|
+
overflow: auto;
|
859
|
+
}
|
857
860
|
.ms\:rounded {
|
858
861
|
border-radius: 0.25rem;
|
859
862
|
}
|
@@ -900,15 +903,9 @@
|
|
900
903
|
.ms\:px-2 {
|
901
904
|
padding-inline: calc(var(--ms-spacing) * 2);
|
902
905
|
}
|
903
|
-
.ms\:px-3 {
|
904
|
-
padding-inline: calc(var(--ms-spacing) * 3);
|
905
|
-
}
|
906
906
|
.ms\:py-1 {
|
907
907
|
padding-block: calc(var(--ms-spacing) * 1);
|
908
908
|
}
|
909
|
-
.ms\:py-2 {
|
910
|
-
padding-block: calc(var(--ms-spacing) * 2);
|
911
|
-
}
|
912
909
|
.ms\:py-px {
|
913
910
|
padding-block: 1px;
|
914
911
|
}
|
@@ -1027,6 +1024,9 @@
|
|
1027
1024
|
flex-direction: row;
|
1028
1025
|
}
|
1029
1026
|
}
|
1027
|
+
.marksmith, .marksmith * {
|
1028
|
+
box-sizing: border-box;
|
1029
|
+
}
|
1030
1030
|
.ms\:button-spinner {
|
1031
1031
|
width: 24px;
|
1032
1032
|
height: 24px;
|
@@ -1,5 +1,19 @@
|
|
1
1
|
<%= field_wrapper **field_wrapper_args, full_width: true do %>
|
2
2
|
<%= @form.marksmith @field.id,
|
3
|
+
gallery: {
|
4
|
+
enabled: true,
|
5
|
+
open_path: avo.attach_media_path,
|
6
|
+
turbo_frame: ::Avo::MODAL_FRAME_ID,
|
7
|
+
params: {
|
8
|
+
resource_name: @resource.singular_route_key,
|
9
|
+
controller_name: "marksmith",
|
10
|
+
controller_selector: "[data-unique-selector='#{unique_id}']",
|
11
|
+
record_id: @resource&.record&.to_param,
|
12
|
+
}
|
13
|
+
},
|
14
|
+
controller_data_attributes: {
|
15
|
+
unique_selector: unique_id, # it must coincide with the selector above
|
16
|
+
},
|
3
17
|
extra_preview_params: {
|
4
18
|
resource_class: @resource.class.name,
|
5
19
|
field_id: field.id,
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import { application } from "./application"
|
2
2
|
|
3
3
|
import MarksmithController from "./marksmith_controller"
|
4
|
+
import ListContinuationController from "./list_continuation_controller"
|
4
5
|
// import MarksmithController from "./../../../../../app/assets/builds/marksmith.esm.js"
|
5
6
|
// console.log(MarksmithController)
|
6
7
|
|
7
8
|
application.register("marksmith", MarksmithController)
|
9
|
+
application.register("list-continuation", ListContinuationController)
|
@@ -15,6 +15,8 @@ export default class extends Controller {
|
|
15
15
|
previewUrl: String,
|
16
16
|
extraPreviewParams: { type: Object, default: {} },
|
17
17
|
fieldId: String,
|
18
|
+
galleryEnabled: { type: Boolean, default: false },
|
19
|
+
galleryOpenPath: String,
|
18
20
|
}
|
19
21
|
|
20
22
|
static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']
|
@@ -67,14 +69,14 @@ export default class extends Controller {
|
|
67
69
|
|
68
70
|
dropUpload(event) {
|
69
71
|
event.preventDefault()
|
70
|
-
this
|
72
|
+
this.#uploadFiles(event.dataTransfer.files)
|
71
73
|
}
|
72
74
|
|
73
75
|
pasteUpload(event) {
|
74
76
|
if (!event.clipboardData.files.length) return
|
75
77
|
|
76
78
|
event.preventDefault()
|
77
|
-
this
|
79
|
+
this.#uploadFiles(event.clipboardData.files)
|
78
80
|
}
|
79
81
|
|
80
82
|
buttonUpload(event) {
|
@@ -86,40 +88,58 @@ export default class extends Controller {
|
|
86
88
|
fileInput.accept = 'image/*,.pdf,.doc,.docx,.txt'
|
87
89
|
|
88
90
|
fileInput.addEventListener('change', (e) => {
|
89
|
-
this
|
91
|
+
this.#uploadFiles(e.target.files)
|
90
92
|
})
|
91
93
|
|
92
94
|
fileInput.click()
|
93
95
|
}
|
94
96
|
|
95
|
-
|
96
|
-
|
97
|
+
// Invoked by the other controllers (media-library)
|
98
|
+
insertAttachments(attachments, event) {
|
99
|
+
const editorAttachments = attachments.map((attachment) => {
|
100
|
+
const { blob, path, url } = attachment
|
101
|
+
const link = this.#markdownLinkFromUrl(blob.filename, path, blob.content_type)
|
102
|
+
|
103
|
+
this.#injectLink(link)
|
104
|
+
})
|
105
|
+
|
106
|
+
this.editor?.chain().focus().setAttachment(editorAttachments).run();
|
107
|
+
}
|
108
|
+
|
109
|
+
#uploadFiles(files) {
|
110
|
+
Array.from(files).forEach((file) => this.#uploadFile(file))
|
97
111
|
}
|
98
112
|
|
99
|
-
uploadFile(file) {
|
113
|
+
#uploadFile(file) {
|
100
114
|
const upload = new DirectUpload(file, this.attachUrlValue)
|
101
115
|
|
102
116
|
upload.create((error, blob) => {
|
103
117
|
if (error) {
|
104
118
|
console.log('Error', error)
|
105
119
|
} else {
|
106
|
-
const
|
107
|
-
|
108
|
-
const end = this.fieldElementTarget.selectionEnd
|
109
|
-
this.fieldElementTarget.setRangeText(text, start, end)
|
120
|
+
const link = this.#markdownLinkFromUrl(blob.filename, this.#pathFromBlob(blob), blob.content_type)
|
121
|
+
this.#injectLink(link)
|
110
122
|
}
|
111
123
|
})
|
112
124
|
}
|
113
125
|
|
114
|
-
|
115
|
-
const
|
116
|
-
const
|
117
|
-
|
126
|
+
#injectLink(link) {
|
127
|
+
const start = this.fieldElementTarget.selectionStart
|
128
|
+
const end = this.fieldElementTarget.selectionEnd
|
129
|
+
this.fieldElementTarget.setRangeText(link, start, end)
|
130
|
+
}
|
131
|
+
|
132
|
+
#pathFromBlob(blob) {
|
133
|
+
return `/rails/active_storage/blobs/redirect/${blob.signed_id}/${blob.filename}`
|
134
|
+
}
|
135
|
+
|
136
|
+
#markdownLinkFromUrl(filename, url, contentType) {
|
137
|
+
const prefix = (this.#isImage(contentType) ? '!' : '')
|
118
138
|
|
119
139
|
return `${prefix}[${filename}](${url})\n`
|
120
140
|
}
|
121
141
|
|
122
|
-
isImage(contentType) {
|
142
|
+
#isImage(contentType) {
|
123
143
|
return ['image/jpeg', 'image/gif', 'image/png'].includes(contentType)
|
124
144
|
}
|
125
145
|
}
|
@@ -1,6 +1,4 @@
|
|
1
1
|
<%= turbo_stream.update params[:element_id] do %>
|
2
|
-
|
3
|
-
<%= render partial: "marksmith/shared/rendered_body", locals: { body: @body } %>
|
4
|
-
</div>
|
2
|
+
<%= render partial: "marksmith/shared/rendered_body", locals: { body: @body } %>
|
5
3
|
<% end %>
|
6
4
|
|
@@ -13,19 +13,32 @@
|
|
13
13
|
local_assigns[:value] || nil
|
14
14
|
end
|
15
15
|
extra_preview_params = local_assigns[:extra_preview_params] || {}
|
16
|
+
|
17
|
+
# Used by Avo and other adapters to enable the gallery link.
|
18
|
+
gallery_enabled = local_assigns.dig(:gallery, :enabled) || false
|
19
|
+
gallery_open_path = local_assigns.dig(:gallery, :open_path) || nil
|
20
|
+
gallery_params = local_assigns.dig(:gallery, :params) || {}
|
21
|
+
if gallery_open_path.present?
|
22
|
+
gallery_full_path = gallery_open_path + "?" + gallery_params.map { |k,v| "#{k}=#{v}" }.join('&')
|
23
|
+
else
|
24
|
+
gallery_full_path = nil
|
25
|
+
end
|
26
|
+
gallery_turbo_frame = local_assigns.dig(:gallery, :turbo_frame) || nil
|
16
27
|
%>
|
17
28
|
<%= content_tag :div,
|
18
|
-
class: "ms:block ms:flex-col ms:w-full ms:border ms:border-neutral-300 ms:rounded ms:@container ms:focus-within:border-neutral-400",
|
29
|
+
class: "marksmith ms:block ms:flex-col ms:w-full ms:border ms:border-neutral-300 ms:rounded ms:@container ms:focus-within:border-neutral-400",
|
19
30
|
data: {
|
20
31
|
controller: "marksmith list-continuation",
|
21
32
|
action: "
|
22
33
|
beforeinput->list-continuation#handleBeforeInput
|
23
34
|
input->list-continuation#handleInput
|
24
35
|
",
|
36
|
+
unique_selector: ".#{@input_id}", # used to pinpoint the exact element in which to insert the attachment
|
25
37
|
marksmith_preview_url_value: marksmith.markdown_previews_path,
|
26
38
|
marksmith_active_tab_class: "bg-white",
|
27
39
|
marksmith_attach_url_value: main_app.rails_direct_uploads_url,
|
28
40
|
marksmith_extra_preview_params_value: extra_preview_params.as_json,
|
41
|
+
**local_assigns.fetch(:controller_data_attributes, {})
|
29
42
|
} do %>
|
30
43
|
<% toggle_button_classes = class_names(marksmith_button_classes, "ms:bg-neutral-200 ms:border-0 ms:bg-none ms:text-sm ms:hover:bg-neutral-300 ms:uppercase ms:text-xs ms:font-semibold ms:text-neutral-800") %>
|
31
44
|
<div class="ms:flex-1 ms:flex-col-reverse ms:@md:flex-row ms:grow ms:flex ms:justify-bewteen ms:bg-neutral-50 ms:rounded ms:px-2 ms:py-1 ms:gap-y-1">
|
@@ -52,11 +65,11 @@
|
|
52
65
|
</markdown-toolbar>
|
53
66
|
</div>
|
54
67
|
<% toolbar_button_classes = "ms:cursor-pointer ms:hover:bg-neutral-100 ms:px-1 ms:py-px ms:rounded ms:text-sm" %>
|
55
|
-
<div class="ms:border-t ms:w-full ms:border-neutral-300 ms:flex">
|
56
|
-
<%= content_tag :div, class: "ms:flex ms:flex-col ms:size-full", data: { marksmith_target: "fieldContainer" } do %>
|
68
|
+
<div class="ms:border-t ms:w-full ms:border-neutral-300 ms:flex ms:flex-1">
|
69
|
+
<%= content_tag :div, class: "ms:flex ms:flex-1 ms:flex-col ms:size-full", data: { marksmith_target: "fieldContainer" } do %>
|
57
70
|
<%= text_area_tag field_name, value,
|
58
71
|
id: name,
|
59
|
-
class: class_names("ms:flex ms:flex-1 ms:rounded ms:border-none ms:
|
72
|
+
class: class_names("ms:flex ms:flex-1 ms:rounded ms:border-none ms:resize-y ms:focus:outline-none ms:font-mono ms:focus:ring-0 ms:leading-normal ms:p-2", classes),
|
60
73
|
rows: rows,
|
61
74
|
data: {
|
62
75
|
action: "drop->marksmith#dropUpload paste->marksmith#pasteUpload",
|
@@ -68,17 +81,22 @@
|
|
68
81
|
autofocus:,
|
69
82
|
style:
|
70
83
|
%>
|
71
|
-
<div class="ms:flex ms:flex-1 ms:flex-grow ms:space-x-2 ms:py-1 ms:border-t ms:border-neutral-300 ms:px-2 ms:font-sans ms:text-sm">
|
72
|
-
<%= link_to "https://docs.github.com/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax", target: "_blank", class: class_names("ms:flex ms:items-center ms:
|
73
|
-
<%= image_tag asset_path("marksmith/svgs/markdown.svg"), class: "ms:inline ms:size-4" %> <%= t("marksmith.markdown_is_supported").humanize %>
|
84
|
+
<div class="ms:flex ms:flex-1 ms:flex-grow ms:space-x-2 ms:py-1 ms:border-t ms:border-neutral-300 ms:px-2 ms:font-sans ms:text-sm ms:p-2">
|
85
|
+
<%= link_to "https://docs.github.com/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax", target: "_blank", class: class_names("ms:flex ms:items-center ms:text-neutral-800 ms:no-underline", toolbar_button_classes) do %>
|
86
|
+
<%= image_tag asset_path("marksmith/svgs/markdown.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.markdown_is_supported").humanize %>
|
74
87
|
<% end %>
|
75
88
|
<%= button_tag data: { action: "click->marksmith#buttonUpload" }, class: class_names("ms:bg-none ms:border-none ms:bg-transparent ms:text-neutral-600 ms:items-center ms:flex", toolbar_button_classes) do %>
|
76
|
-
<%= image_tag asset_path("marksmith/svgs/paperclip.svg"), class: "ms:inline ms:size-4" %> <%= t("marksmith.
|
89
|
+
<%= image_tag asset_path("marksmith/svgs/paperclip.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.upload_files").humanize %>
|
90
|
+
<% end %>
|
91
|
+
<% if gallery_enabled %>
|
92
|
+
<%= link_to gallery_full_path, data: { turbo_frame: gallery_turbo_frame }, class: class_names("ms:flex ms:items-center ms:text-neutral-800 ms:no-underline", toolbar_button_classes) do %>
|
93
|
+
<%= image_tag asset_path("marksmith/svgs/gallery.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.attach_from_gallery").humanize %>
|
94
|
+
<% end %>
|
77
95
|
<% end %>
|
78
96
|
</div>
|
79
97
|
<% end %>
|
80
98
|
<%= content_tag :div,
|
81
|
-
class: "ms:hidden ms:markdown-preview ms:size-full ms:flex-1 ms:flex ms:size-full",
|
99
|
+
class: "ms:hidden ms:markdown-preview ms:size-full ms:flex-1 ms:flex ms:size-full ms:p-2 ms:overflow-auto",
|
82
100
|
id: "markdown-preview-#{name}",
|
83
101
|
data: {
|
84
102
|
marksmith_target: "previewElement",
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= content_tag :div, class: "ms:
|
1
|
+
<%= content_tag :div, class: "ms:block ms:w-full ms:prose ms:max-w-none ms:prose-neutral" do %>
|
2
2
|
<%= sanitize(body, tags: %w(table th tr td span) + ActionView::Helpers::SanitizeHelper.sanitizer_vendor.safe_list_sanitizer.allowed_tags.to_a) %>
|
3
3
|
<% end %>
|
@@ -30,7 +30,7 @@
|
|
30
30
|
|
31
31
|
en:
|
32
32
|
marksmith:
|
33
|
-
|
33
|
+
attach_from_gallery: Attach from gallery
|
34
34
|
bold: bold
|
35
35
|
code: code
|
36
36
|
header: header
|
@@ -43,4 +43,5 @@ en:
|
|
43
43
|
quote: quote
|
44
44
|
task_list: task_list
|
45
45
|
unordered_list: unordered list
|
46
|
+
upload_files: upload files
|
46
47
|
write: write
|
data/lib/marksmith/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marksmith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Marin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- app/assets/images/marksmith/svgs/code.svg
|
54
54
|
- app/assets/images/marksmith/svgs/color-swatch copy.svg
|
55
55
|
- app/assets/images/marksmith/svgs/color-swatch.svg
|
56
|
+
- app/assets/images/marksmith/svgs/gallery.svg
|
56
57
|
- app/assets/images/marksmith/svgs/header.svg
|
57
58
|
- app/assets/images/marksmith/svgs/image.svg
|
58
59
|
- app/assets/images/marksmith/svgs/italic.svg
|
@@ -123,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
124
|
- !ruby/object:Gem::Version
|
124
125
|
version: '0'
|
125
126
|
requirements: []
|
126
|
-
rubygems_version: 3.
|
127
|
+
rubygems_version: 3.5.9
|
127
128
|
signing_key:
|
128
129
|
specification_version: 4
|
129
130
|
summary: Marksmith is a GitHub-style markdown editor for Ruby on Rails applications.
|