@underverse-ui/underverse 1.0.147 → 1.0.149

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.147",
3
+ "version": "1.0.149",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 232,
6
6
  "exports": [
package/dist/index.cjs CHANGED
@@ -25835,67 +25835,7 @@ var SlashCommand = import_core4.Extension.create({
25835
25835
  var import_core5 = require("@tiptap/core");
25836
25836
  var import_state2 = require("@tiptap/pm/state");
25837
25837
 
25838
- // src/components/UEditor/url-safety.ts
25839
- var LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
25840
- var IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
25841
- function normalizeUrlInput(raw) {
25842
- return raw.trim().replace(/[\u0000-\u001F\u007F\s]+/g, "");
25843
- }
25844
- function isProtocolRelativeUrl(value) {
25845
- return value.startsWith("//");
25846
- }
25847
- function isRelativeUrl(value) {
25848
- return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#");
25849
- }
25850
- function isDataImageUrl(value) {
25851
- return /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|bmp|x-icon|avif);base64,/i.test(value);
25852
- }
25853
- function isSafeUEditorUrl(raw, kind) {
25854
- const value = normalizeUrlInput(raw);
25855
- if (!value) return false;
25856
- if (kind === "image" && isDataImageUrl(value)) return true;
25857
- if (isRelativeUrl(value)) return true;
25858
- if (isProtocolRelativeUrl(value)) return false;
25859
- try {
25860
- const parsed = new URL(value);
25861
- return kind === "image" ? IMAGE_PROTOCOLS.has(parsed.protocol) : LINK_PROTOCOLS.has(parsed.protocol);
25862
- } catch {
25863
- return false;
25864
- }
25865
- }
25866
- function sanitizeUEditorUrl(raw, kind) {
25867
- const value = raw.trim();
25868
- if (!value) return "";
25869
- if (isSafeUEditorUrl(value, kind)) return normalizeUrlInput(value);
25870
- if (kind === "link" && !isProtocolRelativeUrl(value) && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
25871
- const withProtocol = `https://${value}`;
25872
- return isSafeUEditorUrl(withProtocol, kind) ? withProtocol : "";
25873
- }
25874
- return "";
25875
- }
25876
-
25877
- // src/components/UEditor/clipboard-images.ts
25878
- var DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE = 10 * 1024 * 1024;
25879
- var DEFAULT_UEDITOR_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"];
25880
- function getImageFiles(dataTransfer) {
25881
- if (!dataTransfer) return [];
25882
- const itemFiles = [];
25883
- const byKey = /* @__PURE__ */ new Map();
25884
- for (const item of Array.from(dataTransfer.items ?? [])) {
25885
- if (item.kind !== "file") continue;
25886
- if (!item.type.startsWith("image/")) continue;
25887
- const file = item.getAsFile();
25888
- if (!file) continue;
25889
- byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
25890
- }
25891
- itemFiles.push(...Array.from(byKey.values()));
25892
- if (itemFiles.length > 0) return itemFiles;
25893
- for (const file of Array.from(dataTransfer.files ?? [])) {
25894
- if (!file.type.startsWith("image/")) continue;
25895
- byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
25896
- }
25897
- return Array.from(byKey.values());
25898
- }
25838
+ // src/components/UEditor/clipboard-tables.ts
25899
25839
  function getClipboardData(dataTransfer, type) {
25900
25840
  try {
25901
25841
  return dataTransfer.getData(type) ?? "";
@@ -26044,6 +25984,68 @@ function getClipboardTsvTableContent(dataTransfer) {
26044
25984
  2
26045
25985
  );
26046
25986
  }
25987
+
25988
+ // src/components/UEditor/url-safety.ts
25989
+ var LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
25990
+ var IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
25991
+ function normalizeUrlInput(raw) {
25992
+ return raw.trim().replace(/[\u0000-\u001F\u007F\s]+/g, "");
25993
+ }
25994
+ function isProtocolRelativeUrl(value) {
25995
+ return value.startsWith("//");
25996
+ }
25997
+ function isRelativeUrl(value) {
25998
+ return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#");
25999
+ }
26000
+ function isDataImageUrl(value) {
26001
+ return /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|bmp|x-icon|avif);base64,/i.test(value);
26002
+ }
26003
+ function isSafeUEditorUrl(raw, kind) {
26004
+ const value = normalizeUrlInput(raw);
26005
+ if (!value) return false;
26006
+ if (kind === "image" && isDataImageUrl(value)) return true;
26007
+ if (isRelativeUrl(value)) return true;
26008
+ if (isProtocolRelativeUrl(value)) return false;
26009
+ try {
26010
+ const parsed = new URL(value);
26011
+ return kind === "image" ? IMAGE_PROTOCOLS.has(parsed.protocol) : LINK_PROTOCOLS.has(parsed.protocol);
26012
+ } catch {
26013
+ return false;
26014
+ }
26015
+ }
26016
+ function sanitizeUEditorUrl(raw, kind) {
26017
+ const value = raw.trim();
26018
+ if (!value) return "";
26019
+ if (isSafeUEditorUrl(value, kind)) return normalizeUrlInput(value);
26020
+ if (kind === "link" && !isProtocolRelativeUrl(value) && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
26021
+ const withProtocol = `https://${value}`;
26022
+ return isSafeUEditorUrl(withProtocol, kind) ? withProtocol : "";
26023
+ }
26024
+ return "";
26025
+ }
26026
+
26027
+ // src/components/UEditor/clipboard-images.ts
26028
+ var DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE = 10 * 1024 * 1024;
26029
+ var DEFAULT_UEDITOR_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"];
26030
+ function getImageFiles(dataTransfer) {
26031
+ if (!dataTransfer) return [];
26032
+ const itemFiles = [];
26033
+ const byKey = /* @__PURE__ */ new Map();
26034
+ for (const item of Array.from(dataTransfer.items ?? [])) {
26035
+ if (item.kind !== "file") continue;
26036
+ if (!item.type.startsWith("image/")) continue;
26037
+ const file = item.getAsFile();
26038
+ if (!file) continue;
26039
+ byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
26040
+ }
26041
+ itemFiles.push(...Array.from(byKey.values()));
26042
+ if (itemFiles.length > 0) return itemFiles;
26043
+ for (const file of Array.from(dataTransfer.files ?? [])) {
26044
+ if (!file.type.startsWith("image/")) continue;
26045
+ byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
26046
+ }
26047
+ return Array.from(byKey.values());
26048
+ }
26047
26049
  function fileToDataUrl(file) {
26048
26050
  return new Promise((resolve, reject) => {
26049
26051
  const reader = new FileReader();
@@ -36830,14 +36832,6 @@ var MenuBar = ({
36830
36832
  }
36831
36833
  openPreviewDialog();
36832
36834
  };
36833
- import_react67.default.useEffect(() => {
36834
- if (!showPreviewDialog) return void 0;
36835
- const previousOverflow = document.body.style.overflow;
36836
- document.body.style.overflow = "hidden";
36837
- return () => {
36838
- document.body.style.overflow = previousOverflow;
36839
- };
36840
- }, [showPreviewDialog]);
36841
36835
  const applySourceHtml = () => {
36842
36836
  editor.chain().focus().setContent(sourceHtml).run();
36843
36837
  setShowSourceDialog(false);
@@ -37055,38 +37049,33 @@ var MenuBar = ({
37055
37049
  ] })
37056
37050
  }
37057
37051
  ),
37058
- showPreviewDialog && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "fixed inset-0 z-9999 flex flex-col bg-background text-foreground", children: [
37059
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "flex shrink-0 items-center justify-between border-b border-border bg-card px-4 py-3", children: [
37060
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("h2", { className: "text-base font-semibold", children: t("menubar.preview") }),
37061
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
37062
- "button",
37052
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
37053
+ Modal_default,
37054
+ {
37055
+ isOpen: showPreviewDialog,
37056
+ onClose: () => setShowPreviewDialog(false),
37057
+ title: t("menubar.preview"),
37058
+ size: "full",
37059
+ width: "min(1180px, calc(100vw - 2rem))",
37060
+ height: "min(860px, calc(100vh - 2rem))",
37061
+ className: "flex flex-col overflow-hidden rounded-xl md:rounded-2xl",
37062
+ contentClassName: "flex min-h-0 flex-1 overflow-hidden p-0",
37063
+ children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
37064
+ "div",
37063
37065
  {
37064
- type: "button",
37065
- onClick: () => setShowPreviewDialog(false),
37066
- "aria-label": t("menubar.closeDialog"),
37067
- className: cn(
37068
- "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors",
37069
- "hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
37070
- ),
37071
- children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(import_lucide_react53.X, { className: "h-4 w-4", "aria-hidden": "true" })
37066
+ "data-testid": "preview-content",
37067
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 md:px-8",
37068
+ children: editor.isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
37069
+ "div",
37070
+ {
37071
+ className: UEDITOR_PROSEMIRROR_CLASS_NAME,
37072
+ dangerouslySetInnerHTML: { __html: editor.getHTML() }
37073
+ }
37074
+ )
37072
37075
  }
37073
37076
  )
37074
- ] }),
37075
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
37076
- "div",
37077
- {
37078
- "data-testid": "preview-content",
37079
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 md:px-8",
37080
- children: editor.isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
37081
- "div",
37082
- {
37083
- className: UEDITOR_PROSEMIRROR_CLASS_NAME,
37084
- dangerouslySetInnerHTML: { __html: editor.getHTML() }
37085
- }
37086
- )
37087
- }
37088
- )
37089
- ] })
37077
+ }
37078
+ )
37090
37079
  ] });
37091
37080
  };
37092
37081