@underverse-ui/underverse 1.0.144 → 1.0.146

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/index.js CHANGED
@@ -25758,6 +25758,26 @@ function extractClipboardHtmlFragment(html) {
25758
25758
  }
25759
25759
  return html;
25760
25760
  }
25761
+ var EMPTY_TABLE_CELL_HTML = "<p></p>";
25762
+ var TABLE_MEDIA_SELECTOR = "img,video,audio,iframe,svg,canvas,embed,object";
25763
+ var TABLE_BLOCK_SELECTOR = "p,ul,ol,blockquote,pre,h1,h2,h3,h4,h5,h6,hr,table";
25764
+ function hasMeaningfulTableCellText(value) {
25765
+ return Boolean(value?.replace(/\u00a0/g, " ").trim());
25766
+ }
25767
+ function normalizeClipboardTableCell(cell) {
25768
+ const hasText = hasMeaningfulTableCellText(cell.textContent);
25769
+ const hasBlockContent = Boolean(cell.querySelector(TABLE_BLOCK_SELECTOR));
25770
+ const hasMediaContent = Boolean(cell.querySelector(TABLE_MEDIA_SELECTOR));
25771
+ if (!hasText && !hasBlockContent && !hasMediaContent) {
25772
+ cell.innerHTML = EMPTY_TABLE_CELL_HTML;
25773
+ }
25774
+ }
25775
+ function normalizeClipboardTable(table) {
25776
+ for (const cell of Array.from(table.querySelectorAll("td,th"))) {
25777
+ if (!(cell instanceof HTMLTableCellElement)) continue;
25778
+ normalizeClipboardTableCell(cell);
25779
+ }
25780
+ }
25761
25781
  function getClipboardTableHtml(dataTransfer) {
25762
25782
  const html = getClipboardData(dataTransfer, "text/html");
25763
25783
  if (!/<table(?:\s|>)/i.test(html)) return "";
@@ -25765,19 +25785,81 @@ function getClipboardTableHtml(dataTransfer) {
25765
25785
  if (typeof DOMParser !== "undefined") {
25766
25786
  const doc = new DOMParser().parseFromString(fragment, "text/html");
25767
25787
  const table = doc.querySelector("table");
25768
- if (table) return table.outerHTML;
25788
+ if (table instanceof HTMLTableElement) {
25789
+ normalizeClipboardTable(table);
25790
+ return table.outerHTML;
25791
+ }
25769
25792
  }
25770
25793
  return fragment;
25771
25794
  }
25772
25795
  function escapeHtml(value) {
25773
25796
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
25774
25797
  }
25798
+ function parseClipboardTsvRows(text) {
25799
+ const rows = [];
25800
+ let row = [];
25801
+ let field = "";
25802
+ let inQuotes = false;
25803
+ const pushField = () => {
25804
+ row.push(field);
25805
+ field = "";
25806
+ };
25807
+ const pushRow = () => {
25808
+ pushField();
25809
+ rows.push(row);
25810
+ row = [];
25811
+ };
25812
+ for (let index = 0; index < text.length; index += 1) {
25813
+ const char = text[index];
25814
+ const nextChar = text[index + 1];
25815
+ if (inQuotes) {
25816
+ if (char === '"' && nextChar === '"') {
25817
+ field += '"';
25818
+ index += 1;
25819
+ continue;
25820
+ }
25821
+ if (char === '"') {
25822
+ inQuotes = false;
25823
+ continue;
25824
+ }
25825
+ field += char;
25826
+ continue;
25827
+ }
25828
+ if (char === '"' && field.length === 0) {
25829
+ inQuotes = true;
25830
+ continue;
25831
+ }
25832
+ if (char === " ") {
25833
+ pushField();
25834
+ continue;
25835
+ }
25836
+ if (char === "\n") {
25837
+ pushRow();
25838
+ continue;
25839
+ }
25840
+ field += char;
25841
+ }
25842
+ pushRow();
25843
+ while (rows.length > 0 && rows[rows.length - 1].every((cell) => cell === "")) {
25844
+ rows.pop();
25845
+ }
25846
+ return rows;
25847
+ }
25848
+ function renderClipboardTableCellHtml(value) {
25849
+ const lines = value.split("\n");
25850
+ const paragraphs = lines.length > 0 ? lines : [""];
25851
+ return paragraphs.map((line) => `<p>${escapeHtml(line)}</p>`).join("");
25852
+ }
25775
25853
  function getClipboardTsvTableHtml(dataTransfer) {
25776
- const text = getClipboardData(dataTransfer, "text/plain").replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\n+$/, "");
25854
+ const text = getClipboardData(dataTransfer, "text/plain").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
25777
25855
  if (!text.includes(" ")) return "";
25778
- const rows = text.split("\n").map((row) => row.split(" "));
25856
+ const rows = parseClipboardTsvRows(text);
25779
25857
  if (rows.length === 0 || rows.every((row) => row.length < 2)) return "";
25780
- const body = rows.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).join("")}</tr>`).join("");
25858
+ const columnCount = rows.reduce((max, row) => Math.max(max, row.length), 0);
25859
+ const body = rows.map((row) => {
25860
+ const normalizedRow = Array.from({ length: columnCount }, (_, index) => row[index] ?? "");
25861
+ return `<tr>${normalizedRow.map((cell) => `<td>${renderClipboardTableCellHtml(cell)}</td>`).join("")}</tr>`;
25862
+ }).join("");
25781
25863
  return `<table><tbody>${body}</tbody></table>`;
25782
25864
  }
25783
25865
  function fileToDataUrl(file) {
@@ -36166,7 +36248,8 @@ import {
36166
36248
  Trash2 as Trash25,
36167
36249
  Underline as UnderlineIcon3,
36168
36250
  Undo as UndoIcon2,
36169
- Upload as Upload4
36251
+ Upload as Upload4,
36252
+ X as X19
36170
36253
  } from "lucide-react";
36171
36254
  import { Fragment as Fragment35, jsx as jsx92, jsxs as jsxs77 } from "react/jsx-runtime";
36172
36255
  function MenuTableInsertGrid({
@@ -36664,6 +36747,14 @@ var MenuBar = ({
36664
36747
  }
36665
36748
  openPreviewDialog();
36666
36749
  };
36750
+ React81.useEffect(() => {
36751
+ if (!showPreviewDialog) return void 0;
36752
+ const previousOverflow = document.body.style.overflow;
36753
+ document.body.style.overflow = "hidden";
36754
+ return () => {
36755
+ document.body.style.overflow = previousOverflow;
36756
+ };
36757
+ }, [showPreviewDialog]);
36667
36758
  const applySourceHtml = () => {
36668
36759
  editor.chain().focus().setContent(sourceHtml).run();
36669
36760
  setShowSourceDialog(false);
@@ -36881,29 +36972,38 @@ var MenuBar = ({
36881
36972
  ] })
36882
36973
  }
36883
36974
  ),
36884
- /* @__PURE__ */ jsx92(
36885
- Modal_default,
36886
- {
36887
- isOpen: showPreviewDialog,
36888
- onClose: () => setShowPreviewDialog(false),
36889
- title: t("menubar.preview"),
36890
- size: "lg",
36891
- children: editor.isEmpty ? /* @__PURE__ */ jsx92("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx92(
36892
- "div",
36975
+ showPreviewDialog && /* @__PURE__ */ jsxs77("div", { className: "fixed inset-0 z-9999 flex flex-col bg-background text-foreground", children: [
36976
+ /* @__PURE__ */ jsxs77("div", { className: "flex shrink-0 items-center justify-between border-b border-border bg-card px-4 py-3", children: [
36977
+ /* @__PURE__ */ jsx92("h2", { className: "text-base font-semibold", children: t("menubar.preview") }),
36978
+ /* @__PURE__ */ jsx92(
36979
+ "button",
36893
36980
  {
36894
- "data-testid": "preview-content",
36895
- className: "max-h-[70vh] overflow-y-auto overscroll-contain pr-2",
36896
- children: /* @__PURE__ */ jsx92(
36897
- "div",
36898
- {
36899
- className: UEDITOR_PROSEMIRROR_CLASS_NAME,
36900
- dangerouslySetInnerHTML: { __html: editor.getHTML() }
36901
- }
36902
- )
36981
+ type: "button",
36982
+ onClick: () => setShowPreviewDialog(false),
36983
+ "aria-label": t("menubar.closeDialog"),
36984
+ className: cn(
36985
+ "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors",
36986
+ "hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
36987
+ ),
36988
+ children: /* @__PURE__ */ jsx92(X19, { className: "h-4 w-4", "aria-hidden": "true" })
36903
36989
  }
36904
36990
  )
36905
- }
36906
- )
36991
+ ] }),
36992
+ /* @__PURE__ */ jsx92(
36993
+ "div",
36994
+ {
36995
+ "data-testid": "preview-content",
36996
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 md:px-8",
36997
+ children: editor.isEmpty ? /* @__PURE__ */ jsx92("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx92(
36998
+ "div",
36999
+ {
37000
+ className: UEDITOR_PROSEMIRROR_CLASS_NAME,
37001
+ dangerouslySetInnerHTML: { __html: editor.getHTML() }
37002
+ }
37003
+ )
37004
+ }
37005
+ )
37006
+ ] })
36907
37007
  ] });
36908
37008
  };
36909
37009