@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.
package/dist/index.js CHANGED
@@ -25680,67 +25680,7 @@ var SlashCommand = Extension.create({
25680
25680
  import { Extension as Extension2 } from "@tiptap/core";
25681
25681
  import { Plugin as Plugin2 } from "@tiptap/pm/state";
25682
25682
 
25683
- // src/components/UEditor/url-safety.ts
25684
- var LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
25685
- var IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
25686
- function normalizeUrlInput(raw) {
25687
- return raw.trim().replace(/[\u0000-\u001F\u007F\s]+/g, "");
25688
- }
25689
- function isProtocolRelativeUrl(value) {
25690
- return value.startsWith("//");
25691
- }
25692
- function isRelativeUrl(value) {
25693
- return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#");
25694
- }
25695
- function isDataImageUrl(value) {
25696
- return /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|bmp|x-icon|avif);base64,/i.test(value);
25697
- }
25698
- function isSafeUEditorUrl(raw, kind) {
25699
- const value = normalizeUrlInput(raw);
25700
- if (!value) return false;
25701
- if (kind === "image" && isDataImageUrl(value)) return true;
25702
- if (isRelativeUrl(value)) return true;
25703
- if (isProtocolRelativeUrl(value)) return false;
25704
- try {
25705
- const parsed = new URL(value);
25706
- return kind === "image" ? IMAGE_PROTOCOLS.has(parsed.protocol) : LINK_PROTOCOLS.has(parsed.protocol);
25707
- } catch {
25708
- return false;
25709
- }
25710
- }
25711
- function sanitizeUEditorUrl(raw, kind) {
25712
- const value = raw.trim();
25713
- if (!value) return "";
25714
- if (isSafeUEditorUrl(value, kind)) return normalizeUrlInput(value);
25715
- if (kind === "link" && !isProtocolRelativeUrl(value) && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
25716
- const withProtocol = `https://${value}`;
25717
- return isSafeUEditorUrl(withProtocol, kind) ? withProtocol : "";
25718
- }
25719
- return "";
25720
- }
25721
-
25722
- // src/components/UEditor/clipboard-images.ts
25723
- var DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE = 10 * 1024 * 1024;
25724
- var DEFAULT_UEDITOR_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"];
25725
- function getImageFiles(dataTransfer) {
25726
- if (!dataTransfer) return [];
25727
- const itemFiles = [];
25728
- const byKey = /* @__PURE__ */ new Map();
25729
- for (const item of Array.from(dataTransfer.items ?? [])) {
25730
- if (item.kind !== "file") continue;
25731
- if (!item.type.startsWith("image/")) continue;
25732
- const file = item.getAsFile();
25733
- if (!file) continue;
25734
- byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
25735
- }
25736
- itemFiles.push(...Array.from(byKey.values()));
25737
- if (itemFiles.length > 0) return itemFiles;
25738
- for (const file of Array.from(dataTransfer.files ?? [])) {
25739
- if (!file.type.startsWith("image/")) continue;
25740
- byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
25741
- }
25742
- return Array.from(byKey.values());
25743
- }
25683
+ // src/components/UEditor/clipboard-tables.ts
25744
25684
  function getClipboardData(dataTransfer, type) {
25745
25685
  try {
25746
25686
  return dataTransfer.getData(type) ?? "";
@@ -25889,6 +25829,68 @@ function getClipboardTsvTableContent(dataTransfer) {
25889
25829
  2
25890
25830
  );
25891
25831
  }
25832
+
25833
+ // src/components/UEditor/url-safety.ts
25834
+ var LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
25835
+ var IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
25836
+ function normalizeUrlInput(raw) {
25837
+ return raw.trim().replace(/[\u0000-\u001F\u007F\s]+/g, "");
25838
+ }
25839
+ function isProtocolRelativeUrl(value) {
25840
+ return value.startsWith("//");
25841
+ }
25842
+ function isRelativeUrl(value) {
25843
+ return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#");
25844
+ }
25845
+ function isDataImageUrl(value) {
25846
+ return /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|bmp|x-icon|avif);base64,/i.test(value);
25847
+ }
25848
+ function isSafeUEditorUrl(raw, kind) {
25849
+ const value = normalizeUrlInput(raw);
25850
+ if (!value) return false;
25851
+ if (kind === "image" && isDataImageUrl(value)) return true;
25852
+ if (isRelativeUrl(value)) return true;
25853
+ if (isProtocolRelativeUrl(value)) return false;
25854
+ try {
25855
+ const parsed = new URL(value);
25856
+ return kind === "image" ? IMAGE_PROTOCOLS.has(parsed.protocol) : LINK_PROTOCOLS.has(parsed.protocol);
25857
+ } catch {
25858
+ return false;
25859
+ }
25860
+ }
25861
+ function sanitizeUEditorUrl(raw, kind) {
25862
+ const value = raw.trim();
25863
+ if (!value) return "";
25864
+ if (isSafeUEditorUrl(value, kind)) return normalizeUrlInput(value);
25865
+ if (kind === "link" && !isProtocolRelativeUrl(value) && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
25866
+ const withProtocol = `https://${value}`;
25867
+ return isSafeUEditorUrl(withProtocol, kind) ? withProtocol : "";
25868
+ }
25869
+ return "";
25870
+ }
25871
+
25872
+ // src/components/UEditor/clipboard-images.ts
25873
+ var DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE = 10 * 1024 * 1024;
25874
+ var DEFAULT_UEDITOR_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"];
25875
+ function getImageFiles(dataTransfer) {
25876
+ if (!dataTransfer) return [];
25877
+ const itemFiles = [];
25878
+ const byKey = /* @__PURE__ */ new Map();
25879
+ for (const item of Array.from(dataTransfer.items ?? [])) {
25880
+ if (item.kind !== "file") continue;
25881
+ if (!item.type.startsWith("image/")) continue;
25882
+ const file = item.getAsFile();
25883
+ if (!file) continue;
25884
+ byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
25885
+ }
25886
+ itemFiles.push(...Array.from(byKey.values()));
25887
+ if (itemFiles.length > 0) return itemFiles;
25888
+ for (const file of Array.from(dataTransfer.files ?? [])) {
25889
+ if (!file.type.startsWith("image/")) continue;
25890
+ byKey.set(`${file.name}:${file.size}:${file.lastModified}`, file);
25891
+ }
25892
+ return Array.from(byKey.values());
25893
+ }
25892
25894
  function fileToDataUrl(file) {
25893
25895
  return new Promise((resolve, reject) => {
25894
25896
  const reader = new FileReader();
@@ -36275,8 +36277,7 @@ import {
36275
36277
  Trash2 as Trash25,
36276
36278
  Underline as UnderlineIcon3,
36277
36279
  Undo as UndoIcon2,
36278
- Upload as Upload4,
36279
- X as X19
36280
+ Upload as Upload4
36280
36281
  } from "lucide-react";
36281
36282
  import { Fragment as Fragment35, jsx as jsx92, jsxs as jsxs77 } from "react/jsx-runtime";
36282
36283
  function MenuTableInsertGrid({
@@ -36774,14 +36775,6 @@ var MenuBar = ({
36774
36775
  }
36775
36776
  openPreviewDialog();
36776
36777
  };
36777
- React81.useEffect(() => {
36778
- if (!showPreviewDialog) return void 0;
36779
- const previousOverflow = document.body.style.overflow;
36780
- document.body.style.overflow = "hidden";
36781
- return () => {
36782
- document.body.style.overflow = previousOverflow;
36783
- };
36784
- }, [showPreviewDialog]);
36785
36778
  const applySourceHtml = () => {
36786
36779
  editor.chain().focus().setContent(sourceHtml).run();
36787
36780
  setShowSourceDialog(false);
@@ -36999,38 +36992,33 @@ var MenuBar = ({
36999
36992
  ] })
37000
36993
  }
37001
36994
  ),
37002
- showPreviewDialog && /* @__PURE__ */ jsxs77("div", { className: "fixed inset-0 z-9999 flex flex-col bg-background text-foreground", children: [
37003
- /* @__PURE__ */ jsxs77("div", { className: "flex shrink-0 items-center justify-between border-b border-border bg-card px-4 py-3", children: [
37004
- /* @__PURE__ */ jsx92("h2", { className: "text-base font-semibold", children: t("menubar.preview") }),
37005
- /* @__PURE__ */ jsx92(
37006
- "button",
36995
+ /* @__PURE__ */ jsx92(
36996
+ Modal_default,
36997
+ {
36998
+ isOpen: showPreviewDialog,
36999
+ onClose: () => setShowPreviewDialog(false),
37000
+ title: t("menubar.preview"),
37001
+ size: "full",
37002
+ width: "min(1180px, calc(100vw - 2rem))",
37003
+ height: "min(860px, calc(100vh - 2rem))",
37004
+ className: "flex flex-col overflow-hidden rounded-xl md:rounded-2xl",
37005
+ contentClassName: "flex min-h-0 flex-1 overflow-hidden p-0",
37006
+ children: /* @__PURE__ */ jsx92(
37007
+ "div",
37007
37008
  {
37008
- type: "button",
37009
- onClick: () => setShowPreviewDialog(false),
37010
- "aria-label": t("menubar.closeDialog"),
37011
- className: cn(
37012
- "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors",
37013
- "hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
37014
- ),
37015
- children: /* @__PURE__ */ jsx92(X19, { className: "h-4 w-4", "aria-hidden": "true" })
37009
+ "data-testid": "preview-content",
37010
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 md:px-8",
37011
+ children: editor.isEmpty ? /* @__PURE__ */ jsx92("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx92(
37012
+ "div",
37013
+ {
37014
+ className: UEDITOR_PROSEMIRROR_CLASS_NAME,
37015
+ dangerouslySetInnerHTML: { __html: editor.getHTML() }
37016
+ }
37017
+ )
37016
37018
  }
37017
37019
  )
37018
- ] }),
37019
- /* @__PURE__ */ jsx92(
37020
- "div",
37021
- {
37022
- "data-testid": "preview-content",
37023
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 md:px-8",
37024
- children: editor.isEmpty ? /* @__PURE__ */ jsx92("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx92(
37025
- "div",
37026
- {
37027
- className: UEDITOR_PROSEMIRROR_CLASS_NAME,
37028
- dangerouslySetInnerHTML: { __html: editor.getHTML() }
37029
- }
37030
- )
37031
- }
37032
- )
37033
- ] })
37020
+ }
37021
+ )
37034
37022
  ] });
37035
37023
  };
37036
37024