ordars_rails_editor 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 +7 -0
- data/MIT-LICENSE +21 -0
- data/README.md +95 -0
- data/app/assets/stylesheets/ordars_rails_editor.css +110 -0
- data/app/helpers/ordars_rails_editor/editor_helper.rb +39 -0
- data/app/javascript/ordars_rails_editor/index.js +420 -0
- data/app/javascript/ordars_rails_editor/tiptap.js +97 -0
- data/app/views/ordars_rails_editor/_editor.html.erb +84 -0
- data/config/importmap.rb +5 -0
- data/lib/ordars_rails_editor/engine.rb +38 -0
- data/lib/ordars_rails_editor/sanitizer.rb +67 -0
- data/lib/ordars_rails_editor/version.rb +5 -0
- data/lib/ordars_rails_editor.rb +18 -0
- metadata +70 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6fbf145086f8e6b153689793f57f6bcf299a1088b5cfafc10d1ca11ce0768fa7
|
|
4
|
+
data.tar.gz: e637103d4e12538c591029ebe39ad8721f3b6ba52658ccd0859cf6b86ea78ff5
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9f8790e29a6543e7c25a0a78f1dfc890809f4f6f5c43d8442e69cca722681250b73aa68fcd69d691104a342ee950f160cb3fb2a3716abe88b3f2e9f1612bcde1
|
|
7
|
+
data.tar.gz: 435fde6dd8843bea2001ac1c9b6f49d8f8a08398cf67526829fd33f39283a68518003eb805cfb4467a7b5e3161e0df58c6f00bd53ffa50ab17ef5d6fa61aac96
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 reshacs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# ordars-rails-editor
|
|
2
|
+
|
|
3
|
+
게시판형 WYSIWYG 에디터 Rails gem — 편집 코어는 **Tiptap/ProseMirror**(번들 내장, 외부 CDN 의존 0),
|
|
4
|
+
gem 은 이토랜드 스타일의 툴바·팔레트·말풍선 툴팁·HTML 소스 모드·첨부 패널·업로드 어댑터·
|
|
5
|
+
서버측 새니타이저·CSS 변수 테마를 제공한다.
|
|
6
|
+
|
|
7
|
+
## 설치
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
# Gemfile
|
|
11
|
+
gem "ordars_rails_editor"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```css
|
|
15
|
+
/* application.css 등 */
|
|
16
|
+
@import url("ordars_rails_editor.css");
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
// application.js (importmap 앱 — pin 은 gem 이 자동 등록)
|
|
21
|
+
import "ordars_rails_editor"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 사용
|
|
25
|
+
|
|
26
|
+
```erb
|
|
27
|
+
<%= form_with ... do %>
|
|
28
|
+
<%= ore_editor name: "board_post[content]",
|
|
29
|
+
content: @post.content_html,
|
|
30
|
+
placeholder: "내용을 입력하세요",
|
|
31
|
+
upload_url: board_editor_upload_path(...),
|
|
32
|
+
attach_name: "attachment_file_ids[]" %>
|
|
33
|
+
<% end %>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
옵션: `max_images:` `max_videos:` `max_mb:`(첨부 한도 표시), `attach: false`(첨부 패널 없이 본문만), `id:`.
|
|
37
|
+
|
|
38
|
+
### 저장 (필수 — 서버측 새니타이즈)
|
|
39
|
+
|
|
40
|
+
에디터 HTML 은 **저장 직전 반드시** 화이트리스트 새니타이저를 통과시킨다:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
post.content = OrdarsRailsEditor::Sanitizer.clean(params[:board_post][:content])
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
허용 스키마: `p br strong b em i s del u code pre blockquote ul ol li h1-h3 hr a img span` +
|
|
47
|
+
`style`(color·background-color·font-size·text-align 만) + `a[href target rel]` +
|
|
48
|
+
`img[src alt width height data-file-id]`. 링크 스킴은 http/https/mailto/tel 만.
|
|
49
|
+
|
|
50
|
+
### 업로드 계약 (upload_url)
|
|
51
|
+
|
|
52
|
+
`POST {upload_url}` — multipart `file` (+`X-CSRF-Token` 헤더). 응답 JSON:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{ "id": "uuid", "url": "https://...", "thumbnail_url": "https://...",
|
|
56
|
+
"file_name": "a.jpg", "file_size": 12345, "file_type": "image" }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
실패 시 `{ "error": "메시지" }` — 에디터가 `ore:error` 이벤트를 발화하고 `window.showSnackbar` 가 있으면 사용.
|
|
60
|
+
|
|
61
|
+
- 본문 삽입 이미지는 `<img src=... data-file-id=...>` 로 저장 — **비공개 저장소라면 렌더 시점에
|
|
62
|
+
data-file-id 로 URL 을 치환**하는 것을 권장(만료되는 presigned URL 을 본문에 박지 않기).
|
|
63
|
+
- 첨부 패널의 파일은 행마다 `<input type="hidden" name="{attach_name}" value="{id}">` 로 폼에 실린다.
|
|
64
|
+
- `upload_url` 미지정 = 로컬 모드(데모용): 이미지 dataURL 삽입, 첨부는 목록 표시만.
|
|
65
|
+
|
|
66
|
+
### 동적 마운트
|
|
67
|
+
|
|
68
|
+
페이지 로드(`DOMContentLoaded`/`turbo:load`)에 자동 마운트. 모달 등 동적 삽입 후에는:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
window.OrdarsRailsEditor.mountAll(container) // 또는 .mount(rootEl)
|
|
72
|
+
const inst = window.OrdarsRailsEditor.get(rootEl) // .getHTML() / .setContent() / .destroy()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 테마
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
.ore { --ore-accent: #16a34a; --ore-accent-soft: #f0fdf4; } /* 등 --ore-* 변수 덮어쓰기 */
|
|
79
|
+
.ore-tip { background: #16a34a; } /* 툴팁은 body 직속이라 별도 */
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Tiptap 번들 재빌드
|
|
83
|
+
|
|
84
|
+
`app/javascript/ordars_rails_editor/tiptap.js` 는 esbuild 산출물이다. 확장 추가/업데이트 시:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cd build && npm install && npx esbuild entry.js --bundle --format=esm --minify \
|
|
88
|
+
--outfile=../app/javascript/ordars_rails_editor/tiptap.js
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
⚠`@tiptap/*` 패키지는 **전부 같은 버전**으로 맞출 것 — 어긋나면 esbuild 에서 export 불일치로 실패한다.
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
MIT
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ordars-rails-editor — 셸 스타일 (.ore-*)
|
|
3
|
+
* 테마는 CSS 변수로 연다: 호스트 앱이 `.ore { --ore-accent: ... }` 로 덮어쓴다.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.ore {
|
|
7
|
+
--ore-accent: #3e6187;
|
|
8
|
+
--ore-accent-soft: #f3f7fb;
|
|
9
|
+
--ore-accent-ring: #3e618722;
|
|
10
|
+
--ore-border: #dbe6f0;
|
|
11
|
+
--ore-bg: #fff;
|
|
12
|
+
--ore-toolbar-bg: #f8fafc;
|
|
13
|
+
--ore-text: #1e293b;
|
|
14
|
+
--ore-muted: #94a3b8;
|
|
15
|
+
--ore-radius: 12px;
|
|
16
|
+
|
|
17
|
+
background: var(--ore-bg);
|
|
18
|
+
border: 1px solid var(--ore-border);
|
|
19
|
+
border-radius: var(--ore-radius);
|
|
20
|
+
}
|
|
21
|
+
.ore > :first-child { border-radius: var(--ore-radius) var(--ore-radius) 0 0; }
|
|
22
|
+
.ore > :last-child { border-radius: 0 0 var(--ore-radius) var(--ore-radius); }
|
|
23
|
+
|
|
24
|
+
/* ── 서식 툴바 ── */
|
|
25
|
+
.ore-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; padding: 7px 10px; border-bottom: 1px solid var(--ore-border); background: var(--ore-bg); }
|
|
26
|
+
.ore-btnwrap { position: relative; display: inline-flex; }
|
|
27
|
+
.ore-btn { width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; border: none; background: none; border-radius: 8px; cursor: pointer; color: #334155; font-size: 15px; padding: 0; font-family: inherit; }
|
|
28
|
+
.ore-btn:hover { background: var(--ore-accent-soft); }
|
|
29
|
+
.ore-btn.on { background: var(--ore-accent); color: #fff; }
|
|
30
|
+
.ore-btn--wide { width: auto; padding: 0 12px; font-size: 12.5px; font-weight: 700; gap: 5px; }
|
|
31
|
+
.ore-sep { width: 1px; height: 20px; background: var(--ore-border); margin: 0 6px; flex-shrink: 0; }
|
|
32
|
+
.ore-tail { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; }
|
|
33
|
+
.ore-select { height: 34px; border: 1px solid var(--ore-border); border-radius: 8px; font-size: 13px; color: #334155; padding: 0 6px; background: #fff; cursor: pointer; font-family: inherit; }
|
|
34
|
+
.ore-select:focus { outline: none; border-color: var(--ore-accent); }
|
|
35
|
+
|
|
36
|
+
/* ── 팔레트 팝업 (버튼 형제 — button 중첩 금지) ── */
|
|
37
|
+
.ore-pop { position: absolute; top: 40px; left: 50%; transform: translateX(-50%); background: #fff; border: 1px solid var(--ore-border); border-radius: 12px; box-shadow: 0 10px 28px rgba(15, 23, 42, .18); padding: 10px; display: none; z-index: 40; }
|
|
38
|
+
.ore-pop.open { display: block; }
|
|
39
|
+
.ore-pop::before { content: ""; position: absolute; top: -6px; left: 50%; transform: translateX(-50%) rotate(45deg); width: 10px; height: 10px; background: #fff; border-left: 1px solid var(--ore-border); border-top: 1px solid var(--ore-border); }
|
|
40
|
+
.ore-pal { display: grid; grid-template-columns: repeat(7, 26px); gap: 6px; }
|
|
41
|
+
.ore-pal button { width: 26px; height: 26px; border-radius: 8px; border: 1px solid rgba(0, 0, 0, .1); cursor: pointer; transition: transform .08s; padding: 0; }
|
|
42
|
+
.ore-pal button:hover { transform: scale(1.18); }
|
|
43
|
+
.ore-pal .clear { background: #fff; position: relative; border: 1px solid #cbd5e1; }
|
|
44
|
+
.ore-pal .clear::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; border: 1.5px solid #94a3b8; }
|
|
45
|
+
.ore-pal .clear::after { content: ""; position: absolute; left: 4px; right: 4px; top: 50%; height: 1.5px; background: #94a3b8; transform: rotate(-45deg); }
|
|
46
|
+
|
|
47
|
+
/* ── 말풍선 툴팁 (버튼 위·화살표 아래 — body 직속 전역 1개) ── */
|
|
48
|
+
.ore-tip { position: fixed; z-index: 12050; background: #3e6187; color: #fff; font-size: 12px; font-weight: 700; padding: 5px 11px; border-radius: 8px; pointer-events: none; white-space: nowrap; opacity: 0; transform: translateY(3px); transition: opacity .1s, transform .1s; box-shadow: 0 4px 12px rgba(15, 23, 42, .22); }
|
|
49
|
+
.ore-tip.show { opacity: 1; transform: translateY(0); }
|
|
50
|
+
.ore-tip::before { content: ""; position: absolute; bottom: -4px; left: 50%; transform: translateX(-50%) rotate(45deg); width: 8px; height: 8px; background: inherit; border-radius: 1px; }
|
|
51
|
+
|
|
52
|
+
/* ── 본문 ── */
|
|
53
|
+
.ore-content { min-height: 300px; max-height: 55vh; overflow-y: auto; padding: 18px 20px; font-size: 15px; line-height: 1.75; color: var(--ore-text); }
|
|
54
|
+
.ore-content .tiptap { outline: none; min-height: 260px; }
|
|
55
|
+
.ore-content .tiptap p { margin: 0 0 .35em; }
|
|
56
|
+
.ore-content .tiptap h1, .ore-content .tiptap h2, .ore-content .tiptap h3 { margin: .6em 0 .35em; line-height: 1.35; }
|
|
57
|
+
.ore-content .tiptap ul, .ore-content .tiptap ol { padding-left: 1.5em; margin: .3em 0; }
|
|
58
|
+
.ore-content .tiptap blockquote { border-left: 3px solid var(--ore-accent); background: var(--ore-accent-soft); padding: 8px 14px; border-radius: 0 8px 8px 0; margin: .5em 0; color: #475569; }
|
|
59
|
+
.ore-content .tiptap code { background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 5px; padding: 1px 5px; font-size: .9em; }
|
|
60
|
+
.ore-content .tiptap pre { background: #0f172a; color: #e2e8f0; border-radius: 10px; padding: 12px 14px; margin: .5em 0; overflow-x: auto; }
|
|
61
|
+
.ore-content .tiptap pre code { background: none; border: none; color: inherit; }
|
|
62
|
+
.ore-content .tiptap hr { border: none; border-top: 2px solid var(--ore-border); margin: 14px 0; }
|
|
63
|
+
.ore-content .tiptap img { max-width: 100%; border-radius: 10px; }
|
|
64
|
+
.ore-content .tiptap img.ProseMirror-selectednode { outline: 3px solid var(--ore-accent-ring); }
|
|
65
|
+
.ore-content .tiptap a { color: var(--ore-accent); text-decoration: underline; }
|
|
66
|
+
.ore-content .tiptap p.is-editor-empty:first-child::before { content: attr(data-placeholder); color: var(--ore-muted); float: left; height: 0; pointer-events: none; }
|
|
67
|
+
|
|
68
|
+
/* ── HTML 소스 모드 ── */
|
|
69
|
+
.ore-html { display: none; width: 100%; min-height: 300px; max-height: 55vh; border: none; padding: 18px 20px; font: 12.5px/1.6 ui-monospace, "Cascadia Code", Consolas, monospace; color: #0f172a; background: #f8fafc; resize: none; box-sizing: border-box; }
|
|
70
|
+
.ore-html:focus { outline: none; }
|
|
71
|
+
.ore.is-html .ore-content { display: none; }
|
|
72
|
+
.ore.is-html .ore-html { display: block; }
|
|
73
|
+
.ore.is-html .ore-toolbar .ore-btn:not(.ore-htmlbtn), .ore.is-html .ore-toolbar .ore-select { opacity: .35; pointer-events: none; }
|
|
74
|
+
|
|
75
|
+
/* ── 하단 첨부 바 ── */
|
|
76
|
+
.ore-attachbar { display: flex; align-items: center; gap: 18px; padding: 10px 14px; background: var(--ore-toolbar-bg); border-top: 1px solid var(--ore-border); font-size: 12.5px; color: #475569; flex-wrap: wrap; }
|
|
77
|
+
.ore-attachbar .grp { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
|
|
78
|
+
.ore-attachbar .grp .ore-filebtn { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; color: var(--ore-accent); background: #fff; border: 1.5px solid var(--ore-accent); border-radius: 8px; padding: 6px 13px; cursor: pointer; font-family: inherit; }
|
|
79
|
+
.ore-attachbar .grp .ore-filebtn:hover { background: var(--ore-accent); color: #fff; }
|
|
80
|
+
.ore-gauge { width: 70px; height: 6px; border-radius: 3px; background: #e2e8f0; overflow: hidden; }
|
|
81
|
+
.ore-gauge i { display: block; height: 100%; width: 0; background: var(--ore-accent); border-radius: 3px; transition: width .2s; }
|
|
82
|
+
.ore-attachbar .cap { margin-left: auto; display: inline-flex; align-items: center; gap: 7px; }
|
|
83
|
+
.ore-attachbar .cap b { color: var(--ore-accent); }
|
|
84
|
+
|
|
85
|
+
/* ── 첨부 목록 ── */
|
|
86
|
+
.ore-attachlist { padding: 10px 14px 14px; background: var(--ore-toolbar-bg); }
|
|
87
|
+
.ore-attach-empty { border: 1.5px dashed var(--ore-border); border-radius: 10px; text-align: center; color: var(--ore-muted); font-size: 13px; padding: 22px; background: #fff; }
|
|
88
|
+
.ore-attach-row { display: flex; align-items: center; gap: 10px; background: #fff; border: 1px solid var(--ore-border); border-radius: 10px; padding: 8px 12px; margin-bottom: 6px; }
|
|
89
|
+
.ore-attach-row img.th { width: 40px; height: 40px; object-fit: cover; border-radius: 7px; border: 1px solid var(--ore-border); }
|
|
90
|
+
.ore-attach-row .ic { width: 40px; height: 40px; border-radius: 7px; background: var(--ore-accent-soft); display: flex; align-items: center; justify-content: center; font-size: 16px; }
|
|
91
|
+
.ore-attach-row .nm { flex: 1; min-width: 0; font-size: 13px; color: #1e293b; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
92
|
+
.ore-attach-row .sz { font-size: 11.5px; color: var(--ore-muted); }
|
|
93
|
+
.ore-attach-row .rm { border: none; background: none; color: var(--ore-muted); cursor: pointer; font-size: 15px; padding: 4px; }
|
|
94
|
+
.ore-attach-row .rm:hover { color: #dc2626; }
|
|
95
|
+
|
|
96
|
+
/* ── 모바일 (≤640px) ── */
|
|
97
|
+
@media (max-width: 640px) {
|
|
98
|
+
.ore-toolbar { gap: 3px; padding: 6px 8px; }
|
|
99
|
+
.ore-toolbar .ore-sep { display: none; }
|
|
100
|
+
.ore-btn { width: 32px; height: 32px; }
|
|
101
|
+
.ore-select { height: 32px; font-size: 12px; }
|
|
102
|
+
.ore-btn--wide { padding: 0 10px; font-size: 12px; }
|
|
103
|
+
.ore-pal { grid-template-columns: repeat(5, 26px); }
|
|
104
|
+
.ore-attachbar { flex-direction: column; align-items: stretch; gap: 9px; }
|
|
105
|
+
.ore-attachbar .grp { width: 100%; }
|
|
106
|
+
.ore-attachbar .grp .ore-filebtn { width: 100%; justify-content: center; padding: 9px; }
|
|
107
|
+
.ore-gauge { flex: 1; width: auto; }
|
|
108
|
+
.ore-attachbar .cap { margin-left: 0; width: 100%; }
|
|
109
|
+
.ore-content { padding: 14px; max-height: none; min-height: 240px; }
|
|
110
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OrdarsRailsEditor
|
|
4
|
+
module EditorHelper
|
|
5
|
+
# 리치텍스트 에디터 렌더.
|
|
6
|
+
#
|
|
7
|
+
# <%= ore_editor name: "board_post[content]", content: @post.content_html,
|
|
8
|
+
# upload_url: upload_path, attach_name: "attachment_file_ids[]",
|
|
9
|
+
# placeholder: "내용을 입력하세요" %>
|
|
10
|
+
#
|
|
11
|
+
# 옵션:
|
|
12
|
+
# name: (필수) 본문 HTML 이 실릴 폼 필드 이름
|
|
13
|
+
# content: 초기 HTML (수정 폼)
|
|
14
|
+
# placeholder: 빈 에디터 안내 문구
|
|
15
|
+
# upload_url: 첨부/이미지 업로드 엔드포인트 (미지정 = 로컬 모드: 이미지 dataURL·첨부 목록만)
|
|
16
|
+
# attach_name: 첨부 file_id hidden input 이름 (예: "attachment_file_ids[]")
|
|
17
|
+
# max_images: / max_videos: / max_mb: 첨부 한도 표시·게이지 기준
|
|
18
|
+
# attach: false 면 하단 첨부 패널 없이 본문 에디터만
|
|
19
|
+
# id: 에디터 루트 DOM id (기본 자동 생성)
|
|
20
|
+
#
|
|
21
|
+
# ⚠저장 시 서버에서 반드시 OrdarsRailsEditor::Sanitizer.clean 을 통과시킬 것.
|
|
22
|
+
def ore_editor(name:, content: nil, placeholder: "내용을 입력하세요", upload_url: nil,
|
|
23
|
+
attach_name: nil, max_images: nil, max_videos: nil, max_mb: nil,
|
|
24
|
+
attach: true, id: nil)
|
|
25
|
+
render partial: "ordars_rails_editor/editor", locals: {
|
|
26
|
+
input_name: name,
|
|
27
|
+
content: content.to_s,
|
|
28
|
+
placeholder: placeholder,
|
|
29
|
+
upload_url: upload_url,
|
|
30
|
+
attach_name: attach_name,
|
|
31
|
+
max_images: max_images || OrdarsRailsEditor.default_max_images,
|
|
32
|
+
max_videos: max_videos || OrdarsRailsEditor.default_max_videos,
|
|
33
|
+
max_mb: max_mb || OrdarsRailsEditor.default_max_total_mb,
|
|
34
|
+
show_attach: attach,
|
|
35
|
+
editor_id: id || "ore-editor-#{SecureRandom.hex(4)}"
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|