superdoc 2.18.1-next.5 → 2.19.0-next.2
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/chunks/{create-super-doc-ui-C3HDE1IE.es.js → create-super-doc-ui-BFJ9Y0YV.cjs} +1396 -1
- package/dist/chunks/{create-super-doc-ui-Gxk1m05U.cjs → create-super-doc-ui-Dfw1b6h_.es.js} +1318 -66
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +9 -0
- package/dist/document-api/src/index.d.ts +1 -0
- package/dist/document-api/src/types/track-changes.types.d.ts +35 -2
- package/dist/document-api/src/validation-primitives.d.ts +1 -1
- package/dist/document-api/src/watermarks/watermarks.d.ts +4 -1
- package/dist/document-api/src/watermarks/watermarks.types.d.ts +34 -0
- package/dist/layout-engine/painters/dom/src/index.d.ts +2 -0
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui-vue.cjs +1 -1
- package/dist/public/ui-vue.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +596 -80
- package/dist/style.layered.css +597 -81
- package/dist/superdoc/src/components/surfaces/WatermarkSurface.vue.d.ts +16 -0
- package/dist/superdoc/src/components/surfaces/watermark-surface-runtime.d.ts +8 -0
- package/dist/superdoc/src/core/SuperDoc.d.ts +8 -7
- package/dist/superdoc/src/core/types/index.d.ts +36 -18
- package/dist/superdoc/src/internal/toolbar/built-in/OverflowMenu.vue.d.ts +93 -1
- package/dist/superdoc/src/internal/toolbar/built-in/Toolbar.vue.d.ts +3 -1
- package/dist/superdoc/src/internal/toolbar/built-in/ToolbarDropdown.vue.d.ts +1 -0
- package/dist/superdoc/src/internal/toolbar/built-in/toolbarIcons.d.ts +1 -0
- package/dist/superdoc/src/internal/toolbar/built-in/toolbarTexts.d.ts +1 -0
- package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +3 -0
- package/dist/superdoc/src/public/ui/types.d.ts +10 -1
- package/dist/superdoc/src/public/ui/watermark-controller.d.ts +32 -0
- package/dist/superdoc/src/public/ui/watermark-dialog-state.d.ts +66 -0
- package/dist/superdoc/src/public/ui/watermark-draft.d.ts +6 -0
- package/dist/superdoc/src/public/ui.d.cts +12 -0
- package/dist/superdoc/src/public/ui.d.ts +1 -1
- package/dist/superdoc.cjs +110 -174
- package/dist/superdoc.es.js +108 -172
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +38 -37
- package/package.json +2 -2
package/dist/superdoc.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("./chunks/rolldown-runtime-74VwNCz7.cjs");
|
|
3
3
|
const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
|
|
4
|
-
const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-
|
|
4
|
+
const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-BFJ9Y0YV.cjs");
|
|
5
5
|
const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
|
|
6
6
|
const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
|
|
7
7
|
const require_jszip = require("./chunks/jszip-D8mAFF-r.cjs");
|
|
@@ -316,7 +316,7 @@ var shuffleArray = (array) => {
|
|
|
316
316
|
var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
|
|
317
317
|
function getSuperdocVersion() {
|
|
318
318
|
try {
|
|
319
|
-
return "2.
|
|
319
|
+
return "2.19.0-next.2";
|
|
320
320
|
} catch {
|
|
321
321
|
return "unknown";
|
|
322
322
|
}
|
|
@@ -5456,13 +5456,13 @@ function resolveProviderExtension(candidate) {
|
|
|
5456
5456
|
if (!adapterId) return {
|
|
5457
5457
|
ok: false,
|
|
5458
5458
|
reason: "invalid-adapter-id",
|
|
5459
|
-
message: "SuperDoc v2 provider extensions require a non-empty
|
|
5459
|
+
message: "SuperDoc v2 provider extensions require a non-empty collaboration.adapterId."
|
|
5460
5460
|
};
|
|
5461
5461
|
const documentId = normalizeNonEmptyString(candidate.documentId);
|
|
5462
5462
|
if (!documentId) return {
|
|
5463
5463
|
ok: false,
|
|
5464
5464
|
reason: "invalid-document-id",
|
|
5465
|
-
message: "SuperDoc v2 provider extensions require a non-empty
|
|
5465
|
+
message: "SuperDoc v2 provider extensions require a non-empty collaboration.documentId."
|
|
5466
5466
|
};
|
|
5467
5467
|
const roomMode = normalizeRoomMode(candidate.roomMode);
|
|
5468
5468
|
if (!roomMode) return invalidRoomMode();
|
|
@@ -18727,6 +18727,7 @@ var toolbarIcons = {
|
|
|
18727
18727
|
link: link_solid_default,
|
|
18728
18728
|
image: image_solid_default,
|
|
18729
18729
|
tableOfContents: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"96 96 448 448\"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M96 160C96 124.7 124.7 96 160 96L480 96C515.3 96 544 124.7 544 160L544 480C544 515.3 515.3 544 480 544L160 544C124.7 544 96 515.3 96 480L96 160zM160 160L160 224L224 224L224 160L160 160zM480 160L288 160L288 224L480 224L480 160zM160 288L160 352L224 352L224 288L160 288zM480 288L288 288L288 352L480 352L480 288zM160 416L160 480L224 480L224 416L160 416zM480 416L288 416L288 480L480 480L480 416z\"></path></svg>\n",
|
|
18730
|
+
watermark: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"16\" viewBox=\"0 0 384 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 288c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM109.2 254.3L150.8 230.3L312.1 349.7L267.0 375.7L236.9 351.5L169.4 390.5L175.2 428.7L130.2 454.7ZM162.6 344.8L200.7 322.8L153.6 285.3Z\"/></svg>\n",
|
|
18730
18731
|
alignLeft: align_left_solid_default,
|
|
18731
18732
|
alignRight: align_right_solid_default,
|
|
18732
18733
|
alignCenter: align_center_solid_default,
|
|
@@ -21458,7 +21459,9 @@ var _sfc_main$23 = {
|
|
|
21458
21459
|
}
|
|
21459
21460
|
}
|
|
21460
21461
|
function handleBackdropClick(event) {
|
|
21461
|
-
if (event.target
|
|
21462
|
+
if (event.target !== event.currentTarget) return;
|
|
21463
|
+
event.preventDefault();
|
|
21464
|
+
if (props.surface.request.closeOnBackdrop !== false) emit("close");
|
|
21462
21465
|
}
|
|
21463
21466
|
const shellProps = (0, vue.computed)(() => ({
|
|
21464
21467
|
surfaceId: props.surface.id,
|
|
@@ -21535,7 +21538,7 @@ var _sfc_main$23 = {
|
|
|
21535
21538
|
};
|
|
21536
21539
|
}
|
|
21537
21540
|
};
|
|
21538
|
-
var SurfaceDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$23, [["__scopeId", "data-v-
|
|
21541
|
+
var SurfaceDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$23, [["__scopeId", "data-v-582b6534"]]);
|
|
21539
21542
|
//#endregion
|
|
21540
21543
|
//#region src/components/surfaces/SurfaceFloating.vue
|
|
21541
21544
|
var _hoisted_1$17 = ["aria-labelledby", "aria-label"];
|
|
@@ -21706,10 +21709,9 @@ var _sfc_main$21 = {
|
|
|
21706
21709
|
* Reads the SurfaceManager's reactive state (activeDialog / activeFloating)
|
|
21707
21710
|
* and renders the appropriate surface shell for each slot.
|
|
21708
21711
|
*
|
|
21709
|
-
*
|
|
21710
|
-
* of
|
|
21711
|
-
*
|
|
21712
|
-
* area regardless of document scroll position.
|
|
21712
|
+
* Floating surfaces are clipped to the visible document viewport. Modal
|
|
21713
|
+
* dialogs are siblings of that clipped host so their backdrop covers the
|
|
21714
|
+
* browser viewport, including toolbars and surrounding application content.
|
|
21713
21715
|
*
|
|
21714
21716
|
* Floating Escape and outside-pointer-down handling live here (document-level)
|
|
21715
21717
|
* because floating surfaces are non-modal — focus can be anywhere in the
|
|
@@ -21907,16 +21909,16 @@ var _sfc_main$21 = {
|
|
|
21907
21909
|
surface: floating.value,
|
|
21908
21910
|
ref_key: "floatingRef",
|
|
21909
21911
|
ref: floatingRef
|
|
21910
|
-
}, null, 8, ["surface"])) : (0, vue.createCommentVNode)("", true), dialog.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(SurfaceDialog_default, {
|
|
21912
|
+
}, null, 8, ["surface"])) : (0, vue.createCommentVNode)("", true)], 4)) : (0, vue.createCommentVNode)("", true), dialog.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(SurfaceDialog_default, {
|
|
21911
21913
|
key: dialog.value.id,
|
|
21912
21914
|
surface: dialog.value,
|
|
21913
21915
|
"scroll-lock-target": (0, vue.unref)(geometryTarget),
|
|
21914
21916
|
onClose: handleDialogClose
|
|
21915
|
-
}, null, 8, ["surface", "scroll-lock-target"])) : (0, vue.createCommentVNode)("", true)]
|
|
21917
|
+
}, null, 8, ["surface", "scroll-lock-target"])) : (0, vue.createCommentVNode)("", true)]);
|
|
21916
21918
|
};
|
|
21917
21919
|
}
|
|
21918
21920
|
};
|
|
21919
|
-
var SurfaceHost_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$21, [["__scopeId", "data-v-
|
|
21921
|
+
var SurfaceHost_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$21, [["__scopeId", "data-v-dad99b67"]]);
|
|
21920
21922
|
//#endregion
|
|
21921
21923
|
//#region src/SuperDoc.vue
|
|
21922
21924
|
var _hoisted_1$16 = ["innerHTML"];
|
|
@@ -38209,6 +38211,7 @@ function addCustomItemRegions(regions, customItems) {
|
|
|
38209
38211
|
return result;
|
|
38210
38212
|
}
|
|
38211
38213
|
var TOOLBAR_OPTIONAL_ITEM_REGIONS = Object.freeze({
|
|
38214
|
+
watermark: "center",
|
|
38212
38215
|
"formatting-marks": "right",
|
|
38213
38216
|
"table-of-contents": "center"
|
|
38214
38217
|
});
|
|
@@ -38319,7 +38322,8 @@ function normalizeToolbarOptions(options) {
|
|
|
38319
38322
|
fonts: options.fontOptions === void 0 ? options.fonts : mapToolbarFontOptions(options.fontOptions),
|
|
38320
38323
|
customButtons: options.customItems === void 0 ? options.customButtons : mapToolbarCustomItems(options.customItems),
|
|
38321
38324
|
showFormattingMarksButton: includeItems === null && !itemIds.has("formatting-marks") ? options.showFormattingMarksButton : itemIds.has("formatting-marks") || includeItems?.has("formatting-marks"),
|
|
38322
|
-
showTableOfContentsButton: includeItems === null && !itemIds.has("table-of-contents") ? options.showTableOfContentsButton : itemIds.has("table-of-contents") || includeItems?.has("table-of-contents")
|
|
38325
|
+
showTableOfContentsButton: includeItems === null && !itemIds.has("table-of-contents") ? options.showTableOfContentsButton : itemIds.has("table-of-contents") || includeItems?.has("table-of-contents"),
|
|
38326
|
+
showWatermarkButton: itemIds.has("watermark") || includeItems?.has("watermark") || false
|
|
38323
38327
|
});
|
|
38324
38328
|
}
|
|
38325
38329
|
/**
|
|
@@ -38849,6 +38853,14 @@ var BUILT_IN_TOOLBAR_CATALOG = [
|
|
|
38849
38853
|
disposition: "controller-routed",
|
|
38850
38854
|
group: "center"
|
|
38851
38855
|
},
|
|
38856
|
+
{
|
|
38857
|
+
name: "watermark",
|
|
38858
|
+
commandId: null,
|
|
38859
|
+
instanceMethod: "ui.watermark.open",
|
|
38860
|
+
disposition: "host-routed",
|
|
38861
|
+
group: "center",
|
|
38862
|
+
note: "opens the shared Watermark dialog through superdoc.ui.watermark.open; the workflow owns scope, edit permissions, and apply"
|
|
38863
|
+
},
|
|
38852
38864
|
{
|
|
38853
38865
|
name: "table",
|
|
38854
38866
|
commandId: "table-insert",
|
|
@@ -38974,153 +38986,6 @@ function resolveToolbarCommandId(name) {
|
|
|
38974
38986
|
return entry?.disposition === "controller-routed" ? entry.commandId : null;
|
|
38975
38987
|
}
|
|
38976
38988
|
//#endregion
|
|
38977
|
-
//#region src/internal/toolbar/image-upload.js
|
|
38978
|
-
/**
|
|
38979
|
-
* Interactive image acquisition for the built-in toolbar (SD-3567).
|
|
38980
|
-
*
|
|
38981
|
-
* The toolbar image button routes through the shared controller command
|
|
38982
|
-
* `image` → `create.image`, which requires a base64 PNG/JPEG data-URI `src`.
|
|
38983
|
-
* This module owns the browser file picker and the File → data-URI
|
|
38984
|
-
* conversion; the toolbar dispatches the resulting payload through the
|
|
38985
|
-
* normal controller command path.
|
|
38986
|
-
*/
|
|
38987
|
-
/** Accept filter for the picker: PNG and JPEG only (V1 parity; OOXML-native formats). */
|
|
38988
|
-
var IMAGE_PICKER_ACCEPT = ".png,.jpg,.jpeg,image/png,image/jpeg";
|
|
38989
|
-
var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
38990
|
-
"image/png",
|
|
38991
|
-
"image/jpeg",
|
|
38992
|
-
"image/jpg"
|
|
38993
|
-
]);
|
|
38994
|
-
var SUPPORTED_IMAGE_EXTENSIONS = /\.(png|jpe?g)$/i;
|
|
38995
|
-
/**
|
|
38996
|
-
* Whether a picked/dropped file is an insertable image (PNG/JPEG). Falls back
|
|
38997
|
-
* to the file extension when the browser reports no MIME type.
|
|
38998
|
-
* @param {File | null | undefined} file
|
|
38999
|
-
* @returns {boolean}
|
|
39000
|
-
*/
|
|
39001
|
-
function isSupportedImageFile(file) {
|
|
39002
|
-
if (!file) return false;
|
|
39003
|
-
const type = typeof file.type === "string" ? file.type.toLowerCase() : "";
|
|
39004
|
-
if (type) return SUPPORTED_IMAGE_MIME_TYPES.has(type);
|
|
39005
|
-
return SUPPORTED_IMAGE_EXTENSIONS.test(String(file.name ?? ""));
|
|
39006
|
-
}
|
|
39007
|
-
/**
|
|
39008
|
-
* Read a File/Blob into a base64 data URI.
|
|
39009
|
-
*
|
|
39010
|
-
* Some browsers/OSes deliver picked files with an empty `type`; the picker
|
|
39011
|
-
* accepts those by extension, but `readAsDataURL` would then produce an
|
|
39012
|
-
* `application/octet-stream` data URI that `create.image` rejects. Rewrite
|
|
39013
|
-
* the media type from the filename so extension-accepted files still insert.
|
|
39014
|
-
* @param {Blob & { name?: string }} file
|
|
39015
|
-
* @returns {Promise<string>}
|
|
39016
|
-
*/
|
|
39017
|
-
function fileToDataUri(file) {
|
|
39018
|
-
return new Promise((resolve, reject) => {
|
|
39019
|
-
const reader = new FileReader();
|
|
39020
|
-
reader.onload = () => resolve(normalizeImageDataUri(String(reader.result), file));
|
|
39021
|
-
reader.onerror = () => reject(reader.error ?? /* @__PURE__ */ new Error("image-read-failed"));
|
|
39022
|
-
reader.readAsDataURL(file);
|
|
39023
|
-
});
|
|
39024
|
-
}
|
|
39025
|
-
/**
|
|
39026
|
-
* Ensure a data URI read from a supported file carries a PNG/JPEG media type.
|
|
39027
|
-
* Leaves URIs already typed as a supported image (or uninferable ones) alone.
|
|
39028
|
-
* @param {string} dataUri
|
|
39029
|
-
* @param {(Blob & { name?: string }) | null | undefined} file
|
|
39030
|
-
* @returns {string}
|
|
39031
|
-
*/
|
|
39032
|
-
function normalizeImageDataUri(dataUri, file) {
|
|
39033
|
-
const match = /^data:([^;,]*);base64,/.exec(dataUri);
|
|
39034
|
-
if (!match) return dataUri;
|
|
39035
|
-
const mime = match[1].toLowerCase();
|
|
39036
|
-
if (SUPPORTED_IMAGE_MIME_TYPES.has(mime)) return dataUri;
|
|
39037
|
-
const name = String(file?.name ?? "");
|
|
39038
|
-
const inferred = /\.jpe?g$/i.test(name) ? "image/jpeg" : /\.png$/i.test(name) ? "image/png" : null;
|
|
39039
|
-
if (!inferred) return dataUri;
|
|
39040
|
-
return `data:${inferred};base64,${dataUri.slice(match[0].length)}`;
|
|
39041
|
-
}
|
|
39042
|
-
/**
|
|
39043
|
-
* Resolve the `create.image` src for a picked file. Uses the consumer's
|
|
39044
|
-
* `handleImageUpload` callback when configured (V1 contract:
|
|
39045
|
-
* `(file: File) => Promise<string>`). A returned non-data URL is fetched and
|
|
39046
|
-
* embedded, because `create.image` requires an embedded base64 data URI.
|
|
39047
|
-
* @param {File} file
|
|
39048
|
-
* @param {((file: File) => Promise<string>) | null | undefined} handleImageUpload
|
|
39049
|
-
* @returns {Promise<string>}
|
|
39050
|
-
*/
|
|
39051
|
-
async function resolveImageSrc(file, handleImageUpload) {
|
|
39052
|
-
if (typeof handleImageUpload === "function") {
|
|
39053
|
-
const result = await handleImageUpload(file);
|
|
39054
|
-
if (typeof result !== "string" || result.trim() === "") throw new Error("handleImageUpload returned an empty result");
|
|
39055
|
-
if (result.startsWith("data:")) return result;
|
|
39056
|
-
return embedRemoteImage(result, file);
|
|
39057
|
-
}
|
|
39058
|
-
return fileToDataUri(file);
|
|
39059
|
-
}
|
|
39060
|
-
/**
|
|
39061
|
-
* Fetch a remote image URL and embed it as a data URI. Object-store /
|
|
39062
|
-
* presigned URLs often respond `application/octet-stream`, so keep a filename
|
|
39063
|
-
* hint (URL path, falling back to the originally picked file) for the media
|
|
39064
|
-
* type normalization in `fileToDataUri`.
|
|
39065
|
-
* @param {string} url
|
|
39066
|
-
* @param {File | null | undefined} pickedFile
|
|
39067
|
-
* @returns {Promise<string>}
|
|
39068
|
-
*/
|
|
39069
|
-
async function embedRemoteImage(url, pickedFile) {
|
|
39070
|
-
const response = await fetch(url);
|
|
39071
|
-
if (!response.ok) throw new Error(`image fetch failed: ${response.status}`);
|
|
39072
|
-
const blob = await response.blob();
|
|
39073
|
-
const name = (/\.(?:png|jpe?g)(?:$|[?#])/i.test(url) ? url.split(/[?#]/)[0] : "") || pickedFile?.name || "";
|
|
39074
|
-
return fileToDataUri(name ? Object.assign(blob, { name }) : blob);
|
|
39075
|
-
}
|
|
39076
|
-
/**
|
|
39077
|
-
* Hidden `<input type=file>` picker bound to one toolbar instance. The input
|
|
39078
|
-
* stays attached (hidden) so automation and tests can drive it; `destroy()`
|
|
39079
|
-
* removes it. Picking a file calls `onPick(file)`; an unsupported type or a
|
|
39080
|
-
* failed pick routes through `onError(error)`.
|
|
39081
|
-
*
|
|
39082
|
-
* @param {{
|
|
39083
|
-
* ownerDocument?: Document,
|
|
39084
|
-
* onPick?: (file: File) => unknown,
|
|
39085
|
-
* onError?: (error: Error) => void,
|
|
39086
|
-
* }} options
|
|
39087
|
-
* @returns {{ input: HTMLInputElement, open: () => void, destroy: () => void }}
|
|
39088
|
-
*/
|
|
39089
|
-
function createImageFilePicker({ ownerDocument = document, onPick, onError } = {}) {
|
|
39090
|
-
const input = ownerDocument.createElement("input");
|
|
39091
|
-
input.type = "file";
|
|
39092
|
-
input.accept = IMAGE_PICKER_ACCEPT;
|
|
39093
|
-
input.hidden = true;
|
|
39094
|
-
input.tabIndex = -1;
|
|
39095
|
-
input.setAttribute("data-superdoc-image-picker", "true");
|
|
39096
|
-
input.setAttribute("aria-hidden", "true");
|
|
39097
|
-
input.addEventListener("change", () => {
|
|
39098
|
-
const file = input.files && input.files[0];
|
|
39099
|
-
input.value = "";
|
|
39100
|
-
if (!file) return;
|
|
39101
|
-
if (!isSupportedImageFile(file)) {
|
|
39102
|
-
onError?.(/* @__PURE__ */ new Error(`unsupported image type: ${file.type || file.name}`));
|
|
39103
|
-
return;
|
|
39104
|
-
}
|
|
39105
|
-
try {
|
|
39106
|
-
const result = onPick?.(file);
|
|
39107
|
-
if (result && typeof result.then === "function") result.catch((error) => onError?.(error));
|
|
39108
|
-
} catch (error) {
|
|
39109
|
-
onError?.(error);
|
|
39110
|
-
}
|
|
39111
|
-
});
|
|
39112
|
-
ownerDocument.body?.appendChild(input);
|
|
39113
|
-
return {
|
|
39114
|
-
input,
|
|
39115
|
-
open() {
|
|
39116
|
-
input.click();
|
|
39117
|
-
},
|
|
39118
|
-
destroy() {
|
|
39119
|
-
input.remove();
|
|
39120
|
-
}
|
|
39121
|
-
};
|
|
39122
|
-
}
|
|
39123
|
-
//#endregion
|
|
39124
38989
|
//#region src/internal/toolbar/built-in/helpers.js
|
|
39125
38990
|
var sanitizeNumber = (value, defaultNumber) => {
|
|
39126
38991
|
let sanitized = value.replace(/[^0-9.]/g, "");
|
|
@@ -39311,6 +39176,7 @@ var _sfc_main$18 = {
|
|
|
39311
39176
|
handleClick();
|
|
39312
39177
|
};
|
|
39313
39178
|
const onEnterKeydown = (event) => {
|
|
39179
|
+
event.preventDefault();
|
|
39314
39180
|
if (!props.allowEnterPropagation) event.stopPropagation();
|
|
39315
39181
|
handleOuterEnter(event);
|
|
39316
39182
|
};
|
|
@@ -39503,7 +39369,7 @@ var _sfc_main$18 = {
|
|
|
39503
39369
|
};
|
|
39504
39370
|
}
|
|
39505
39371
|
};
|
|
39506
|
-
var ToolbarButton_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$18, [["__scopeId", "data-v-
|
|
39372
|
+
var ToolbarButton_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$18, [["__scopeId", "data-v-96796456"]]);
|
|
39507
39373
|
//#endregion
|
|
39508
39374
|
//#region src/internal/toolbar/built-in/ToolbarSeparator.vue
|
|
39509
39375
|
var _hoisted_1$13 = {
|
|
@@ -39584,7 +39450,7 @@ var _sfc_main$16 = {
|
|
|
39584
39450
|
}
|
|
39585
39451
|
},
|
|
39586
39452
|
emits: ["update:show", "select"],
|
|
39587
|
-
setup(__props, { emit: __emit }) {
|
|
39453
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
39588
39454
|
const props = __props;
|
|
39589
39455
|
const emit = __emit;
|
|
39590
39456
|
const slots = (0, vue.useSlots)();
|
|
@@ -39819,6 +39685,7 @@ var _sfc_main$16 = {
|
|
|
39819
39685
|
trigger.setAttribute("tabindex", "-1");
|
|
39820
39686
|
trigger.focus();
|
|
39821
39687
|
};
|
|
39688
|
+
__expose({ focusTrigger });
|
|
39822
39689
|
const handleKeyDown = (event) => {
|
|
39823
39690
|
if (!isOpen.value) return;
|
|
39824
39691
|
const { key } = event;
|
|
@@ -39931,7 +39798,7 @@ var _sfc_main$16 = {
|
|
|
39931
39798
|
};
|
|
39932
39799
|
}
|
|
39933
39800
|
};
|
|
39934
|
-
var ToolbarDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$16, [["__scopeId", "data-v-
|
|
39801
|
+
var ToolbarDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$16, [["__scopeId", "data-v-fa3f6b69"]]);
|
|
39935
39802
|
//#endregion
|
|
39936
39803
|
//#region src/internal/toolbar/built-in/toolbar-focus-helpers.js
|
|
39937
39804
|
var preventEditorFocusTransfer = (event) => {
|
|
@@ -39979,6 +39846,7 @@ var _sfc_main$15 = {
|
|
|
39979
39846
|
setup(__props, { emit: __emit }) {
|
|
39980
39847
|
const emit = __emit;
|
|
39981
39848
|
const props = __props;
|
|
39849
|
+
const dropdown = (0, vue.ref)(null);
|
|
39982
39850
|
const isOverflowMenuOpened = (0, vue.computed)(() => props.toolbarItem.expand.value);
|
|
39983
39851
|
const hasOpenDropdown = (0, vue.computed)(() => props.overflowItems.some((item) => item.type === "dropdown" && (0, vue.unref)(item.expand)));
|
|
39984
39852
|
const overflowToolbarItem = (0, vue.computed)(() => ({
|
|
@@ -39994,6 +39862,10 @@ var _sfc_main$15 = {
|
|
|
39994
39862
|
emit("close");
|
|
39995
39863
|
};
|
|
39996
39864
|
const handleCommand = ({ item, argument, option }) => {
|
|
39865
|
+
if (item.name.value === "watermark") {
|
|
39866
|
+
emit("close");
|
|
39867
|
+
dropdown.value?.focusTrigger();
|
|
39868
|
+
}
|
|
39997
39869
|
emit("command", {
|
|
39998
39870
|
item,
|
|
39999
39871
|
argument,
|
|
@@ -40002,6 +39874,8 @@ var _sfc_main$15 = {
|
|
|
40002
39874
|
};
|
|
40003
39875
|
return (_ctx, _cache) => {
|
|
40004
39876
|
return (0, vue.openBlock)(), (0, vue.createBlock)(ToolbarDropdown_default, {
|
|
39877
|
+
ref_key: "dropdown",
|
|
39878
|
+
ref: dropdown,
|
|
40005
39879
|
class: "overflow-menu",
|
|
40006
39880
|
"close-on-escape": !hasOpenDropdown.value,
|
|
40007
39881
|
"has-open-child": hasOpenDropdown.value,
|
|
@@ -40019,7 +39893,10 @@ var _sfc_main$15 = {
|
|
|
40019
39893
|
class: ["overflow-menu_items", "sd-toolbar-overflow-menu"]
|
|
40020
39894
|
})
|
|
40021
39895
|
}, {
|
|
40022
|
-
trigger: (0, vue.withCtx)(() => [(0, vue.createVNode)(ToolbarButton_default, {
|
|
39896
|
+
trigger: (0, vue.withCtx)(() => [(0, vue.createVNode)(ToolbarButton_default, {
|
|
39897
|
+
"toolbar-item": overflowToolbarItem.value,
|
|
39898
|
+
"allow-enter-propagation": true
|
|
39899
|
+
}, null, 8, ["toolbar-item"])]),
|
|
40023
39900
|
menu: (0, vue.withCtx)(() => [(0, vue.createVNode)(ButtonGroup_default, {
|
|
40024
39901
|
class: "superdoc-toolbar-overflow",
|
|
40025
39902
|
"toolbar-items": __props.overflowItems,
|
|
@@ -40042,7 +39919,7 @@ var _sfc_main$15 = {
|
|
|
40042
39919
|
};
|
|
40043
39920
|
}
|
|
40044
39921
|
};
|
|
40045
|
-
var OverflowMenu_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$15, [["__scopeId", "data-v-
|
|
39922
|
+
var OverflowMenu_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$15, [["__scopeId", "data-v-1227fcf9"]]);
|
|
40046
39923
|
//#endregion
|
|
40047
39924
|
//#region src/internal/toolbar/built-in/font-typeahead.js
|
|
40048
39925
|
/**
|
|
@@ -41680,10 +41557,12 @@ var Toolbar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vu
|
|
|
41680
41557
|
setup(__props, { emit: __emit }) {
|
|
41681
41558
|
const { proxy } = (0, vue.getCurrentInstance)();
|
|
41682
41559
|
let toolbarKey = (0, vue.ref)(1);
|
|
41560
|
+
const toolbarRoot = (0, vue.ref)(null);
|
|
41683
41561
|
const toolbarStateVersion = (0, vue.ref)(0);
|
|
41684
41562
|
const compactSideGroups = (0, vue.ref)(false);
|
|
41685
41563
|
let containerResizeObserver = null;
|
|
41686
41564
|
let pendingSelectionCapture = null;
|
|
41565
|
+
let renderedWidth = proxy.$toolbar.getAvailableWidth();
|
|
41687
41566
|
/**
|
|
41688
41567
|
* Computed property that determines the font-family to use for toolbar UI surfaces.
|
|
41689
41568
|
* Retrieves the configured font from the toolbar instance's config and validates it.
|
|
@@ -41704,10 +41583,41 @@ var Toolbar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vu
|
|
|
41704
41583
|
const updateCompactSideGroups = () => {
|
|
41705
41584
|
compactSideGroups.value = proxy.$toolbar.getAvailableWidth() <= RESPONSIVE_BREAKPOINTS.lg;
|
|
41706
41585
|
};
|
|
41586
|
+
const captureFocusedControl = () => {
|
|
41587
|
+
const root = toolbarRoot.value;
|
|
41588
|
+
const ownerDocument = root?.ownerDocument;
|
|
41589
|
+
const focused = ownerDocument?.activeElement;
|
|
41590
|
+
if (!root?.contains(focused)) return null;
|
|
41591
|
+
const control = focused.closest("[data-sd-part=\"toolbar-item\"]") ?? focused.querySelector("[data-sd-part=\"toolbar-item\"]");
|
|
41592
|
+
if (!control || focused !== control && !focused.contains(control)) return null;
|
|
41593
|
+
const itemId = control.querySelector("[data-item]")?.getAttribute("data-item");
|
|
41594
|
+
if (!itemId) return null;
|
|
41595
|
+
return () => {
|
|
41596
|
+
const currentRoot = toolbarRoot.value;
|
|
41597
|
+
if (!currentRoot?.isConnected || focused.isConnected || ownerDocument.activeElement !== ownerDocument.body) return;
|
|
41598
|
+
const markers = [...currentRoot.querySelectorAll("[data-item]")];
|
|
41599
|
+
for (const id of [itemId, "btn-overflow"]) {
|
|
41600
|
+
const target = markers.find((marker) => marker.getAttribute("data-item") === id)?.closest("[data-sd-part=\"toolbar-item\"]");
|
|
41601
|
+
if (target && target.getAttribute("aria-disabled") !== "true") {
|
|
41602
|
+
target.focus({ preventScroll: true });
|
|
41603
|
+
return;
|
|
41604
|
+
}
|
|
41605
|
+
}
|
|
41606
|
+
};
|
|
41607
|
+
};
|
|
41608
|
+
const renderToolbar = async (restoreFocus) => {
|
|
41609
|
+
toolbarKey.value += 1;
|
|
41610
|
+
await (0, vue.nextTick)();
|
|
41611
|
+
restoreFocus?.();
|
|
41612
|
+
};
|
|
41707
41613
|
const onWindowResized = async () => {
|
|
41614
|
+
const width = proxy.$toolbar.getAvailableWidth();
|
|
41615
|
+
if (width === renderedWidth) return;
|
|
41616
|
+
renderedWidth = width;
|
|
41617
|
+
const restoreFocus = captureFocusedControl();
|
|
41708
41618
|
await proxy.$toolbar.onToolbarResize();
|
|
41709
41619
|
updateCompactSideGroups();
|
|
41710
|
-
|
|
41620
|
+
await renderToolbar(restoreFocus);
|
|
41711
41621
|
};
|
|
41712
41622
|
const onResizeThrottled = throttle(onWindowResized, 300);
|
|
41713
41623
|
/**
|
|
@@ -41717,12 +41627,16 @@ var Toolbar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vu
|
|
|
41717
41627
|
* SuperToolbar emits `toolbar-items-changed` on rebuild; bumping the key re-reads the new items into the DOM.
|
|
41718
41628
|
*/
|
|
41719
41629
|
const onToolbarItemsChanged = () => {
|
|
41720
|
-
|
|
41630
|
+
const restoreFocus = captureFocusedControl();
|
|
41631
|
+
renderedWidth = proxy.$toolbar.getAvailableWidth();
|
|
41632
|
+
updateCompactSideGroups();
|
|
41633
|
+
renderToolbar(restoreFocus);
|
|
41721
41634
|
};
|
|
41722
41635
|
const onToolbarStateChanged = () => {
|
|
41723
41636
|
toolbarStateVersion.value += 1;
|
|
41724
41637
|
};
|
|
41725
41638
|
function teardownListeners() {
|
|
41639
|
+
onResizeThrottled.cancel();
|
|
41726
41640
|
window.removeEventListener("resize", onResizeThrottled);
|
|
41727
41641
|
proxy.$toolbar.off?.("toolbar-items-changed", onToolbarItemsChanged);
|
|
41728
41642
|
proxy.$toolbar.off?.("toolbar-state-change", onToolbarStateChanged);
|
|
@@ -41780,6 +41694,8 @@ var Toolbar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vu
|
|
|
41780
41694
|
return (_ctx, _cache) => {
|
|
41781
41695
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
41782
41696
|
class: "superdoc-toolbar",
|
|
41697
|
+
ref_key: "toolbarRoot",
|
|
41698
|
+
ref: toolbarRoot,
|
|
41783
41699
|
key: (0, vue.unref)(toolbarKey),
|
|
41784
41700
|
role: "toolbar",
|
|
41785
41701
|
"aria-label": "Toolbar",
|
|
@@ -41836,7 +41752,7 @@ var Toolbar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vu
|
|
|
41836
41752
|
], 32);
|
|
41837
41753
|
};
|
|
41838
41754
|
}
|
|
41839
|
-
}, [["__scopeId", "data-v-
|
|
41755
|
+
}, [["__scopeId", "data-v-9418cc7d"]]);
|
|
41840
41756
|
//#endregion
|
|
41841
41757
|
//#region src/internal/toolbar/built-in/font-options.js
|
|
41842
41758
|
/**
|
|
@@ -43452,6 +43368,15 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons, toolbarTexts, toolbarFonts
|
|
|
43452
43368
|
disabled: false,
|
|
43453
43369
|
attributes: { ariaLabel: "Table of contents" }
|
|
43454
43370
|
});
|
|
43371
|
+
const watermark = useToolbarItem({
|
|
43372
|
+
type: "button",
|
|
43373
|
+
name: "watermark",
|
|
43374
|
+
icon: toolbarIcons.watermark,
|
|
43375
|
+
tooltip: toolbarTexts.watermark,
|
|
43376
|
+
allowWithoutEditor: true,
|
|
43377
|
+
disabled: true,
|
|
43378
|
+
attributes: { ariaLabel: toolbarTexts.watermark }
|
|
43379
|
+
});
|
|
43455
43380
|
const tableItem = useToolbarItem({
|
|
43456
43381
|
type: "dropdown",
|
|
43457
43382
|
name: "table",
|
|
@@ -44157,6 +44082,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons, toolbarTexts, toolbarFonts
|
|
|
44157
44082
|
link,
|
|
44158
44083
|
image,
|
|
44159
44084
|
...shouldIncludeTableOfContents ? [tableOfContents] : [],
|
|
44085
|
+
...superToolbar.config?.showWatermarkButton || configuredItemNames?.has("watermark") ? [watermark] : [],
|
|
44160
44086
|
tableItem,
|
|
44161
44087
|
tableActionsItem,
|
|
44162
44088
|
makeSeparator(),
|
|
@@ -44263,6 +44189,7 @@ var toolbarTexts = {
|
|
|
44263
44189
|
link: "Link",
|
|
44264
44190
|
image: "Image",
|
|
44265
44191
|
tableOfContents: "Table of contents",
|
|
44192
|
+
watermark: "Watermark",
|
|
44266
44193
|
table: "Insert table",
|
|
44267
44194
|
tableActions: "Table options",
|
|
44268
44195
|
addRowBefore: "Insert row above",
|
|
@@ -44462,7 +44389,8 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
|
|
|
44462
44389
|
groups: null,
|
|
44463
44390
|
customButtons: [],
|
|
44464
44391
|
showFormattingMarksButton: false,
|
|
44465
|
-
showTableOfContentsButton: false
|
|
44392
|
+
showTableOfContentsButton: false,
|
|
44393
|
+
showWatermarkButton: false
|
|
44466
44394
|
};
|
|
44467
44395
|
toolbarItems = [];
|
|
44468
44396
|
overflowItems = [];
|
|
@@ -44796,6 +44724,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
|
|
|
44796
44724
|
return false;
|
|
44797
44725
|
}
|
|
44798
44726
|
#canRunHostAction(name) {
|
|
44727
|
+
if (name === "watermark") return this.ui?.document?.getSnapshot?.().ready === true && typeof this.ui?.watermark?.open === "function";
|
|
44799
44728
|
if (name === "ruler") return typeof this.superdoc?.toggleRuler === "function";
|
|
44800
44729
|
if (name === "formattingMarks") return typeof this.superdoc?.toggleFormattingMarks === "function" || typeof this.superdoc?.setShowFormattingMarks === "function";
|
|
44801
44730
|
return false;
|
|
@@ -44974,6 +44903,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
|
|
|
44974
44903
|
item.resetDisabled();
|
|
44975
44904
|
this.#applyHeadlessState(item);
|
|
44976
44905
|
});
|
|
44906
|
+
this.getToolbarItemByName("overflow")?.setDisabled(!this.overflowItems.some((item) => item.type !== "separator" && !item.disabled.value));
|
|
44977
44907
|
const copyFormatItem = this.getToolbarItemByName("copyFormat");
|
|
44978
44908
|
if (copyFormatItem) if (this.snapshot?.copyFormatActive) copyFormatItem.activate();
|
|
44979
44909
|
else copyFormatItem.deactivate();
|
|
@@ -44988,6 +44918,12 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
|
|
|
44988
44918
|
}
|
|
44989
44919
|
#runHostAction(name, argument) {
|
|
44990
44920
|
const superdoc = this.superdoc;
|
|
44921
|
+
if (name === "watermark") {
|
|
44922
|
+
if (!this.#canRunHostAction(name)) return false;
|
|
44923
|
+
const result = this.ui.watermark.open();
|
|
44924
|
+
if (!result.ok) throw new Error(`[superdoc toolbar] Watermark dialog unavailable: ${result.reason}`);
|
|
44925
|
+
return true;
|
|
44926
|
+
}
|
|
44991
44927
|
if (name === "ruler") {
|
|
44992
44928
|
if (typeof superdoc?.toggleRuler === "function") {
|
|
44993
44929
|
superdoc.toggleRuler();
|
|
@@ -45042,10 +44978,10 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
|
|
|
45042
44978
|
*/
|
|
45043
44979
|
#startImagePick() {
|
|
45044
44980
|
if ((this.snapshot?.commands?.["image"])?.disabled) return true;
|
|
45045
|
-
if (!this.#imagePicker) this.#imagePicker = createImageFilePicker({
|
|
44981
|
+
if (!this.#imagePicker) this.#imagePicker = require_create_super_doc_ui.createImageFilePicker({
|
|
45046
44982
|
ownerDocument: this.toolbarContainer?.ownerDocument ?? document,
|
|
45047
44983
|
onPick: async (file) => {
|
|
45048
|
-
const src = await resolveImageSrc(file, this.superdoc?.config?.handleImageUpload);
|
|
44984
|
+
const src = await require_create_super_doc_ui.resolveImageSrc(file, this.superdoc?.config?.handleImageUpload);
|
|
45049
44985
|
executeCommand(this.ui, "image", { src }, {
|
|
45050
44986
|
firstParty: true,
|
|
45051
44987
|
onSettled: () => this.updateToolbarState(),
|
|
@@ -45750,7 +45686,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
45750
45686
|
this.config.colors = shuffleArray(this.config.colors);
|
|
45751
45687
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
45752
45688
|
this.colorIndex = 0;
|
|
45753
|
-
this.version = "2.
|
|
45689
|
+
this.version = "2.19.0-next.2";
|
|
45754
45690
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
45755
45691
|
this.superdocId = config.superdocId || require_uuid.v4();
|
|
45756
45692
|
this.colors = this.config.colors ?? [];
|
|
@@ -47142,7 +47078,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
47142
47078
|
{
|
|
47143
47079
|
feature: "shell.collaboration",
|
|
47144
47080
|
status: "supported",
|
|
47145
|
-
reason: "v2 single-doc y-websocket
|
|
47081
|
+
reason: "v2 single-doc collaboration (hocuspocus, y-websocket, liveblocks, and registered provider extensions) is wired through document.collaboration, including collaboration-ready, awareness-update, and locked event bridges; external { ydoc, provider } instances remain unsupported"
|
|
47146
47082
|
},
|
|
47147
47083
|
{
|
|
47148
47084
|
feature: "shell.context-menu",
|