@underverse-ui/underverse 1.0.99 → 1.0.101
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 +145 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +145 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2955,7 +2955,11 @@ interface UEditorProps {
|
|
|
2955
2955
|
onJsonChange?: (json: object) => void;
|
|
2956
2956
|
uploadImage?: (file: File) => Promise<string> | string;
|
|
2957
2957
|
uploadImageForSave?: UEditorUploadImageForSave;
|
|
2958
|
+
uploadImageConcurrency?: number;
|
|
2958
2959
|
imageInsertMode?: "base64" | "upload";
|
|
2960
|
+
maxImageFileSize?: number;
|
|
2961
|
+
allowedImageMimeTypes?: string[];
|
|
2962
|
+
fallbackToDataUrl?: boolean;
|
|
2959
2963
|
placeholder?: string;
|
|
2960
2964
|
className?: string;
|
|
2961
2965
|
editable?: boolean;
|
|
@@ -2983,9 +2987,10 @@ declare class UEditorPrepareContentForSaveError extends Error {
|
|
|
2983
2987
|
readonly result: UEditorPrepareContentForSaveResult;
|
|
2984
2988
|
constructor(result: UEditorPrepareContentForSaveResult);
|
|
2985
2989
|
}
|
|
2986
|
-
declare function prepareUEditorContentForSave({ html, uploadImageForSave, }: {
|
|
2990
|
+
declare function prepareUEditorContentForSave({ html, uploadImageForSave, uploadConcurrency, }: {
|
|
2987
2991
|
html: string;
|
|
2988
2992
|
uploadImageForSave?: UEditorUploadImageForSave;
|
|
2993
|
+
uploadConcurrency?: number;
|
|
2989
2994
|
}): Promise<UEditorPrepareContentForSaveResult>;
|
|
2990
2995
|
|
|
2991
2996
|
/** Button component for actions, icon buttons, loading states, and submit flows. */
|
package/dist/index.d.ts
CHANGED
|
@@ -2955,7 +2955,11 @@ interface UEditorProps {
|
|
|
2955
2955
|
onJsonChange?: (json: object) => void;
|
|
2956
2956
|
uploadImage?: (file: File) => Promise<string> | string;
|
|
2957
2957
|
uploadImageForSave?: UEditorUploadImageForSave;
|
|
2958
|
+
uploadImageConcurrency?: number;
|
|
2958
2959
|
imageInsertMode?: "base64" | "upload";
|
|
2960
|
+
maxImageFileSize?: number;
|
|
2961
|
+
allowedImageMimeTypes?: string[];
|
|
2962
|
+
fallbackToDataUrl?: boolean;
|
|
2959
2963
|
placeholder?: string;
|
|
2960
2964
|
className?: string;
|
|
2961
2965
|
editable?: boolean;
|
|
@@ -2983,9 +2987,10 @@ declare class UEditorPrepareContentForSaveError extends Error {
|
|
|
2983
2987
|
readonly result: UEditorPrepareContentForSaveResult;
|
|
2984
2988
|
constructor(result: UEditorPrepareContentForSaveResult);
|
|
2985
2989
|
}
|
|
2986
|
-
declare function prepareUEditorContentForSave({ html, uploadImageForSave, }: {
|
|
2990
|
+
declare function prepareUEditorContentForSave({ html, uploadImageForSave, uploadConcurrency, }: {
|
|
2987
2991
|
html: string;
|
|
2988
2992
|
uploadImageForSave?: UEditorUploadImageForSave;
|
|
2993
|
+
uploadConcurrency?: number;
|
|
2989
2994
|
}): Promise<UEditorPrepareContentForSaveResult>;
|
|
2990
2995
|
|
|
2991
2996
|
/** Button component for actions, icon buttons, loading states, and submit flows. */
|
package/dist/index.js
CHANGED
|
@@ -22675,7 +22675,7 @@ var useFormField = () => {
|
|
|
22675
22675
|
var FormItemContext = React63.createContext({});
|
|
22676
22676
|
var FormItem = React63.forwardRef(({ className, ...props }, ref) => {
|
|
22677
22677
|
const id = React63.useId();
|
|
22678
|
-
return /* @__PURE__ */ jsx68(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx68("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
22678
|
+
return /* @__PURE__ */ jsx68(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx68("div", { ref, className: cn("group space-y-2", className), ...props }) });
|
|
22679
22679
|
});
|
|
22680
22680
|
FormItem.displayName = "FormItem";
|
|
22681
22681
|
var FormLabel = React63.forwardRef(
|
|
@@ -22683,10 +22683,24 @@ var FormLabel = React63.forwardRef(
|
|
|
22683
22683
|
const { error, formItemId } = useFormField();
|
|
22684
22684
|
const config = React63.useContext(FormConfigContext);
|
|
22685
22685
|
const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
|
|
22686
|
-
return /* @__PURE__ */ jsxs57(
|
|
22687
|
-
|
|
22688
|
-
|
|
22689
|
-
|
|
22686
|
+
return /* @__PURE__ */ jsxs57(
|
|
22687
|
+
Label,
|
|
22688
|
+
{
|
|
22689
|
+
ref,
|
|
22690
|
+
className: cn(
|
|
22691
|
+
sizeClass,
|
|
22692
|
+
"transition-colors duration-200",
|
|
22693
|
+
error ? "text-destructive" : "group-focus-within:text-primary",
|
|
22694
|
+
className
|
|
22695
|
+
),
|
|
22696
|
+
htmlFor: formItemId,
|
|
22697
|
+
...props,
|
|
22698
|
+
children: [
|
|
22699
|
+
children,
|
|
22700
|
+
required && /* @__PURE__ */ jsx68("span", { className: "text-destructive ml-1", children: "*" })
|
|
22701
|
+
]
|
|
22702
|
+
}
|
|
22703
|
+
);
|
|
22690
22704
|
}
|
|
22691
22705
|
);
|
|
22692
22706
|
FormLabel.displayName = "FormLabel";
|
|
@@ -23482,6 +23496,49 @@ var SlashCommand = Extension.create({
|
|
|
23482
23496
|
// src/components/UEditor/clipboard-images.ts
|
|
23483
23497
|
import { Extension as Extension2 } from "@tiptap/core";
|
|
23484
23498
|
import { Plugin } from "@tiptap/pm/state";
|
|
23499
|
+
|
|
23500
|
+
// src/components/UEditor/url-safety.ts
|
|
23501
|
+
var LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
|
|
23502
|
+
var IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
23503
|
+
function normalizeUrlInput(raw) {
|
|
23504
|
+
return raw.trim().replace(/[\u0000-\u001F\u007F\s]+/g, "");
|
|
23505
|
+
}
|
|
23506
|
+
function isProtocolRelativeUrl(value) {
|
|
23507
|
+
return value.startsWith("//");
|
|
23508
|
+
}
|
|
23509
|
+
function isRelativeUrl(value) {
|
|
23510
|
+
return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#");
|
|
23511
|
+
}
|
|
23512
|
+
function isDataImageUrl(value) {
|
|
23513
|
+
return /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|bmp|x-icon|avif);base64,/i.test(value);
|
|
23514
|
+
}
|
|
23515
|
+
function isSafeUEditorUrl(raw, kind) {
|
|
23516
|
+
const value = normalizeUrlInput(raw);
|
|
23517
|
+
if (!value) return false;
|
|
23518
|
+
if (kind === "image" && isDataImageUrl(value)) return true;
|
|
23519
|
+
if (isRelativeUrl(value)) return true;
|
|
23520
|
+
if (isProtocolRelativeUrl(value)) return false;
|
|
23521
|
+
try {
|
|
23522
|
+
const parsed = new URL(value);
|
|
23523
|
+
return kind === "image" ? IMAGE_PROTOCOLS.has(parsed.protocol) : LINK_PROTOCOLS.has(parsed.protocol);
|
|
23524
|
+
} catch {
|
|
23525
|
+
return false;
|
|
23526
|
+
}
|
|
23527
|
+
}
|
|
23528
|
+
function sanitizeUEditorUrl(raw, kind) {
|
|
23529
|
+
const value = raw.trim();
|
|
23530
|
+
if (!value) return "";
|
|
23531
|
+
if (isSafeUEditorUrl(value, kind)) return normalizeUrlInput(value);
|
|
23532
|
+
if (kind === "link" && !isProtocolRelativeUrl(value) && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
|
|
23533
|
+
const withProtocol = `https://${value}`;
|
|
23534
|
+
return isSafeUEditorUrl(withProtocol, kind) ? withProtocol : "";
|
|
23535
|
+
}
|
|
23536
|
+
return "";
|
|
23537
|
+
}
|
|
23538
|
+
|
|
23539
|
+
// src/components/UEditor/clipboard-images.ts
|
|
23540
|
+
var DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
23541
|
+
var DEFAULT_UEDITOR_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"];
|
|
23485
23542
|
function getImageFiles(dataTransfer) {
|
|
23486
23543
|
if (!dataTransfer) return [];
|
|
23487
23544
|
const itemFiles = [];
|
|
@@ -23513,7 +23570,7 @@ async function resolveImageSrc(file, options) {
|
|
|
23513
23570
|
if (options.insertMode === "upload" && options.upload) {
|
|
23514
23571
|
try {
|
|
23515
23572
|
const result = await options.upload(file);
|
|
23516
|
-
const src = typeof result === "string" ? result : "";
|
|
23573
|
+
const src = typeof result === "string" ? sanitizeUEditorUrl(result, "image") : "";
|
|
23517
23574
|
if (src) return src;
|
|
23518
23575
|
} catch (err) {
|
|
23519
23576
|
if (!options.fallbackToDataUrl) throw err;
|
|
@@ -23525,8 +23582,8 @@ var ClipboardImages = Extension2.create({
|
|
|
23525
23582
|
name: "clipboardImages",
|
|
23526
23583
|
addOptions() {
|
|
23527
23584
|
return {
|
|
23528
|
-
maxFileSize:
|
|
23529
|
-
allowedMimeTypes:
|
|
23585
|
+
maxFileSize: DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE,
|
|
23586
|
+
allowedMimeTypes: DEFAULT_UEDITOR_IMAGE_MIME_TYPES,
|
|
23530
23587
|
upload: void 0,
|
|
23531
23588
|
fallbackToDataUrl: true,
|
|
23532
23589
|
insertMode: "base64"
|
|
@@ -24385,6 +24442,9 @@ function buildUEditorExtensions({
|
|
|
24385
24442
|
maxCharacters,
|
|
24386
24443
|
uploadImage,
|
|
24387
24444
|
imageInsertMode = "base64",
|
|
24445
|
+
maxImageFileSize,
|
|
24446
|
+
allowedImageMimeTypes,
|
|
24447
|
+
fallbackToDataUrl,
|
|
24388
24448
|
editable = true
|
|
24389
24449
|
}) {
|
|
24390
24450
|
return [
|
|
@@ -24438,12 +24498,20 @@ function buildUEditorExtensions({
|
|
|
24438
24498
|
HorizontalRule,
|
|
24439
24499
|
Link.configure({
|
|
24440
24500
|
openOnClick: false,
|
|
24501
|
+
protocols: ["http", "https", "mailto", "tel"],
|
|
24502
|
+
isAllowedUri: (url) => isSafeUEditorUrl(url ?? "", "link"),
|
|
24441
24503
|
HTMLAttributes: {
|
|
24442
24504
|
class: "text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer"
|
|
24443
24505
|
}
|
|
24444
24506
|
}),
|
|
24445
24507
|
resizable_image_default,
|
|
24446
|
-
ClipboardImages.configure({
|
|
24508
|
+
ClipboardImages.configure({
|
|
24509
|
+
upload: uploadImage,
|
|
24510
|
+
insertMode: imageInsertMode,
|
|
24511
|
+
...maxImageFileSize !== void 0 ? { maxFileSize: maxImageFileSize } : {},
|
|
24512
|
+
...allowedImageMimeTypes ? { allowedMimeTypes: allowedImageMimeTypes } : {},
|
|
24513
|
+
...fallbackToDataUrl !== void 0 ? { fallbackToDataUrl } : {}
|
|
24514
|
+
}),
|
|
24447
24515
|
TextStyle,
|
|
24448
24516
|
font_family_default,
|
|
24449
24517
|
font_size_default,
|
|
@@ -24699,11 +24767,7 @@ import { useEffect as useEffect33, useRef as useRef28, useState as useState43 }
|
|
|
24699
24767
|
import { Check as Check10, X as X19 } from "lucide-react";
|
|
24700
24768
|
import { jsx as jsx78, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
24701
24769
|
function normalizeUrl(raw) {
|
|
24702
|
-
|
|
24703
|
-
if (!url) return "";
|
|
24704
|
-
if (url.startsWith("#") || url.startsWith("/")) return url;
|
|
24705
|
-
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url)) return url;
|
|
24706
|
-
return `https://${url}`;
|
|
24770
|
+
return sanitizeUEditorUrl(raw, "link");
|
|
24707
24771
|
}
|
|
24708
24772
|
var LinkInput = ({
|
|
24709
24773
|
onSubmit,
|
|
@@ -24748,8 +24812,9 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
24748
24812
|
}, []);
|
|
24749
24813
|
const handleSubmit = (e) => {
|
|
24750
24814
|
e.preventDefault();
|
|
24751
|
-
|
|
24752
|
-
|
|
24815
|
+
const safeUrl = sanitizeUEditorUrl(url, "image");
|
|
24816
|
+
if (safeUrl) {
|
|
24817
|
+
onSubmit(safeUrl, alt);
|
|
24753
24818
|
}
|
|
24754
24819
|
};
|
|
24755
24820
|
return /* @__PURE__ */ jsxs66("form", { onSubmit: handleSubmit, className: "p-3 space-y-3", children: [
|
|
@@ -24935,6 +25000,8 @@ var EditorToolbar = ({
|
|
|
24935
25000
|
variant,
|
|
24936
25001
|
uploadImage,
|
|
24937
25002
|
imageInsertMode = "base64",
|
|
25003
|
+
maxImageFileSize = DEFAULT_UEDITOR_IMAGE_MAX_FILE_SIZE,
|
|
25004
|
+
allowedImageMimeTypes = DEFAULT_UEDITOR_IMAGE_MIME_TYPES,
|
|
24938
25005
|
fontFamilies,
|
|
24939
25006
|
fontSizes,
|
|
24940
25007
|
lineHeights,
|
|
@@ -25002,10 +25069,13 @@ var EditorToolbar = ({
|
|
|
25002
25069
|
setImageUploadError(null);
|
|
25003
25070
|
for (const file of files) {
|
|
25004
25071
|
if (!file.type.startsWith("image/")) continue;
|
|
25072
|
+
if (file.size > maxImageFileSize) continue;
|
|
25073
|
+
if (allowedImageMimeTypes.length > 0 && !allowedImageMimeTypes.includes(file.type)) continue;
|
|
25005
25074
|
try {
|
|
25006
25075
|
const src = imageInsertMode === "upload" && uploadImage ? await uploadImage(file) : await fileToDataUrl2(file);
|
|
25007
|
-
|
|
25008
|
-
|
|
25076
|
+
const safeSrc = sanitizeUEditorUrl(src, "image");
|
|
25077
|
+
if (!safeSrc) continue;
|
|
25078
|
+
editor.chain().focus().setImage({ src: safeSrc, alt: file.name }).run();
|
|
25009
25079
|
editor.commands.createParagraphNear();
|
|
25010
25080
|
} catch {
|
|
25011
25081
|
setImageUploadError(t("imageInput.uploadError"));
|
|
@@ -26216,12 +26286,12 @@ var MIME_EXTENSION_MAP = {
|
|
|
26216
26286
|
"image/x-icon": "ico",
|
|
26217
26287
|
"image/avif": "avif"
|
|
26218
26288
|
};
|
|
26219
|
-
function
|
|
26289
|
+
function isDataImageUrl2(value) {
|
|
26220
26290
|
return /^data:image\//i.test(value.trim());
|
|
26221
26291
|
}
|
|
26222
26292
|
function parseDataImageUrl(dataUrl) {
|
|
26223
26293
|
const value = dataUrl.trim();
|
|
26224
|
-
if (!
|
|
26294
|
+
if (!isDataImageUrl2(value)) return null;
|
|
26225
26295
|
const commaIndex = value.indexOf(",");
|
|
26226
26296
|
if (commaIndex < 0) return null;
|
|
26227
26297
|
const header = value.slice(5, commaIndex);
|
|
@@ -26255,19 +26325,33 @@ function createFileFromDataImageUrl(dataUrl, index) {
|
|
|
26255
26325
|
}
|
|
26256
26326
|
function normalizeUploadResult(result) {
|
|
26257
26327
|
if (typeof result === "string") {
|
|
26258
|
-
const url2 = result
|
|
26328
|
+
const url2 = sanitizeUEditorUrl(result, "image");
|
|
26259
26329
|
if (!url2) throw new Error("Upload handler returned an empty URL.");
|
|
26260
26330
|
return { url: url2 };
|
|
26261
26331
|
}
|
|
26262
26332
|
if (!result || typeof result !== "object") {
|
|
26263
26333
|
throw new Error("Upload handler returned invalid result.");
|
|
26264
26334
|
}
|
|
26265
|
-
const url = typeof result.url === "string" ? result.url
|
|
26335
|
+
const url = typeof result.url === "string" ? sanitizeUEditorUrl(result.url, "image") : "";
|
|
26266
26336
|
if (!url) throw new Error("Upload handler object result is missing `url`.");
|
|
26267
26337
|
const { url: _ignoredUrl, ...rest } = result;
|
|
26268
26338
|
const meta = Object.keys(rest).length > 0 ? rest : void 0;
|
|
26269
26339
|
return { url, meta };
|
|
26270
26340
|
}
|
|
26341
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
26342
|
+
const limit = Math.max(1, Math.floor(concurrency));
|
|
26343
|
+
const results = new Array(items.length);
|
|
26344
|
+
let nextIndex = 0;
|
|
26345
|
+
async function runNext() {
|
|
26346
|
+
while (nextIndex < items.length) {
|
|
26347
|
+
const currentIndex = nextIndex;
|
|
26348
|
+
nextIndex += 1;
|
|
26349
|
+
results[currentIndex] = await worker(items[currentIndex]);
|
|
26350
|
+
}
|
|
26351
|
+
}
|
|
26352
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, runNext));
|
|
26353
|
+
return results;
|
|
26354
|
+
}
|
|
26271
26355
|
function getErrorReason(error) {
|
|
26272
26356
|
if (error instanceof Error && error.message) return error.message;
|
|
26273
26357
|
if (typeof error === "string" && error.trim()) return error;
|
|
@@ -26279,7 +26363,7 @@ function decodeHtmlEntities(value) {
|
|
|
26279
26363
|
function normalizeImageUrl(url) {
|
|
26280
26364
|
const input = decodeHtmlEntities(url.trim());
|
|
26281
26365
|
if (!input) return "";
|
|
26282
|
-
if (
|
|
26366
|
+
if (isDataImageUrl2(input)) return input;
|
|
26283
26367
|
const isAbsolute = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(input);
|
|
26284
26368
|
if (!isAbsolute) {
|
|
26285
26369
|
return input.split("#")[0] ?? input;
|
|
@@ -26363,7 +26447,8 @@ var UEditorPrepareContentForSaveError = class extends Error {
|
|
|
26363
26447
|
};
|
|
26364
26448
|
async function prepareUEditorContentForSave({
|
|
26365
26449
|
html,
|
|
26366
|
-
uploadImageForSave
|
|
26450
|
+
uploadImageForSave,
|
|
26451
|
+
uploadConcurrency = 3
|
|
26367
26452
|
}) {
|
|
26368
26453
|
if (!html || !html.includes("<img")) {
|
|
26369
26454
|
return createResult({ html, uploaded: [], inlineUploaded: [], errors: [] });
|
|
@@ -26376,7 +26461,7 @@ async function prepareUEditorContentForSave({
|
|
|
26376
26461
|
for (const match of imgMatches) {
|
|
26377
26462
|
if (!match.srcAttr) continue;
|
|
26378
26463
|
const src = match.srcAttr.value.trim();
|
|
26379
|
-
if (!
|
|
26464
|
+
if (!isDataImageUrl2(src)) continue;
|
|
26380
26465
|
base64Candidates.push({
|
|
26381
26466
|
id: `${match.start}:${match.end}`,
|
|
26382
26467
|
match,
|
|
@@ -26402,8 +26487,10 @@ async function prepareUEditorContentForSave({
|
|
|
26402
26487
|
const inlineUploaded = [];
|
|
26403
26488
|
const errors = [];
|
|
26404
26489
|
const replacements = /* @__PURE__ */ new Map();
|
|
26405
|
-
const uploadResults = await
|
|
26406
|
-
base64Candidates
|
|
26490
|
+
const uploadResults = await runWithConcurrency(
|
|
26491
|
+
base64Candidates,
|
|
26492
|
+
uploadConcurrency,
|
|
26493
|
+
async (candidate) => {
|
|
26407
26494
|
try {
|
|
26408
26495
|
const file = createFileFromDataImageUrl(candidate.src, candidate.index);
|
|
26409
26496
|
const uploadResult = await uploadImageForSave(file);
|
|
@@ -26412,7 +26499,7 @@ async function prepareUEditorContentForSave({
|
|
|
26412
26499
|
} catch (error) {
|
|
26413
26500
|
return { candidate, error: getErrorReason(error) };
|
|
26414
26501
|
}
|
|
26415
|
-
}
|
|
26502
|
+
}
|
|
26416
26503
|
);
|
|
26417
26504
|
for (const item of uploadResults) {
|
|
26418
26505
|
if ("error" in item) {
|
|
@@ -31750,7 +31837,11 @@ var UEditor = React74.forwardRef(({
|
|
|
31750
31837
|
onJsonChange,
|
|
31751
31838
|
uploadImage,
|
|
31752
31839
|
uploadImageForSave,
|
|
31840
|
+
uploadImageConcurrency = 3,
|
|
31753
31841
|
imageInsertMode = "base64",
|
|
31842
|
+
maxImageFileSize,
|
|
31843
|
+
allowedImageMimeTypes,
|
|
31844
|
+
fallbackToDataUrl,
|
|
31754
31845
|
placeholder,
|
|
31755
31846
|
className,
|
|
31756
31847
|
editable = true,
|
|
@@ -31861,8 +31952,18 @@ var UEditor = React74.forwardRef(({
|
|
|
31861
31952
|
setEditorResizeCursor("row-resize");
|
|
31862
31953
|
}, [setEditorResizeCursor]);
|
|
31863
31954
|
const extensions = useMemo24(
|
|
31864
|
-
() => buildUEditorExtensions({
|
|
31865
|
-
|
|
31955
|
+
() => buildUEditorExtensions({
|
|
31956
|
+
placeholder: effectivePlaceholder,
|
|
31957
|
+
translate: t,
|
|
31958
|
+
maxCharacters,
|
|
31959
|
+
uploadImage,
|
|
31960
|
+
imageInsertMode,
|
|
31961
|
+
maxImageFileSize,
|
|
31962
|
+
allowedImageMimeTypes,
|
|
31963
|
+
fallbackToDataUrl,
|
|
31964
|
+
editable
|
|
31965
|
+
}),
|
|
31966
|
+
[effectivePlaceholder, t, maxCharacters, uploadImage, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable]
|
|
31866
31967
|
);
|
|
31867
31968
|
const editor = useEditor({
|
|
31868
31969
|
immediatelyRender: false,
|
|
@@ -32059,7 +32160,8 @@ var UEditor = React74.forwardRef(({
|
|
|
32059
32160
|
const htmlSnapshot = editor?.getHTML() ?? content ?? "";
|
|
32060
32161
|
inFlightPrepareRef.current = prepareUEditorContentForSave({
|
|
32061
32162
|
html: htmlSnapshot,
|
|
32062
|
-
uploadImageForSave
|
|
32163
|
+
uploadImageForSave,
|
|
32164
|
+
uploadConcurrency: uploadImageConcurrency
|
|
32063
32165
|
}).finally(() => {
|
|
32064
32166
|
inFlightPrepareRef.current = null;
|
|
32065
32167
|
});
|
|
@@ -32071,7 +32173,7 @@ var UEditor = React74.forwardRef(({
|
|
|
32071
32173
|
return result;
|
|
32072
32174
|
}
|
|
32073
32175
|
}),
|
|
32074
|
-
[content, editor, uploadImageForSave]
|
|
32176
|
+
[content, editor, uploadImageForSave, uploadImageConcurrency]
|
|
32075
32177
|
);
|
|
32076
32178
|
useEffect35(() => {
|
|
32077
32179
|
if (!editor) return;
|
|
@@ -32201,21 +32303,6 @@ var UEditor = React74.forwardRef(({
|
|
|
32201
32303
|
}
|
|
32202
32304
|
state.previewHeight = nextHeight;
|
|
32203
32305
|
applyPreviewRowHeight(state.rowElement, nextHeight);
|
|
32204
|
-
const tr = editor.view.state.tr;
|
|
32205
|
-
tr.setNodeMarkup(state.rowPos, void 0, {
|
|
32206
|
-
...state.rowNode.attrs,
|
|
32207
|
-
rowHeight: nextHeight
|
|
32208
|
-
});
|
|
32209
|
-
editor.view.dispatch(tr);
|
|
32210
|
-
state.rowNode = editor.view.state.doc.nodeAt(state.rowPos) ?? state.rowNode;
|
|
32211
|
-
const refreshedRow = state.tableElement.rows.item(state.rowElement.rowIndex);
|
|
32212
|
-
if (refreshedRow instanceof HTMLTableRowElement) {
|
|
32213
|
-
state.rowElement = refreshedRow;
|
|
32214
|
-
const refreshedCell = refreshedRow.cells.item(state.cellIndex);
|
|
32215
|
-
if (refreshedCell instanceof HTMLTableCellElement) {
|
|
32216
|
-
state.cellElement = refreshedCell;
|
|
32217
|
-
}
|
|
32218
|
-
}
|
|
32219
32306
|
document.body.style.cursor = "row-resize";
|
|
32220
32307
|
showRowGuide(state.tableElement, state.rowElement, state.cellElement);
|
|
32221
32308
|
};
|
|
@@ -32226,7 +32313,16 @@ var UEditor = React74.forwardRef(({
|
|
|
32226
32313
|
MIN_TABLE_ROW_HEIGHT,
|
|
32227
32314
|
Math.round(state.startHeight + (event.clientY - state.startY))
|
|
32228
32315
|
);
|
|
32316
|
+
const rowNode = editor.view.state.doc.nodeAt(state.rowPos) ?? state.rowNode;
|
|
32229
32317
|
clearPreviewRowHeight(state.rowElement);
|
|
32318
|
+
if (rowNode.attrs.rowHeight !== nextHeight) {
|
|
32319
|
+
const tr = editor.view.state.tr;
|
|
32320
|
+
tr.setNodeMarkup(state.rowPos, void 0, {
|
|
32321
|
+
...rowNode.attrs,
|
|
32322
|
+
rowHeight: nextHeight
|
|
32323
|
+
});
|
|
32324
|
+
editor.view.dispatch(tr);
|
|
32325
|
+
}
|
|
32230
32326
|
rowResizeStateRef.current = null;
|
|
32231
32327
|
document.body.style.cursor = "";
|
|
32232
32328
|
clearHoveredTableCell();
|
|
@@ -32314,6 +32410,8 @@ var UEditor = React74.forwardRef(({
|
|
|
32314
32410
|
variant,
|
|
32315
32411
|
uploadImage,
|
|
32316
32412
|
imageInsertMode,
|
|
32413
|
+
maxImageFileSize,
|
|
32414
|
+
allowedImageMimeTypes,
|
|
32317
32415
|
fontFamilies,
|
|
32318
32416
|
fontSizes,
|
|
32319
32417
|
lineHeights,
|