@teriusu/rich-editor 0.5.0 → 0.5.2
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.
- package/dist/components/TipTapEditor.svelte +12 -3
- package/dist/components/TipTapEditor.svelte.d.ts.map +1 -1
- package/dist/extensions/FileAttachment.d.ts.map +1 -1
- package/dist/extensions/FileAttachment.js +35 -14
- package/dist/extensions/PdfBlock.d.ts.map +1 -1
- package/dist/extensions/PdfBlock.js +19 -14
- package/dist/types.js +1 -1
- package/package.json +1 -1
|
@@ -229,13 +229,19 @@
|
|
|
229
229
|
uploading = true;
|
|
230
230
|
const size = file.size;
|
|
231
231
|
onUploadFile(file)
|
|
232
|
-
.then((
|
|
232
|
+
.then((result) => {
|
|
233
|
+
const isFileId = result && !result.includes("/") && !result.includes(":");
|
|
233
234
|
editor!
|
|
234
235
|
.chain()
|
|
235
236
|
.focus()
|
|
236
237
|
.insertContent({
|
|
237
238
|
type: "fileAttachment",
|
|
238
|
-
attrs: {
|
|
239
|
+
attrs: {
|
|
240
|
+
src: isFileId ? null : result,
|
|
241
|
+
fileId: isFileId ? result : null,
|
|
242
|
+
name: file.name,
|
|
243
|
+
size,
|
|
244
|
+
},
|
|
239
245
|
})
|
|
240
246
|
.run();
|
|
241
247
|
})
|
|
@@ -486,7 +492,10 @@
|
|
|
486
492
|
|
|
487
493
|
// File resolver를 storage에 등록
|
|
488
494
|
if (onResolveFile) {
|
|
489
|
-
editor.storage.fileAttachment = {
|
|
495
|
+
editor.storage.fileAttachment = {
|
|
496
|
+
...editor.storage.fileAttachment,
|
|
497
|
+
resolver: onResolveFile,
|
|
498
|
+
};
|
|
490
499
|
}
|
|
491
500
|
|
|
492
501
|
editor.on("update", handleUpdate);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAa5D,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEhE,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAa5D,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEhE,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC;AA2mBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileAttachment.d.ts","sourceRoot":"","sources":["../../src/extensions/FileAttachment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1E,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,cAAc,EAAE;YACd,iBAAiB,EAAE,CAAC,KAAK,EAAE;gBACzB,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,MAAM,CAAC,EAAE,MAAM,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC;gBACb,IAAI,CAAC,EAAE,MAAM,CAAC;aACf,KAAK,UAAU,CAAC;SAClB,CAAC;KACH;CACF;
|
|
1
|
+
{"version":3,"file":"FileAttachment.d.ts","sourceRoot":"","sources":["../../src/extensions/FileAttachment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1E,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,cAAc,EAAE;YACd,iBAAiB,EAAE,CAAC,KAAK,EAAE;gBACzB,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,MAAM,CAAC,EAAE,MAAM,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC;gBACb,IAAI,CAAC,EAAE,MAAM,CAAC;aACf,KAAK,UAAU,CAAC;SAClB,CAAC;KACH;CACF;AAkCD,eAAO,MAAM,cAAc,kCAmNzB,CAAC"}
|
|
@@ -6,6 +6,10 @@ function formatFileSize(bytes) {
|
|
|
6
6
|
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
7
7
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
8
8
|
}
|
|
9
|
+
function isInlineable(name) {
|
|
10
|
+
const ext = name.split(".").pop()?.toLowerCase() || "";
|
|
11
|
+
return ["pdf", "png", "jpg", "jpeg", "gif", "webp", "svg"].includes(ext);
|
|
12
|
+
}
|
|
9
13
|
function getFileIcon(name) {
|
|
10
14
|
const ext = name.split(".").pop()?.toLowerCase() || "";
|
|
11
15
|
const icons = {
|
|
@@ -116,22 +120,36 @@ export const FileAttachment = Node.create({
|
|
|
116
120
|
"display:block;font-size:13px;font-weight:600;color:var(--primary, #4A7DAC);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;";
|
|
117
121
|
let resolvedSrc = null;
|
|
118
122
|
let resolvedName = node.attrs.name;
|
|
119
|
-
function
|
|
123
|
+
function getProxyUrl() {
|
|
124
|
+
const fileId = node.attrs.fileId;
|
|
125
|
+
if (!fileId)
|
|
126
|
+
return null;
|
|
127
|
+
const baseUrl = editor.storage.fileAttachment?.downloadBaseUrl || "/api/upload";
|
|
128
|
+
return `${baseUrl}/${fileId}/download`;
|
|
129
|
+
}
|
|
130
|
+
function handleClick(e) {
|
|
120
131
|
e.preventDefault();
|
|
121
|
-
|
|
132
|
+
const proxyUrl = getProxyUrl();
|
|
133
|
+
const targetUrl = proxyUrl || resolvedSrc;
|
|
134
|
+
if (!targetUrl)
|
|
122
135
|
return;
|
|
123
|
-
|
|
124
|
-
.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
if (isInlineable(resolvedName)) {
|
|
137
|
+
window.open(targetUrl, "_blank");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
fetch(targetUrl)
|
|
141
|
+
.then((res) => res.blob())
|
|
142
|
+
.then((blob) => {
|
|
143
|
+
const url = URL.createObjectURL(blob);
|
|
144
|
+
const a = document.createElement("a");
|
|
145
|
+
a.href = url;
|
|
146
|
+
a.download = resolvedName;
|
|
147
|
+
a.click();
|
|
148
|
+
URL.revokeObjectURL(url);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
133
151
|
}
|
|
134
|
-
nameEl.addEventListener("click",
|
|
152
|
+
nameEl.addEventListener("click", handleClick);
|
|
135
153
|
const sizeEl = document.createElement("span");
|
|
136
154
|
sizeEl.style.cssText =
|
|
137
155
|
"font-size:11px;color:var(--muted-foreground, #718096);";
|
|
@@ -197,7 +215,10 @@ export const FileAttachment = Node.create({
|
|
|
197
215
|
};
|
|
198
216
|
},
|
|
199
217
|
addStorage() {
|
|
200
|
-
return {
|
|
218
|
+
return {
|
|
219
|
+
resolver: null,
|
|
220
|
+
downloadBaseUrl: "/api/upload",
|
|
221
|
+
};
|
|
201
222
|
},
|
|
202
223
|
addCommands() {
|
|
203
224
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PdfBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/PdfBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,UAAU,EAAmB,MAAM,cAAc,CAAC;AAInE,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"PdfBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/PdfBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,UAAU,EAAmB,MAAM,cAAc,CAAC;AAInE,eAAO,MAAM,QAAQ,sBA8TnB,CAAC"}
|
|
@@ -245,31 +245,36 @@ export const PdfBlock = TiptapNode.create({
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
// URL 해결 후 PDF 로드
|
|
248
|
+
function getProxyUrl(fileId) {
|
|
249
|
+
const baseUrl = editor.storage.fileAttachment?.downloadBaseUrl || "/api/upload";
|
|
250
|
+
return `${baseUrl}/${fileId}/download`;
|
|
251
|
+
}
|
|
248
252
|
if (node.attrs.src) {
|
|
249
|
-
|
|
250
|
-
|
|
253
|
+
if (node.attrs.fileId) {
|
|
254
|
+
// fileId 있으면 프록시 URL 사용 (경로 숨김)
|
|
255
|
+
const proxyUrl = getProxyUrl(node.attrs.fileId);
|
|
256
|
+
openLink.href = proxyUrl;
|
|
257
|
+
loadPdf(proxyUrl);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
openLink.href = node.attrs.src;
|
|
261
|
+
loadPdf(node.attrs.src);
|
|
262
|
+
}
|
|
251
263
|
}
|
|
252
264
|
else if (node.attrs.fileId) {
|
|
253
|
-
|
|
254
|
-
openLink.href =
|
|
265
|
+
const proxyUrl = getProxyUrl(node.attrs.fileId);
|
|
266
|
+
openLink.href = proxyUrl;
|
|
267
|
+
// resolver로 이름 획득
|
|
255
268
|
const resolver = editor.storage.fileAttachment?.resolver;
|
|
256
269
|
if (resolver) {
|
|
257
270
|
resolver(node.attrs.fileId)
|
|
258
271
|
.then((result) => {
|
|
259
|
-
openLink.href = result.src;
|
|
260
272
|
if (result.name)
|
|
261
273
|
nameSpan.textContent = result.name;
|
|
262
|
-
loadPdf(result.src);
|
|
263
274
|
})
|
|
264
|
-
.catch(() => {
|
|
265
|
-
loadingDiv.innerHTML =
|
|
266
|
-
'<p class="text-sm text-muted-foreground">PDF URL\uC744 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.</p>';
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
loadingDiv.innerHTML =
|
|
271
|
-
`<p class="text-sm text-muted-foreground">PDF ID: ${node.attrs.fileId}</p>`;
|
|
275
|
+
.catch(() => { });
|
|
272
276
|
}
|
|
277
|
+
loadPdf(proxyUrl);
|
|
273
278
|
}
|
|
274
279
|
return {
|
|
275
280
|
dom,
|
package/dist/types.js
CHANGED
|
@@ -20,7 +20,7 @@ export const TOOLBAR_PRESETS = {
|
|
|
20
20
|
'blockquote', 'horizontal-rule', 'toggle',
|
|
21
21
|
'link', 'image', 'pdf', 'youtube', 'video', 'file',
|
|
22
22
|
'columns-2', 'columns-3', 'table', 'code-block',
|
|
23
|
-
'bubble-toolbar', 'slash-menu', 'table-menu'
|
|
23
|
+
'fixed-toolbar', 'bubble-toolbar', 'slash-menu', 'table-menu'
|
|
24
24
|
],
|
|
25
25
|
minimal: [
|
|
26
26
|
'bold', 'italic', 'strike', 'code',
|