@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.
Files changed (34) hide show
  1. package/lib/cjs/feature/block-edit/index.js +3 -3
  2. package/lib/cjs/feature/block-edit/index.js.map +1 -1
  3. package/lib/cjs/feature/toolbar/index.js +1 -1
  4. package/lib/cjs/feature/toolbar/index.js.map +1 -1
  5. package/lib/cjs/index.js +420 -6
  6. package/lib/cjs/index.js.map +1 -1
  7. package/lib/esm/feature/block-edit/index.js +3 -3
  8. package/lib/esm/feature/block-edit/index.js.map +1 -1
  9. package/lib/esm/feature/toolbar/index.js +1 -1
  10. package/lib/esm/feature/toolbar/index.js.map +1 -1
  11. package/lib/esm/index.js +421 -7
  12. package/lib/esm/index.js.map +1 -1
  13. package/lib/theme/common/block-edit.css +5 -3
  14. package/lib/theme/common/code-mirror.css +19 -0
  15. package/lib/theme/common/link-tooltip.css +2 -2
  16. package/lib/theme/common/toolbar.css +1 -1
  17. package/lib/tsconfig.tsbuildinfo +1 -1
  18. package/lib/types/default-config/index.d.ts.map +1 -1
  19. package/lib/types/feature/block-edit/handle/index.d.ts.map +1 -1
  20. package/lib/types/feature/block-edit/menu/component.d.ts.map +1 -1
  21. package/lib/types/feature/fixed-toolbar/config.d.ts.map +1 -1
  22. package/lib/types/feature/fixed-toolbar/index.d.ts +2 -0
  23. package/lib/types/feature/fixed-toolbar/index.d.ts.map +1 -1
  24. package/package.json +4 -4
  25. package/src/default-config/default-config.spec.ts +15 -0
  26. package/src/default-config/index.ts +17 -1
  27. package/src/feature/block-edit/handle/index.ts +8 -2
  28. package/src/feature/block-edit/menu/component.tsx +4 -1
  29. package/src/feature/fixed-toolbar/config.ts +482 -3
  30. package/src/feature/fixed-toolbar/index.ts +2 -0
  31. package/src/theme/common/block-edit.css +5 -3
  32. package/src/theme/common/code-mirror.css +19 -0
  33. package/src/theme/common/link-tooltip.css +2 -2
  34. package/src/theme/common/toolbar.css +1 -1
package/lib/cjs/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var utils$1 = require('@jvs-milkdown/utils');
4
4
  var lodashEs = require('lodash-es');
5
+ var language = require('@codemirror/language');
5
6
  var languageData = require('@codemirror/language-data');
6
7
  var themeOneDark = require('@codemirror/theme-one-dark');
7
8
  var ctx = require('@jvs-milkdown/kit/ctx');
@@ -696,10 +697,21 @@ const importIcon = `
696
697
  </svg>
697
698
  `;
698
699
 
700
+ const mermaidLanguage = language.LanguageDescription.of({
701
+ name: "Mermaid",
702
+ alias: ["mermaid"],
703
+ load: () => {
704
+ const fallback = languageData.languages.find((l) => l.name === "YAML") || languageData.languages.find((l) => l.name === "Markdown");
705
+ return fallback ? fallback.load() : Promise.resolve(null);
706
+ }
707
+ });
708
+ const allLanguages = [mermaidLanguage, ...languageData.languages].sort(
709
+ (a, b) => a.name.localeCompare(b.name)
710
+ );
699
711
  const defaultConfig = {
700
712
  [CrepeFeature.CodeMirror]: {
701
713
  theme: themeOneDark.oneDark,
702
- languages: languageData.languages,
714
+ languages: allLanguages,
703
715
  expandIcon: chevronDownIcon,
704
716
  searchIcon,
705
717
  clearSearchIcon: clearIcon,
@@ -3085,7 +3097,7 @@ const Menu = vue.defineComponent({
3085
3097
  const isTableBlock = (node == null ? void 0 : node.type.name) === "table";
3086
3098
  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;
3087
3099
  const showAlign = !isMedia || isImageBlock;
3088
- const isEmpty = node ? node.textContent.length === 0 && node.content.size <= 2 && !isMedia : false;
3100
+ const isEmpty = node ? node.type.name === "paragraph" && node.textContent.length === 0 && node.content.size <= 2 && !isMedia : false;
3089
3101
  const currentAlign = ((_b = node == null ? void 0 : node.attrs) == null ? void 0 : _b.align) || "left";
3090
3102
  const currentIndent = ((_c = node == null ? void 0 : node.attrs) == null ? void 0 : _c.indent) || 0;
3091
3103
  const setAlign = (alignValue) => {
@@ -4041,7 +4053,7 @@ class BlockHandleView {
4041
4053
  });
4042
4054
  }
4043
4055
  const isMedia = node.type.name.includes("image") || node.type.name.includes("attachment") || node.type.name === "hr" || node.type.name.includes("math") || hasMediaChild;
4044
- const isEmpty = node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
4056
+ const isEmpty = node.type.name === "paragraph" && node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
4045
4057
  if (isEmpty) {
4046
4058
  __privateGet$5(this, _content$3).classList.add("empty-block");
4047
4059
  } else {
@@ -4192,7 +4204,7 @@ class BlockHandleView {
4192
4204
  });
4193
4205
  }
4194
4206
  const isMedia = node.type.name.includes("image") || node.type.name.includes("attachment") || node.type.name === "hr" || node.type.name.includes("math") || hasMediaChild;
4195
- const isEmpty = node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
4207
+ const isEmpty = node.type.name === "paragraph" && node.textContent.length === 0 && node.content.size <= 2 && !isMedia;
4196
4208
  if (isEmpty) {
4197
4209
  __privateGet$5(this, _content$3).classList.add("empty-block");
4198
4210
  } else {
@@ -9117,7 +9129,17 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
9117
9129
  active: () => false,
9118
9130
  onRun: (ctx2) => {
9119
9131
  const markdown = utils.getMarkdown()(ctx2);
9120
- if (_config == null ? void 0 : _config.onExport) {
9132
+ const view = ctx2.get(core.editorViewCtx);
9133
+ const root = ctx2.get(core.rootCtx);
9134
+ const rootNode = view.dom.getRootNode();
9135
+ if ((_config == null ? void 0 : _config.exportItems) && _config.exportItems.length > 0) {
9136
+ const exportItems = _config.exportItems;
9137
+ if (exportItems.length === 1) {
9138
+ handleDirectExport(exportItems[0], markdown, view, root);
9139
+ } else {
9140
+ showDownloadPopover(rootNode, root, view, markdown, exportItems);
9141
+ }
9142
+ } else if (_config == null ? void 0 : _config.onExport) {
9121
9143
  _config.onExport(markdown, ctx2);
9122
9144
  } else {
9123
9145
  const blob = new Blob([markdown], {
@@ -9139,7 +9161,17 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
9139
9161
  icon: importIcon,
9140
9162
  active: () => false,
9141
9163
  onRun: (ctx2) => {
9142
- if (_config == null ? void 0 : _config.onImport) {
9164
+ const view = ctx2.get(core.editorViewCtx);
9165
+ const root = ctx2.get(core.rootCtx);
9166
+ const rootNode = view.dom.getRootNode();
9167
+ if ((_config == null ? void 0 : _config.importItems) && _config.importItems.length > 0) {
9168
+ const importItems = _config.importItems;
9169
+ if (importItems.length === 1) {
9170
+ handleDirectImport(importItems[0], root, ctx2);
9171
+ } else {
9172
+ showImportPopover(rootNode, root, ctx2, importItems);
9173
+ }
9174
+ } else if (_config == null ? void 0 : _config.onImport) {
9143
9175
  _config.onImport((markdown) => utils$1.replaceAll(markdown)(ctx2), ctx2);
9144
9176
  } else {
9145
9177
  const input = document.createElement("input");
@@ -9170,6 +9202,388 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
9170
9202
  });
9171
9203
  return builder.build();
9172
9204
  }
9205
+ const activeDownloadPopovers = /* @__PURE__ */ new WeakMap();
9206
+ const activeImportPopovers = /* @__PURE__ */ new WeakMap();
9207
+ const ensureStyles = (rootNode) => {
9208
+ const target = rootNode instanceof ShadowRoot ? rootNode : document.head;
9209
+ if (target.querySelector("#download-popover-styles")) return;
9210
+ const styleEl = document.createElement("style");
9211
+ styleEl.id = "download-popover-styles";
9212
+ styleEl.textContent = `
9213
+ .download-popover, .import-popover {
9214
+ position: fixed;
9215
+ z-index: 10000;
9216
+ width: 140px;
9217
+ padding: 6px 0;
9218
+ display: flex;
9219
+ flex-direction: column;
9220
+ background-color: var(--crepe-color-surface, #ffffff);
9221
+ border: 1px solid var(--crepe-color-outline-variant, color-mix(in srgb, var(--crepe-color-outline), transparent 80%));
9222
+ border-radius: 8px;
9223
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
9224
+ opacity: 0;
9225
+ transform: translateY(-8px);
9226
+ transition: opacity 0.15s ease, transform 0.15s ease;
9227
+ pointer-events: none;
9228
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
9229
+ }
9230
+ .download-popover.show, .import-popover.show {
9231
+ opacity: 1;
9232
+ transform: translateY(0);
9233
+ pointer-events: auto;
9234
+ }
9235
+ .download-popover-item, .import-popover-item {
9236
+ cursor: pointer;
9237
+ padding: 8px 14px;
9238
+ display: flex;
9239
+ align-items: center;
9240
+ gap: 8px;
9241
+ font-size: 13px;
9242
+ font-weight: 500;
9243
+ color: var(--crepe-color-primary, #363B4C);
9244
+ transition: background-color 0.2s;
9245
+ user-select: none;
9246
+ }
9247
+ .download-popover-item:hover, .import-popover-item:hover {
9248
+ background-color: var(--crepe-color-hover, #f5f5f5);
9249
+ }
9250
+ .download-popover-item-icon, .import-popover-item-icon {
9251
+ display: flex;
9252
+ align-items: center;
9253
+ justify-content: center;
9254
+ width: 14px;
9255
+ height: 14px;
9256
+ color: var(--crepe-color-primary, #363B4C);
9257
+ opacity: 0.8;
9258
+ }
9259
+ `;
9260
+ target.appendChild(styleEl);
9261
+ };
9262
+ function handleDirectExport(type, markdown, view, root) {
9263
+ if (type === "markdown") {
9264
+ const blob = new Blob([markdown], { type: "text/markdown;charset=utf-8;" });
9265
+ const url = URL.createObjectURL(blob);
9266
+ const link = document.createElement("a");
9267
+ link.href = url;
9268
+ link.download = "document.md";
9269
+ link.click();
9270
+ URL.revokeObjectURL(url);
9271
+ }
9272
+ const event = new CustomEvent("download-click", {
9273
+ detail: {
9274
+ type,
9275
+ markdown,
9276
+ html: view.dom.innerHTML || ""
9277
+ },
9278
+ bubbles: true,
9279
+ composed: true
9280
+ });
9281
+ root.dispatchEvent(event);
9282
+ }
9283
+ function handleDirectImport(type, root, ctx) {
9284
+ if (type === "markdown") {
9285
+ const input = document.createElement("input");
9286
+ input.type = "file";
9287
+ input.accept = ".md";
9288
+ input.onchange = (evt) => {
9289
+ var _a;
9290
+ const file = (_a = evt.target.files) == null ? void 0 : _a[0];
9291
+ if (!file) return;
9292
+ file.text().then((text) => {
9293
+ utils$1.replaceAll(text)(ctx);
9294
+ const event = new CustomEvent("import-click", {
9295
+ detail: { type: "markdown", file },
9296
+ bubbles: true,
9297
+ composed: true
9298
+ });
9299
+ root.dispatchEvent(event);
9300
+ }).catch((err) => {
9301
+ console.error("Failed to read file:", err);
9302
+ });
9303
+ };
9304
+ input.click();
9305
+ } else {
9306
+ const event = new CustomEvent("import-click", {
9307
+ detail: { type },
9308
+ bubbles: true,
9309
+ composed: true
9310
+ });
9311
+ root.dispatchEvent(event);
9312
+ }
9313
+ }
9314
+ function showDownloadPopover(rootNode, root, view, markdown, exportItems) {
9315
+ var _a, _b, _c;
9316
+ const button = root.querySelector('button[data-key="export"]');
9317
+ if (!button) return;
9318
+ const existing = activeDownloadPopovers.get(button);
9319
+ if (existing) {
9320
+ existing.closePopover();
9321
+ return;
9322
+ }
9323
+ ensureStyles(rootNode);
9324
+ const container = rootNode instanceof ShadowRoot ? rootNode : document.body;
9325
+ const popover = document.createElement("div");
9326
+ popover.className = "download-popover";
9327
+ let popoverHtml = "";
9328
+ if (exportItems.includes("markdown")) {
9329
+ popoverHtml += `
9330
+ <div class="download-popover-item" id="download-md-btn">
9331
+ <span class="download-popover-item-icon">
9332
+ <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>
9333
+ </span>
9334
+ <span>\u4E0B\u8F7D MD</span>
9335
+ </div>
9336
+ `;
9337
+ }
9338
+ if (exportItems.includes("word")) {
9339
+ popoverHtml += `
9340
+ <div class="download-popover-item" id="download-word-btn">
9341
+ <span class="download-popover-item-icon">
9342
+ <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>
9343
+ </span>
9344
+ <span>\u4E0B\u8F7D WORD</span>
9345
+ </div>
9346
+ `;
9347
+ }
9348
+ if (exportItems.includes("pdf")) {
9349
+ popoverHtml += `
9350
+ <div class="download-popover-item" id="download-pdf-btn">
9351
+ <span class="download-popover-item-icon">
9352
+ <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>
9353
+ </span>
9354
+ <span>\u4E0B\u8F7D PDF</span>
9355
+ </div>
9356
+ `;
9357
+ }
9358
+ popover.innerHTML = popoverHtml;
9359
+ container.appendChild(popover);
9360
+ activeDownloadPopovers.set(button, popover);
9361
+ const updatePosition = () => {
9362
+ const rect = button.getBoundingClientRect();
9363
+ popover.style.top = `${rect.bottom + 4}px`;
9364
+ popover.style.left = `${rect.left + (rect.width - 140) / 2}px`;
9365
+ };
9366
+ updatePosition();
9367
+ requestAnimationFrame(() => {
9368
+ popover.classList.add("show");
9369
+ });
9370
+ const closePopover = () => {
9371
+ popover.classList.remove("show");
9372
+ activeDownloadPopovers.delete(button);
9373
+ container.removeEventListener("pointerdown", handleContainerClick, true);
9374
+ document.removeEventListener("pointerdown", handleOuterClick, true);
9375
+ window.removeEventListener("resize", updatePosition);
9376
+ popover.addEventListener(
9377
+ "transitionend",
9378
+ () => {
9379
+ popover.remove();
9380
+ },
9381
+ { once: true }
9382
+ );
9383
+ };
9384
+ popover.closePopover = closePopover;
9385
+ const handleContainerClick = (e) => {
9386
+ const target = e.target;
9387
+ if (!popover.contains(target) && target !== button && !button.contains(target)) {
9388
+ closePopover();
9389
+ }
9390
+ };
9391
+ const handleOuterClick = (e) => {
9392
+ const target = e.target;
9393
+ if (target !== root && !root.contains(target)) {
9394
+ closePopover();
9395
+ }
9396
+ };
9397
+ popover.addEventListener("pointerdown", (e) => {
9398
+ e.stopPropagation();
9399
+ });
9400
+ container.addEventListener("pointerdown", handleContainerClick, true);
9401
+ document.addEventListener("pointerdown", handleOuterClick, true);
9402
+ window.addEventListener("resize", updatePosition);
9403
+ (_a = popover.querySelector("#download-md-btn")) == null ? void 0 : _a.addEventListener("click", (e) => {
9404
+ e.stopPropagation();
9405
+ const blob = new Blob([markdown], { type: "text/markdown;charset=utf-8;" });
9406
+ const url = URL.createObjectURL(blob);
9407
+ const link = document.createElement("a");
9408
+ link.href = url;
9409
+ link.download = "document.md";
9410
+ link.click();
9411
+ URL.revokeObjectURL(url);
9412
+ closePopover();
9413
+ const event = new CustomEvent("download-click", {
9414
+ detail: {
9415
+ type: "markdown",
9416
+ markdown,
9417
+ html: view.dom.innerHTML || ""
9418
+ },
9419
+ bubbles: true,
9420
+ composed: true
9421
+ });
9422
+ root.dispatchEvent(event);
9423
+ });
9424
+ (_b = popover.querySelector("#download-word-btn")) == null ? void 0 : _b.addEventListener("click", (e) => {
9425
+ e.stopPropagation();
9426
+ closePopover();
9427
+ const event = new CustomEvent("download-click", {
9428
+ detail: {
9429
+ type: "word",
9430
+ markdown,
9431
+ html: view.dom.innerHTML || ""
9432
+ },
9433
+ bubbles: true,
9434
+ composed: true
9435
+ });
9436
+ root.dispatchEvent(event);
9437
+ });
9438
+ (_c = popover.querySelector("#download-pdf-btn")) == null ? void 0 : _c.addEventListener("click", (e) => {
9439
+ e.stopPropagation();
9440
+ closePopover();
9441
+ const event = new CustomEvent("download-click", {
9442
+ detail: {
9443
+ type: "pdf",
9444
+ markdown,
9445
+ html: view.dom.innerHTML || ""
9446
+ },
9447
+ bubbles: true,
9448
+ composed: true
9449
+ });
9450
+ root.dispatchEvent(event);
9451
+ });
9452
+ }
9453
+ function showImportPopover(rootNode, root, ctx, importItems) {
9454
+ var _a, _b, _c;
9455
+ const button = root.querySelector('button[data-key="import"]');
9456
+ if (!button) return;
9457
+ const existing = activeImportPopovers.get(button);
9458
+ if (existing) {
9459
+ existing.closePopover();
9460
+ return;
9461
+ }
9462
+ ensureStyles(rootNode);
9463
+ const container = rootNode instanceof ShadowRoot ? rootNode : document.body;
9464
+ const popover = document.createElement("div");
9465
+ popover.className = "import-popover";
9466
+ let popoverHtml = "";
9467
+ if (importItems.includes("markdown")) {
9468
+ popoverHtml += `
9469
+ <div class="import-popover-item" id="import-md-btn">
9470
+ <span class="import-popover-item-icon">
9471
+ <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>
9472
+ </span>
9473
+ <span>\u5BFC\u5165 MD</span>
9474
+ </div>
9475
+ `;
9476
+ }
9477
+ if (importItems.includes("word")) {
9478
+ popoverHtml += `
9479
+ <div class="import-popover-item" id="import-word-btn">
9480
+ <span class="import-popover-item-icon">
9481
+ <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>
9482
+ </span>
9483
+ <span>\u5BFC\u5165 WORD</span>
9484
+ </div>
9485
+ `;
9486
+ }
9487
+ if (importItems.includes("pdf")) {
9488
+ popoverHtml += `
9489
+ <div class="import-popover-item" id="import-pdf-btn">
9490
+ <span class="import-popover-item-icon">
9491
+ <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>
9492
+ </span>
9493
+ <span>\u5BFC\u5165 PDF</span>
9494
+ </div>
9495
+ `;
9496
+ }
9497
+ popover.innerHTML = popoverHtml;
9498
+ container.appendChild(popover);
9499
+ activeImportPopovers.set(button, popover);
9500
+ const updatePosition = () => {
9501
+ const rect = button.getBoundingClientRect();
9502
+ popover.style.top = `${rect.bottom + 4}px`;
9503
+ popover.style.left = `${rect.left + (rect.width - 140) / 2}px`;
9504
+ };
9505
+ updatePosition();
9506
+ requestAnimationFrame(() => {
9507
+ popover.classList.add("show");
9508
+ });
9509
+ const closePopover = () => {
9510
+ popover.classList.remove("show");
9511
+ activeImportPopovers.delete(button);
9512
+ container.removeEventListener("pointerdown", handleContainerClick, true);
9513
+ document.removeEventListener("pointerdown", handleOuterClick, true);
9514
+ window.removeEventListener("resize", updatePosition);
9515
+ popover.addEventListener(
9516
+ "transitionend",
9517
+ () => {
9518
+ popover.remove();
9519
+ },
9520
+ { once: true }
9521
+ );
9522
+ };
9523
+ popover.closePopover = closePopover;
9524
+ const handleContainerClick = (e) => {
9525
+ const target = e.target;
9526
+ if (!popover.contains(target) && target !== button && !button.contains(target)) {
9527
+ closePopover();
9528
+ }
9529
+ };
9530
+ const handleOuterClick = (e) => {
9531
+ const target = e.target;
9532
+ if (target !== root && !root.contains(target)) {
9533
+ closePopover();
9534
+ }
9535
+ };
9536
+ popover.addEventListener("pointerdown", (e) => {
9537
+ e.stopPropagation();
9538
+ });
9539
+ container.addEventListener("pointerdown", handleContainerClick, true);
9540
+ document.addEventListener("pointerdown", handleOuterClick, true);
9541
+ window.addEventListener("resize", updatePosition);
9542
+ (_a = popover.querySelector("#import-md-btn")) == null ? void 0 : _a.addEventListener("click", (e) => {
9543
+ e.stopPropagation();
9544
+ closePopover();
9545
+ const input = document.createElement("input");
9546
+ input.type = "file";
9547
+ input.accept = ".md";
9548
+ input.onchange = (evt) => {
9549
+ var _a2;
9550
+ const file = (_a2 = evt.target.files) == null ? void 0 : _a2[0];
9551
+ if (!file) return;
9552
+ file.text().then((text) => {
9553
+ utils$1.replaceAll(text)(ctx);
9554
+ const event = new CustomEvent("import-click", {
9555
+ detail: { type: "markdown", file },
9556
+ bubbles: true,
9557
+ composed: true
9558
+ });
9559
+ root.dispatchEvent(event);
9560
+ }).catch((err) => {
9561
+ console.error("Failed to read file:", err);
9562
+ });
9563
+ };
9564
+ input.click();
9565
+ });
9566
+ (_b = popover.querySelector("#import-word-btn")) == null ? void 0 : _b.addEventListener("click", (e) => {
9567
+ e.stopPropagation();
9568
+ closePopover();
9569
+ const event = new CustomEvent("import-click", {
9570
+ detail: { type: "word" },
9571
+ bubbles: true,
9572
+ composed: true
9573
+ });
9574
+ root.dispatchEvent(event);
9575
+ });
9576
+ (_c = popover.querySelector("#import-pdf-btn")) == null ? void 0 : _c.addEventListener("click", (e) => {
9577
+ e.stopPropagation();
9578
+ closePopover();
9579
+ const event = new CustomEvent("import-click", {
9580
+ detail: { type: "pdf" },
9581
+ bubbles: true,
9582
+ composed: true
9583
+ });
9584
+ root.dispatchEvent(event);
9585
+ });
9586
+ }
9173
9587
 
9174
9588
  keepAlive(vue.h);
9175
9589
  const DocumentHeader = vue.defineComponent({