@jvs-milkdown/crepe 1.2.25 → 1.2.27
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/lib/cjs/feature/block-edit/index.js +3 -3
- package/lib/cjs/feature/block-edit/index.js.map +1 -1
- package/lib/cjs/feature/toolbar/index.js +1 -1
- package/lib/cjs/feature/toolbar/index.js.map +1 -1
- package/lib/cjs/index.js +420 -6
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/feature/block-edit/index.js +3 -3
- package/lib/esm/feature/block-edit/index.js.map +1 -1
- package/lib/esm/feature/toolbar/index.js +1 -1
- package/lib/esm/feature/toolbar/index.js.map +1 -1
- package/lib/esm/index.js +421 -7
- package/lib/esm/index.js.map +1 -1
- package/lib/theme/common/block-edit.css +5 -3
- package/lib/theme/common/code-mirror.css +19 -0
- package/lib/theme/common/link-tooltip.css +2 -2
- package/lib/theme/common/toolbar.css +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/default-config/index.d.ts.map +1 -1
- package/lib/types/feature/block-edit/handle/index.d.ts.map +1 -1
- package/lib/types/feature/block-edit/menu/component.d.ts.map +1 -1
- package/lib/types/feature/fixed-toolbar/config.d.ts.map +1 -1
- package/lib/types/feature/fixed-toolbar/index.d.ts +2 -0
- package/lib/types/feature/fixed-toolbar/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/default-config/default-config.spec.ts +15 -0
- package/src/default-config/index.ts +17 -1
- package/src/feature/block-edit/handle/index.ts +8 -2
- package/src/feature/block-edit/menu/component.tsx +4 -1
- package/src/feature/fixed-toolbar/config.ts +482 -3
- package/src/feature/fixed-toolbar/index.ts +2 -0
- package/src/theme/common/block-edit.css +5 -3
- package/src/theme/common/code-mirror.css +19 -0
- package/src/theme/common/link-tooltip.css +2 -2
- package/src/theme/common/toolbar.css +1 -1
package/lib/esm/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { replaceAll, $prose as $prose$1, getHTML } from '@jvs-milkdown/utils';
|
|
2
2
|
import { defaultsDeep } from 'lodash-es';
|
|
3
|
+
import { LanguageDescription } from '@codemirror/language';
|
|
3
4
|
import { languages } from '@codemirror/language-data';
|
|
4
5
|
import { oneDark } from '@codemirror/theme-one-dark';
|
|
5
6
|
import { createSlice } from '@jvs-milkdown/kit/ctx';
|
|
@@ -7,7 +8,7 @@ import { $ctx, $nodeSchema, $view, $remark, $markAttr, $markSchema, $command, $p
|
|
|
7
8
|
import { defineComponent, shallowRef, ref, computed, h, createApp, watchEffect, watch, onUnmounted, Fragment, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
|
8
9
|
import { Icon } from '@jvs-milkdown/kit/component';
|
|
9
10
|
import { blockConfig, block, BlockProvider } from '@jvs-milkdown/kit/plugin/block';
|
|
10
|
-
import { commandsCtx, editorViewCtx, schemaCtx, editorCtx, EditorStatus, parserCtx, editorViewOptionsCtx, Editor,
|
|
11
|
+
import { commandsCtx, editorViewCtx, schemaCtx, editorCtx, EditorStatus, rootCtx, parserCtx, editorViewOptionsCtx, Editor, defaultValueCtx } from '@jvs-milkdown/kit/core';
|
|
11
12
|
import { findNodeInSelection, findParent, nodeRule } from '@jvs-milkdown/kit/prose';
|
|
12
13
|
import { NodeSelection, TextSelection, Plugin, PluginKey, EditorState, AllSelection } from '@jvs-milkdown/kit/prose/state';
|
|
13
14
|
import { computePosition, flip, shift, offset } from '@floating-ui/dom';
|
|
@@ -675,10 +676,21 @@ const importIcon = `
|
|
|
675
676
|
</svg>
|
|
676
677
|
`;
|
|
677
678
|
|
|
679
|
+
const mermaidLanguage = LanguageDescription.of({
|
|
680
|
+
name: "Mermaid",
|
|
681
|
+
alias: ["mermaid"],
|
|
682
|
+
load: () => {
|
|
683
|
+
const fallback = languages.find((l) => l.name === "YAML") || languages.find((l) => l.name === "Markdown");
|
|
684
|
+
return fallback ? fallback.load() : Promise.resolve(null);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
const allLanguages = [mermaidLanguage, ...languages].sort(
|
|
688
|
+
(a, b) => a.name.localeCompare(b.name)
|
|
689
|
+
);
|
|
678
690
|
const defaultConfig = {
|
|
679
691
|
[CrepeFeature.CodeMirror]: {
|
|
680
692
|
theme: oneDark,
|
|
681
|
-
languages,
|
|
693
|
+
languages: allLanguages,
|
|
682
694
|
expandIcon: chevronDownIcon,
|
|
683
695
|
searchIcon,
|
|
684
696
|
clearSearchIcon: clearIcon,
|
|
@@ -3064,7 +3076,7 @@ const Menu = defineComponent({
|
|
|
3064
3076
|
const isTableBlock = (node == null ? void 0 : node.type.name) === "table";
|
|
3065
3077
|
const isMedia = ((_a = node == null ? void 0 : node.type.name) == null ? void 0 : _a.includes("image")) || isAttachmentBlock || isImageParagraph || (node == null ? void 0 : node.type.name) === "hr" || isTableBlock;
|
|
3066
3078
|
const showAlign = !isMedia || isImageBlock;
|
|
3067
|
-
const isEmpty = node ? node.textContent.length === 0 && node.content.size <= 2 && !isMedia : false;
|
|
3079
|
+
const isEmpty = node ? node.type.name === "paragraph" && node.textContent.length === 0 && node.content.size <= 2 && !isMedia : false;
|
|
3068
3080
|
const currentAlign = ((_b = node == null ? void 0 : node.attrs) == null ? void 0 : _b.align) || "left";
|
|
3069
3081
|
const currentIndent = ((_c = node == null ? void 0 : node.attrs) == null ? void 0 : _c.indent) || 0;
|
|
3070
3082
|
const setAlign = (alignValue) => {
|
|
@@ -4020,7 +4032,7 @@ class BlockHandleView {
|
|
|
4020
4032
|
});
|
|
4021
4033
|
}
|
|
4022
4034
|
const isMedia = node.type.name.includes("image") || node.type.name.includes("attachment") || node.type.name === "hr" || node.type.name.includes("math") || hasMediaChild;
|
|
4023
|
-
const isEmpty = node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
|
|
4035
|
+
const isEmpty = node.type.name === "paragraph" && node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
|
|
4024
4036
|
if (isEmpty) {
|
|
4025
4037
|
__privateGet$5(this, _content$3).classList.add("empty-block");
|
|
4026
4038
|
} else {
|
|
@@ -4171,7 +4183,7 @@ class BlockHandleView {
|
|
|
4171
4183
|
});
|
|
4172
4184
|
}
|
|
4173
4185
|
const isMedia = node.type.name.includes("image") || node.type.name.includes("attachment") || node.type.name === "hr" || node.type.name.includes("math") || hasMediaChild;
|
|
4174
|
-
const isEmpty = node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
|
|
4186
|
+
const isEmpty = node.type.name === "paragraph" && node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
|
|
4175
4187
|
if (isEmpty) {
|
|
4176
4188
|
__privateGet$5(this, _content$3).classList.add("empty-block");
|
|
4177
4189
|
} else {
|
|
@@ -9096,7 +9108,17 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
|
|
|
9096
9108
|
active: () => false,
|
|
9097
9109
|
onRun: (ctx2) => {
|
|
9098
9110
|
const markdown = getMarkdown()(ctx2);
|
|
9099
|
-
|
|
9111
|
+
const view = ctx2.get(editorViewCtx);
|
|
9112
|
+
const root = ctx2.get(rootCtx);
|
|
9113
|
+
const rootNode = view.dom.getRootNode();
|
|
9114
|
+
if ((_config == null ? void 0 : _config.exportItems) && _config.exportItems.length > 0) {
|
|
9115
|
+
const exportItems = _config.exportItems;
|
|
9116
|
+
if (exportItems.length === 1) {
|
|
9117
|
+
handleDirectExport(exportItems[0], markdown, view, root);
|
|
9118
|
+
} else {
|
|
9119
|
+
showDownloadPopover(rootNode, root, view, markdown, exportItems);
|
|
9120
|
+
}
|
|
9121
|
+
} else if (_config == null ? void 0 : _config.onExport) {
|
|
9100
9122
|
_config.onExport(markdown, ctx2);
|
|
9101
9123
|
} else {
|
|
9102
9124
|
const blob = new Blob([markdown], {
|
|
@@ -9118,7 +9140,17 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
|
|
|
9118
9140
|
icon: importIcon,
|
|
9119
9141
|
active: () => false,
|
|
9120
9142
|
onRun: (ctx2) => {
|
|
9121
|
-
|
|
9143
|
+
const view = ctx2.get(editorViewCtx);
|
|
9144
|
+
const root = ctx2.get(rootCtx);
|
|
9145
|
+
const rootNode = view.dom.getRootNode();
|
|
9146
|
+
if ((_config == null ? void 0 : _config.importItems) && _config.importItems.length > 0) {
|
|
9147
|
+
const importItems = _config.importItems;
|
|
9148
|
+
if (importItems.length === 1) {
|
|
9149
|
+
handleDirectImport(importItems[0], root, ctx2);
|
|
9150
|
+
} else {
|
|
9151
|
+
showImportPopover(rootNode, root, ctx2, importItems);
|
|
9152
|
+
}
|
|
9153
|
+
} else if (_config == null ? void 0 : _config.onImport) {
|
|
9122
9154
|
_config.onImport((markdown) => replaceAll(markdown)(ctx2), ctx2);
|
|
9123
9155
|
} else {
|
|
9124
9156
|
const input = document.createElement("input");
|
|
@@ -9149,6 +9181,388 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
|
|
|
9149
9181
|
});
|
|
9150
9182
|
return builder.build();
|
|
9151
9183
|
}
|
|
9184
|
+
const activeDownloadPopovers = /* @__PURE__ */ new WeakMap();
|
|
9185
|
+
const activeImportPopovers = /* @__PURE__ */ new WeakMap();
|
|
9186
|
+
const ensureStyles = (rootNode) => {
|
|
9187
|
+
const target = rootNode instanceof ShadowRoot ? rootNode : document.head;
|
|
9188
|
+
if (target.querySelector("#download-popover-styles")) return;
|
|
9189
|
+
const styleEl = document.createElement("style");
|
|
9190
|
+
styleEl.id = "download-popover-styles";
|
|
9191
|
+
styleEl.textContent = `
|
|
9192
|
+
.download-popover, .import-popover {
|
|
9193
|
+
position: fixed;
|
|
9194
|
+
z-index: 10000;
|
|
9195
|
+
width: 140px;
|
|
9196
|
+
padding: 6px 0;
|
|
9197
|
+
display: flex;
|
|
9198
|
+
flex-direction: column;
|
|
9199
|
+
background-color: var(--crepe-color-surface, #ffffff);
|
|
9200
|
+
border: 1px solid var(--crepe-color-outline-variant, color-mix(in srgb, var(--crepe-color-outline), transparent 80%));
|
|
9201
|
+
border-radius: 8px;
|
|
9202
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
9203
|
+
opacity: 0;
|
|
9204
|
+
transform: translateY(-8px);
|
|
9205
|
+
transition: opacity 0.15s ease, transform 0.15s ease;
|
|
9206
|
+
pointer-events: none;
|
|
9207
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
9208
|
+
}
|
|
9209
|
+
.download-popover.show, .import-popover.show {
|
|
9210
|
+
opacity: 1;
|
|
9211
|
+
transform: translateY(0);
|
|
9212
|
+
pointer-events: auto;
|
|
9213
|
+
}
|
|
9214
|
+
.download-popover-item, .import-popover-item {
|
|
9215
|
+
cursor: pointer;
|
|
9216
|
+
padding: 8px 14px;
|
|
9217
|
+
display: flex;
|
|
9218
|
+
align-items: center;
|
|
9219
|
+
gap: 8px;
|
|
9220
|
+
font-size: 13px;
|
|
9221
|
+
font-weight: 500;
|
|
9222
|
+
color: var(--crepe-color-primary, #363B4C);
|
|
9223
|
+
transition: background-color 0.2s;
|
|
9224
|
+
user-select: none;
|
|
9225
|
+
}
|
|
9226
|
+
.download-popover-item:hover, .import-popover-item:hover {
|
|
9227
|
+
background-color: var(--crepe-color-hover, #f5f5f5);
|
|
9228
|
+
}
|
|
9229
|
+
.download-popover-item-icon, .import-popover-item-icon {
|
|
9230
|
+
display: flex;
|
|
9231
|
+
align-items: center;
|
|
9232
|
+
justify-content: center;
|
|
9233
|
+
width: 14px;
|
|
9234
|
+
height: 14px;
|
|
9235
|
+
color: var(--crepe-color-primary, #363B4C);
|
|
9236
|
+
opacity: 0.8;
|
|
9237
|
+
}
|
|
9238
|
+
`;
|
|
9239
|
+
target.appendChild(styleEl);
|
|
9240
|
+
};
|
|
9241
|
+
function handleDirectExport(type, markdown, view, root) {
|
|
9242
|
+
if (type === "markdown") {
|
|
9243
|
+
const blob = new Blob([markdown], { type: "text/markdown;charset=utf-8;" });
|
|
9244
|
+
const url = URL.createObjectURL(blob);
|
|
9245
|
+
const link = document.createElement("a");
|
|
9246
|
+
link.href = url;
|
|
9247
|
+
link.download = "document.md";
|
|
9248
|
+
link.click();
|
|
9249
|
+
URL.revokeObjectURL(url);
|
|
9250
|
+
}
|
|
9251
|
+
const event = new CustomEvent("download-click", {
|
|
9252
|
+
detail: {
|
|
9253
|
+
type,
|
|
9254
|
+
markdown,
|
|
9255
|
+
html: view.dom.innerHTML || ""
|
|
9256
|
+
},
|
|
9257
|
+
bubbles: true,
|
|
9258
|
+
composed: true
|
|
9259
|
+
});
|
|
9260
|
+
root.dispatchEvent(event);
|
|
9261
|
+
}
|
|
9262
|
+
function handleDirectImport(type, root, ctx) {
|
|
9263
|
+
if (type === "markdown") {
|
|
9264
|
+
const input = document.createElement("input");
|
|
9265
|
+
input.type = "file";
|
|
9266
|
+
input.accept = ".md";
|
|
9267
|
+
input.onchange = (evt) => {
|
|
9268
|
+
var _a;
|
|
9269
|
+
const file = (_a = evt.target.files) == null ? void 0 : _a[0];
|
|
9270
|
+
if (!file) return;
|
|
9271
|
+
file.text().then((text) => {
|
|
9272
|
+
replaceAll(text)(ctx);
|
|
9273
|
+
const event = new CustomEvent("import-click", {
|
|
9274
|
+
detail: { type: "markdown", file },
|
|
9275
|
+
bubbles: true,
|
|
9276
|
+
composed: true
|
|
9277
|
+
});
|
|
9278
|
+
root.dispatchEvent(event);
|
|
9279
|
+
}).catch((err) => {
|
|
9280
|
+
console.error("Failed to read file:", err);
|
|
9281
|
+
});
|
|
9282
|
+
};
|
|
9283
|
+
input.click();
|
|
9284
|
+
} else {
|
|
9285
|
+
const event = new CustomEvent("import-click", {
|
|
9286
|
+
detail: { type },
|
|
9287
|
+
bubbles: true,
|
|
9288
|
+
composed: true
|
|
9289
|
+
});
|
|
9290
|
+
root.dispatchEvent(event);
|
|
9291
|
+
}
|
|
9292
|
+
}
|
|
9293
|
+
function showDownloadPopover(rootNode, root, view, markdown, exportItems) {
|
|
9294
|
+
var _a, _b, _c;
|
|
9295
|
+
const button = root.querySelector('button[data-key="export"]');
|
|
9296
|
+
if (!button) return;
|
|
9297
|
+
const existing = activeDownloadPopovers.get(button);
|
|
9298
|
+
if (existing) {
|
|
9299
|
+
existing.closePopover();
|
|
9300
|
+
return;
|
|
9301
|
+
}
|
|
9302
|
+
ensureStyles(rootNode);
|
|
9303
|
+
const container = rootNode instanceof ShadowRoot ? rootNode : document.body;
|
|
9304
|
+
const popover = document.createElement("div");
|
|
9305
|
+
popover.className = "download-popover";
|
|
9306
|
+
let popoverHtml = "";
|
|
9307
|
+
if (exportItems.includes("markdown")) {
|
|
9308
|
+
popoverHtml += `
|
|
9309
|
+
<div class="download-popover-item" id="download-md-btn">
|
|
9310
|
+
<span class="download-popover-item-icon">
|
|
9311
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><line x1="10" y1="9" x2="8" y2="9"></line></svg>
|
|
9312
|
+
</span>
|
|
9313
|
+
<span>\u4E0B\u8F7D MD</span>
|
|
9314
|
+
</div>
|
|
9315
|
+
`;
|
|
9316
|
+
}
|
|
9317
|
+
if (exportItems.includes("word")) {
|
|
9318
|
+
popoverHtml += `
|
|
9319
|
+
<div class="download-popover-item" id="download-word-btn">
|
|
9320
|
+
<span class="download-popover-item-icon">
|
|
9321
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
|
|
9322
|
+
</span>
|
|
9323
|
+
<span>\u4E0B\u8F7D WORD</span>
|
|
9324
|
+
</div>
|
|
9325
|
+
`;
|
|
9326
|
+
}
|
|
9327
|
+
if (exportItems.includes("pdf")) {
|
|
9328
|
+
popoverHtml += `
|
|
9329
|
+
<div class="download-popover-item" id="download-pdf-btn">
|
|
9330
|
+
<span class="download-popover-item-icon">
|
|
9331
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>
|
|
9332
|
+
</span>
|
|
9333
|
+
<span>\u4E0B\u8F7D PDF</span>
|
|
9334
|
+
</div>
|
|
9335
|
+
`;
|
|
9336
|
+
}
|
|
9337
|
+
popover.innerHTML = popoverHtml;
|
|
9338
|
+
container.appendChild(popover);
|
|
9339
|
+
activeDownloadPopovers.set(button, popover);
|
|
9340
|
+
const updatePosition = () => {
|
|
9341
|
+
const rect = button.getBoundingClientRect();
|
|
9342
|
+
popover.style.top = `${rect.bottom + 4}px`;
|
|
9343
|
+
popover.style.left = `${rect.left + (rect.width - 140) / 2}px`;
|
|
9344
|
+
};
|
|
9345
|
+
updatePosition();
|
|
9346
|
+
requestAnimationFrame(() => {
|
|
9347
|
+
popover.classList.add("show");
|
|
9348
|
+
});
|
|
9349
|
+
const closePopover = () => {
|
|
9350
|
+
popover.classList.remove("show");
|
|
9351
|
+
activeDownloadPopovers.delete(button);
|
|
9352
|
+
container.removeEventListener("pointerdown", handleContainerClick, true);
|
|
9353
|
+
document.removeEventListener("pointerdown", handleOuterClick, true);
|
|
9354
|
+
window.removeEventListener("resize", updatePosition);
|
|
9355
|
+
popover.addEventListener(
|
|
9356
|
+
"transitionend",
|
|
9357
|
+
() => {
|
|
9358
|
+
popover.remove();
|
|
9359
|
+
},
|
|
9360
|
+
{ once: true }
|
|
9361
|
+
);
|
|
9362
|
+
};
|
|
9363
|
+
popover.closePopover = closePopover;
|
|
9364
|
+
const handleContainerClick = (e) => {
|
|
9365
|
+
const target = e.target;
|
|
9366
|
+
if (!popover.contains(target) && target !== button && !button.contains(target)) {
|
|
9367
|
+
closePopover();
|
|
9368
|
+
}
|
|
9369
|
+
};
|
|
9370
|
+
const handleOuterClick = (e) => {
|
|
9371
|
+
const target = e.target;
|
|
9372
|
+
if (target !== root && !root.contains(target)) {
|
|
9373
|
+
closePopover();
|
|
9374
|
+
}
|
|
9375
|
+
};
|
|
9376
|
+
popover.addEventListener("pointerdown", (e) => {
|
|
9377
|
+
e.stopPropagation();
|
|
9378
|
+
});
|
|
9379
|
+
container.addEventListener("pointerdown", handleContainerClick, true);
|
|
9380
|
+
document.addEventListener("pointerdown", handleOuterClick, true);
|
|
9381
|
+
window.addEventListener("resize", updatePosition);
|
|
9382
|
+
(_a = popover.querySelector("#download-md-btn")) == null ? void 0 : _a.addEventListener("click", (e) => {
|
|
9383
|
+
e.stopPropagation();
|
|
9384
|
+
const blob = new Blob([markdown], { type: "text/markdown;charset=utf-8;" });
|
|
9385
|
+
const url = URL.createObjectURL(blob);
|
|
9386
|
+
const link = document.createElement("a");
|
|
9387
|
+
link.href = url;
|
|
9388
|
+
link.download = "document.md";
|
|
9389
|
+
link.click();
|
|
9390
|
+
URL.revokeObjectURL(url);
|
|
9391
|
+
closePopover();
|
|
9392
|
+
const event = new CustomEvent("download-click", {
|
|
9393
|
+
detail: {
|
|
9394
|
+
type: "markdown",
|
|
9395
|
+
markdown,
|
|
9396
|
+
html: view.dom.innerHTML || ""
|
|
9397
|
+
},
|
|
9398
|
+
bubbles: true,
|
|
9399
|
+
composed: true
|
|
9400
|
+
});
|
|
9401
|
+
root.dispatchEvent(event);
|
|
9402
|
+
});
|
|
9403
|
+
(_b = popover.querySelector("#download-word-btn")) == null ? void 0 : _b.addEventListener("click", (e) => {
|
|
9404
|
+
e.stopPropagation();
|
|
9405
|
+
closePopover();
|
|
9406
|
+
const event = new CustomEvent("download-click", {
|
|
9407
|
+
detail: {
|
|
9408
|
+
type: "word",
|
|
9409
|
+
markdown,
|
|
9410
|
+
html: view.dom.innerHTML || ""
|
|
9411
|
+
},
|
|
9412
|
+
bubbles: true,
|
|
9413
|
+
composed: true
|
|
9414
|
+
});
|
|
9415
|
+
root.dispatchEvent(event);
|
|
9416
|
+
});
|
|
9417
|
+
(_c = popover.querySelector("#download-pdf-btn")) == null ? void 0 : _c.addEventListener("click", (e) => {
|
|
9418
|
+
e.stopPropagation();
|
|
9419
|
+
closePopover();
|
|
9420
|
+
const event = new CustomEvent("download-click", {
|
|
9421
|
+
detail: {
|
|
9422
|
+
type: "pdf",
|
|
9423
|
+
markdown,
|
|
9424
|
+
html: view.dom.innerHTML || ""
|
|
9425
|
+
},
|
|
9426
|
+
bubbles: true,
|
|
9427
|
+
composed: true
|
|
9428
|
+
});
|
|
9429
|
+
root.dispatchEvent(event);
|
|
9430
|
+
});
|
|
9431
|
+
}
|
|
9432
|
+
function showImportPopover(rootNode, root, ctx, importItems) {
|
|
9433
|
+
var _a, _b, _c;
|
|
9434
|
+
const button = root.querySelector('button[data-key="import"]');
|
|
9435
|
+
if (!button) return;
|
|
9436
|
+
const existing = activeImportPopovers.get(button);
|
|
9437
|
+
if (existing) {
|
|
9438
|
+
existing.closePopover();
|
|
9439
|
+
return;
|
|
9440
|
+
}
|
|
9441
|
+
ensureStyles(rootNode);
|
|
9442
|
+
const container = rootNode instanceof ShadowRoot ? rootNode : document.body;
|
|
9443
|
+
const popover = document.createElement("div");
|
|
9444
|
+
popover.className = "import-popover";
|
|
9445
|
+
let popoverHtml = "";
|
|
9446
|
+
if (importItems.includes("markdown")) {
|
|
9447
|
+
popoverHtml += `
|
|
9448
|
+
<div class="import-popover-item" id="import-md-btn">
|
|
9449
|
+
<span class="import-popover-item-icon">
|
|
9450
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><line x1="10" y1="9" x2="8" y2="9"></line></svg>
|
|
9451
|
+
</span>
|
|
9452
|
+
<span>\u5BFC\u5165 MD</span>
|
|
9453
|
+
</div>
|
|
9454
|
+
`;
|
|
9455
|
+
}
|
|
9456
|
+
if (importItems.includes("word")) {
|
|
9457
|
+
popoverHtml += `
|
|
9458
|
+
<div class="import-popover-item" id="import-word-btn">
|
|
9459
|
+
<span class="import-popover-item-icon">
|
|
9460
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
|
|
9461
|
+
</span>
|
|
9462
|
+
<span>\u5BFC\u5165 WORD</span>
|
|
9463
|
+
</div>
|
|
9464
|
+
`;
|
|
9465
|
+
}
|
|
9466
|
+
if (importItems.includes("pdf")) {
|
|
9467
|
+
popoverHtml += `
|
|
9468
|
+
<div class="import-popover-item" id="import-pdf-btn">
|
|
9469
|
+
<span class="import-popover-item-icon">
|
|
9470
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>
|
|
9471
|
+
</span>
|
|
9472
|
+
<span>\u5BFC\u5165 PDF</span>
|
|
9473
|
+
</div>
|
|
9474
|
+
`;
|
|
9475
|
+
}
|
|
9476
|
+
popover.innerHTML = popoverHtml;
|
|
9477
|
+
container.appendChild(popover);
|
|
9478
|
+
activeImportPopovers.set(button, popover);
|
|
9479
|
+
const updatePosition = () => {
|
|
9480
|
+
const rect = button.getBoundingClientRect();
|
|
9481
|
+
popover.style.top = `${rect.bottom + 4}px`;
|
|
9482
|
+
popover.style.left = `${rect.left + (rect.width - 140) / 2}px`;
|
|
9483
|
+
};
|
|
9484
|
+
updatePosition();
|
|
9485
|
+
requestAnimationFrame(() => {
|
|
9486
|
+
popover.classList.add("show");
|
|
9487
|
+
});
|
|
9488
|
+
const closePopover = () => {
|
|
9489
|
+
popover.classList.remove("show");
|
|
9490
|
+
activeImportPopovers.delete(button);
|
|
9491
|
+
container.removeEventListener("pointerdown", handleContainerClick, true);
|
|
9492
|
+
document.removeEventListener("pointerdown", handleOuterClick, true);
|
|
9493
|
+
window.removeEventListener("resize", updatePosition);
|
|
9494
|
+
popover.addEventListener(
|
|
9495
|
+
"transitionend",
|
|
9496
|
+
() => {
|
|
9497
|
+
popover.remove();
|
|
9498
|
+
},
|
|
9499
|
+
{ once: true }
|
|
9500
|
+
);
|
|
9501
|
+
};
|
|
9502
|
+
popover.closePopover = closePopover;
|
|
9503
|
+
const handleContainerClick = (e) => {
|
|
9504
|
+
const target = e.target;
|
|
9505
|
+
if (!popover.contains(target) && target !== button && !button.contains(target)) {
|
|
9506
|
+
closePopover();
|
|
9507
|
+
}
|
|
9508
|
+
};
|
|
9509
|
+
const handleOuterClick = (e) => {
|
|
9510
|
+
const target = e.target;
|
|
9511
|
+
if (target !== root && !root.contains(target)) {
|
|
9512
|
+
closePopover();
|
|
9513
|
+
}
|
|
9514
|
+
};
|
|
9515
|
+
popover.addEventListener("pointerdown", (e) => {
|
|
9516
|
+
e.stopPropagation();
|
|
9517
|
+
});
|
|
9518
|
+
container.addEventListener("pointerdown", handleContainerClick, true);
|
|
9519
|
+
document.addEventListener("pointerdown", handleOuterClick, true);
|
|
9520
|
+
window.addEventListener("resize", updatePosition);
|
|
9521
|
+
(_a = popover.querySelector("#import-md-btn")) == null ? void 0 : _a.addEventListener("click", (e) => {
|
|
9522
|
+
e.stopPropagation();
|
|
9523
|
+
closePopover();
|
|
9524
|
+
const input = document.createElement("input");
|
|
9525
|
+
input.type = "file";
|
|
9526
|
+
input.accept = ".md";
|
|
9527
|
+
input.onchange = (evt) => {
|
|
9528
|
+
var _a2;
|
|
9529
|
+
const file = (_a2 = evt.target.files) == null ? void 0 : _a2[0];
|
|
9530
|
+
if (!file) return;
|
|
9531
|
+
file.text().then((text) => {
|
|
9532
|
+
replaceAll(text)(ctx);
|
|
9533
|
+
const event = new CustomEvent("import-click", {
|
|
9534
|
+
detail: { type: "markdown", file },
|
|
9535
|
+
bubbles: true,
|
|
9536
|
+
composed: true
|
|
9537
|
+
});
|
|
9538
|
+
root.dispatchEvent(event);
|
|
9539
|
+
}).catch((err) => {
|
|
9540
|
+
console.error("Failed to read file:", err);
|
|
9541
|
+
});
|
|
9542
|
+
};
|
|
9543
|
+
input.click();
|
|
9544
|
+
});
|
|
9545
|
+
(_b = popover.querySelector("#import-word-btn")) == null ? void 0 : _b.addEventListener("click", (e) => {
|
|
9546
|
+
e.stopPropagation();
|
|
9547
|
+
closePopover();
|
|
9548
|
+
const event = new CustomEvent("import-click", {
|
|
9549
|
+
detail: { type: "word" },
|
|
9550
|
+
bubbles: true,
|
|
9551
|
+
composed: true
|
|
9552
|
+
});
|
|
9553
|
+
root.dispatchEvent(event);
|
|
9554
|
+
});
|
|
9555
|
+
(_c = popover.querySelector("#import-pdf-btn")) == null ? void 0 : _c.addEventListener("click", (e) => {
|
|
9556
|
+
e.stopPropagation();
|
|
9557
|
+
closePopover();
|
|
9558
|
+
const event = new CustomEvent("import-click", {
|
|
9559
|
+
detail: { type: "pdf" },
|
|
9560
|
+
bubbles: true,
|
|
9561
|
+
composed: true
|
|
9562
|
+
});
|
|
9563
|
+
root.dispatchEvent(event);
|
|
9564
|
+
});
|
|
9565
|
+
}
|
|
9152
9566
|
|
|
9153
9567
|
keepAlive(h);
|
|
9154
9568
|
const DocumentHeader = defineComponent({
|