@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/api-reference.json +1 -1
- package/dist/index.cjs +123 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +125 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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)
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
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")
|
|
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
|
|
25856
|
+
const rows = parseClipboardTsvRows(text);
|
|
25779
25857
|
if (rows.length === 0 || rows.every((row) => row.length < 2)) return "";
|
|
25780
|
-
const
|
|
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__ */
|
|
36885
|
-
|
|
36886
|
-
|
|
36887
|
-
|
|
36888
|
-
|
|
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
|
-
|
|
36895
|
-
|
|
36896
|
-
|
|
36897
|
-
|
|
36898
|
-
|
|
36899
|
-
|
|
36900
|
-
|
|
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
|
|