@harbour-enterprises/superdoc 0.12.37-next.1 → 0.12.37-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/{super-editor.es-DmBtUqwe.cjs → super-editor.es-3IGIxgjF.cjs} +376 -148
- package/dist/chunks/{super-editor.es-DYzhjqc5.es.js → super-editor.es-WrgX5vxB.es.js} +376 -148
- package/dist/style.css +76 -0
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-ffnCghzo.js → converter-RpLHCUPf.js} +2 -2
- package/dist/super-editor/chunks/{docx-zipper-BvIz98Bh.js → docx-zipper-V5sLSr7T.js} +1 -1
- package/dist/super-editor/chunks/{editor-BCC23g3q.js → editor-CAT1dxaK.js} +379 -16
- package/dist/super-editor/chunks/{toolbar-BZxPbO0T.js → toolbar-Cts0XR5V.js} +2 -2
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor/docx-zipper.es.js +2 -2
- package/dist/super-editor/editor.es.js +3 -3
- package/dist/super-editor/extensions/image/imageHelpers/imagePositionPlugin.d.ts.map +1 -1
- package/dist/super-editor/extensions/image/imageHelpers/index.d.ts +1 -0
- package/dist/super-editor/extensions/image/imageHelpers/processUploadedImage.d.ts.map +1 -1
- package/dist/super-editor/extensions/image/index.d.ts +1 -0
- package/dist/super-editor/extensions/index.d.ts +2 -1
- package/dist/super-editor/extensions/index.d.ts.map +1 -1
- package/dist/super-editor/extensions/noderesizer/index.d.ts +2 -0
- package/dist/super-editor/extensions/noderesizer/index.d.ts.map +1 -0
- package/dist/super-editor/extensions/noderesizer/noderesizer.d.ts +7 -0
- package/dist/super-editor/extensions/noderesizer/noderesizer.d.ts.map +1 -0
- package/dist/super-editor/file-zipper.es.js +1 -1
- package/dist/super-editor/style.css +76 -0
- package/dist/super-editor/super-editor.es.js +7 -141
- package/dist/super-editor/toolbar.es.js +2 -2
- package/dist/super-editor.cjs +1 -1
- package/dist/super-editor.es.js +1 -1
- package/dist/superdoc.cjs +2 -2
- package/dist/superdoc.es.js +3 -3
- package/dist/superdoc.umd.js +376 -148
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const Y = require("yjs");
|
|
3
2
|
const vue = require("./vue-HIY1g7dm.cjs");
|
|
3
|
+
const Y = require("yjs");
|
|
4
4
|
function _interopNamespaceDefault(e) {
|
|
5
5
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
6
6
|
if (e) {
|
|
@@ -23410,7 +23410,7 @@ const _SuperConverter = class _SuperConverter2 {
|
|
|
23410
23410
|
return;
|
|
23411
23411
|
}
|
|
23412
23412
|
}
|
|
23413
|
-
static updateDocumentVersion(docx = this.convertedXml, version2 = "0.12.37-next.
|
|
23413
|
+
static updateDocumentVersion(docx = this.convertedXml, version2 = "0.12.37-next.2") {
|
|
23414
23414
|
const customLocation = "docProps/custom.xml";
|
|
23415
23415
|
if (!docx[customLocation]) {
|
|
23416
23416
|
docx[customLocation] = generateCustomXml();
|
|
@@ -23877,7 +23877,7 @@ function storeSuperdocVersion(docx) {
|
|
|
23877
23877
|
function generateCustomXml() {
|
|
23878
23878
|
return DEFAULT_CUSTOM_XML;
|
|
23879
23879
|
}
|
|
23880
|
-
function generateSuperdocVersion(pid = 2, version2 = "0.12.37-next.
|
|
23880
|
+
function generateSuperdocVersion(pid = 2, version2 = "0.12.37-next.2") {
|
|
23881
23881
|
return {
|
|
23882
23882
|
type: "element",
|
|
23883
23883
|
name: "property",
|
|
@@ -41254,7 +41254,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
|
|
|
41254
41254
|
* @returns {Object | void} Migration results
|
|
41255
41255
|
*/
|
|
41256
41256
|
processCollaborationMigrations() {
|
|
41257
|
-
console.debug("[checkVersionMigrations] Current editor version", "0.12.37-next.
|
|
41257
|
+
console.debug("[checkVersionMigrations] Current editor version", "0.12.37-next.2");
|
|
41258
41258
|
if (!this.options.ydoc) return;
|
|
41259
41259
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
41260
41260
|
let docVersion = metaMap.get("version");
|
|
@@ -48637,10 +48637,7 @@ const ImagePositionPlugin = ({ editor }) => {
|
|
|
48637
48637
|
if (shouldUpdate) {
|
|
48638
48638
|
shouldUpdate = false;
|
|
48639
48639
|
const decorations = getImagePositionDecorations(lastState, view3);
|
|
48640
|
-
const updateTransaction = view3.state.tr.setMeta(
|
|
48641
|
-
ImagePositionPluginKey,
|
|
48642
|
-
{ decorations }
|
|
48643
|
-
);
|
|
48640
|
+
const updateTransaction = view3.state.tr.setMeta(ImagePositionPluginKey, { decorations });
|
|
48644
48641
|
view3.dispatch(updateTransaction);
|
|
48645
48642
|
}
|
|
48646
48643
|
if (pagination?.isReadyToInit) {
|
|
@@ -48772,16 +48769,16 @@ const Image = Node$1.create({
|
|
|
48772
48769
|
default: {},
|
|
48773
48770
|
renderDOM: ({ size: size2 }) => {
|
|
48774
48771
|
let style2 = "";
|
|
48775
|
-
|
|
48772
|
+
const { width, height } = size2 ?? {};
|
|
48776
48773
|
if (width) style2 += `width: ${width}px;`;
|
|
48777
|
-
if (height) style2 +=
|
|
48774
|
+
if (height) style2 += "height: auto;";
|
|
48778
48775
|
return { style: style2 };
|
|
48779
48776
|
}
|
|
48780
48777
|
},
|
|
48781
48778
|
padding: {
|
|
48782
48779
|
default: {},
|
|
48783
48780
|
renderDOM: ({ padding, marginOffset }) => {
|
|
48784
|
-
|
|
48781
|
+
const { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
|
|
48785
48782
|
let style2 = "";
|
|
48786
48783
|
if (left2 && !marginOffset?.left) style2 += `margin-left: ${left2}px;`;
|
|
48787
48784
|
if (top2 && !marginOffset?.top) style2 += `margin-top: ${top2}px;`;
|
|
@@ -48793,7 +48790,7 @@ const Image = Node$1.create({
|
|
|
48793
48790
|
marginOffset: {
|
|
48794
48791
|
default: {},
|
|
48795
48792
|
renderDOM: ({ marginOffset }) => {
|
|
48796
|
-
|
|
48793
|
+
const { left: left2 = 0, top: top2 = 0 } = marginOffset ?? {};
|
|
48797
48794
|
let style2 = "";
|
|
48798
48795
|
if (left2) style2 += `margin-left: ${left2}px;`;
|
|
48799
48796
|
if (top2) style2 += `margin-top: ${top2}px;`;
|
|
@@ -48834,6 +48831,136 @@ const Image = Node$1.create({
|
|
|
48834
48831
|
return [ImagePlaceholderPlugin(), ImagePositionPlugin({ editor: this.editor })];
|
|
48835
48832
|
}
|
|
48836
48833
|
});
|
|
48834
|
+
const ACCEPT_IMAGE_TYPES = [".jpg", ".jpeg", ".png", "image/jpeg", "image/png"];
|
|
48835
|
+
const getFileOpener = () => {
|
|
48836
|
+
let fileInput = document.createElement("input");
|
|
48837
|
+
fileInput.type = "file";
|
|
48838
|
+
let acceptTypes = ACCEPT_IMAGE_TYPES;
|
|
48839
|
+
fileInput.accept = acceptTypes.join(",");
|
|
48840
|
+
const openFile = () => {
|
|
48841
|
+
return new Promise((resolve, reject) => {
|
|
48842
|
+
fileInput.onchange = async () => {
|
|
48843
|
+
const files = fileInput.files;
|
|
48844
|
+
if (!files) return resolve(null);
|
|
48845
|
+
const file = files.item(0);
|
|
48846
|
+
if (!file) return resolve(null);
|
|
48847
|
+
return resolve({ file });
|
|
48848
|
+
};
|
|
48849
|
+
fileInput.oncancel = () => resolve(null);
|
|
48850
|
+
fileInput.onerror = reject;
|
|
48851
|
+
fileInput.click();
|
|
48852
|
+
});
|
|
48853
|
+
};
|
|
48854
|
+
return openFile;
|
|
48855
|
+
};
|
|
48856
|
+
const handleImageUpload = (file) => {
|
|
48857
|
+
return new Promise((resolve, reject) => {
|
|
48858
|
+
let reader = new FileReader();
|
|
48859
|
+
reader.onload = (event) => resolve(event.target.result);
|
|
48860
|
+
reader.onerror = reject;
|
|
48861
|
+
setTimeout(() => reader.readAsDataURL(file), 250);
|
|
48862
|
+
});
|
|
48863
|
+
};
|
|
48864
|
+
const processUploadedImage = (fileData, editor) => {
|
|
48865
|
+
return new Promise((resolve, reject) => {
|
|
48866
|
+
const img = new window.Image();
|
|
48867
|
+
img.onload = () => {
|
|
48868
|
+
const canvas = document.createElement("canvas");
|
|
48869
|
+
const { width, height } = getAllowedImageDimensions(img.width, img.height, editor);
|
|
48870
|
+
canvas.width = width;
|
|
48871
|
+
canvas.height = height;
|
|
48872
|
+
const ctx2 = canvas.getContext("2d");
|
|
48873
|
+
ctx2.drawImage(img, 0, 0, width, height);
|
|
48874
|
+
if (typeof fileData === "string") {
|
|
48875
|
+
const resizedBase64 = canvas.toDataURL();
|
|
48876
|
+
resolve(resizedBase64);
|
|
48877
|
+
} else {
|
|
48878
|
+
canvas.toBlob((blob) => {
|
|
48879
|
+
const updatedFile = new File([blob], fileData.name, {
|
|
48880
|
+
type: fileData.type,
|
|
48881
|
+
lastModified: Date.now()
|
|
48882
|
+
});
|
|
48883
|
+
resolve({ file: updatedFile, width, height });
|
|
48884
|
+
});
|
|
48885
|
+
}
|
|
48886
|
+
};
|
|
48887
|
+
img.onerror = (error) => reject(error);
|
|
48888
|
+
img.src = typeof fileData === "string" ? fileData : URL.createObjectURL(fileData);
|
|
48889
|
+
});
|
|
48890
|
+
};
|
|
48891
|
+
const getAllowedImageDimensions = (width, height, editor) => {
|
|
48892
|
+
const { width: maxWidth, height: maxHeight } = editor.getMaxContentSize();
|
|
48893
|
+
if (!maxWidth || !maxHeight) return { width, height };
|
|
48894
|
+
let adjustedWidth = width;
|
|
48895
|
+
let adjustedHeight = height;
|
|
48896
|
+
const aspectRatio = width / height;
|
|
48897
|
+
if (height > maxHeight) {
|
|
48898
|
+
adjustedHeight = maxHeight;
|
|
48899
|
+
adjustedWidth = Math.round(maxHeight * aspectRatio);
|
|
48900
|
+
}
|
|
48901
|
+
if (adjustedWidth > maxWidth) {
|
|
48902
|
+
adjustedWidth = maxWidth;
|
|
48903
|
+
adjustedHeight = Math.round(maxWidth / aspectRatio);
|
|
48904
|
+
}
|
|
48905
|
+
return { width: adjustedWidth, height: adjustedHeight };
|
|
48906
|
+
};
|
|
48907
|
+
const startImageUpload = async ({ editor, view, file }) => {
|
|
48908
|
+
let imageUploadHandler = typeof editor.options.handleImageUpload === "function" ? editor.options.handleImageUpload : handleImageUpload;
|
|
48909
|
+
let fileSizeMb = (file.size / (1024 * 1024)).toFixed(4);
|
|
48910
|
+
if (fileSizeMb > 5) {
|
|
48911
|
+
window.alert("Image size must be less than 5MB");
|
|
48912
|
+
return;
|
|
48913
|
+
}
|
|
48914
|
+
let width;
|
|
48915
|
+
let height;
|
|
48916
|
+
try {
|
|
48917
|
+
const processedImageResult = await processUploadedImage(file, editor);
|
|
48918
|
+
width = processedImageResult.width;
|
|
48919
|
+
height = processedImageResult.height;
|
|
48920
|
+
file = processedImageResult.file;
|
|
48921
|
+
} catch (err) {
|
|
48922
|
+
console.warn("Error processing image:", err);
|
|
48923
|
+
return;
|
|
48924
|
+
}
|
|
48925
|
+
let id = {};
|
|
48926
|
+
let { tr, schema } = view.state;
|
|
48927
|
+
if (!tr.selection.empty) {
|
|
48928
|
+
tr.deleteSelection();
|
|
48929
|
+
}
|
|
48930
|
+
let imageMeta = {
|
|
48931
|
+
type: "add",
|
|
48932
|
+
pos: tr.selection.from,
|
|
48933
|
+
id
|
|
48934
|
+
};
|
|
48935
|
+
tr.setMeta(ImagePlaceholderPluginKey, imageMeta);
|
|
48936
|
+
view.dispatch(tr);
|
|
48937
|
+
imageUploadHandler(file).then(
|
|
48938
|
+
(url) => {
|
|
48939
|
+
let fileName = file.name.replace(" ", "_");
|
|
48940
|
+
let placeholderPos = findPlaceholder(view.state, id);
|
|
48941
|
+
if (placeholderPos == null) {
|
|
48942
|
+
return;
|
|
48943
|
+
}
|
|
48944
|
+
let removeMeta = { type: "remove", id };
|
|
48945
|
+
let mediaPath = `word/media/${fileName}`;
|
|
48946
|
+
let imageNode = schema.nodes.image.create({
|
|
48947
|
+
src: mediaPath,
|
|
48948
|
+
size: { width, height }
|
|
48949
|
+
});
|
|
48950
|
+
editor.storage.image.media = Object.assign(editor.storage.image.media, { [mediaPath]: url });
|
|
48951
|
+
if (editor.options.ydoc) {
|
|
48952
|
+
editor.commands.addImageToCollaboration({ mediaPath, fileData: url });
|
|
48953
|
+
}
|
|
48954
|
+
view.dispatch(
|
|
48955
|
+
view.state.tr.replaceWith(placeholderPos, placeholderPos, imageNode).setMeta(ImagePlaceholderPluginKey, removeMeta)
|
|
48956
|
+
);
|
|
48957
|
+
},
|
|
48958
|
+
() => {
|
|
48959
|
+
let removeMeta = { type: "remove", id };
|
|
48960
|
+
view.dispatch(tr.setMeta(ImagePlaceholderPluginKey, removeMeta));
|
|
48961
|
+
}
|
|
48962
|
+
);
|
|
48963
|
+
};
|
|
48837
48964
|
const BookmarkStart = Node$1.create({
|
|
48838
48965
|
name: "bookmarkStart",
|
|
48839
48966
|
group: "inline",
|
|
@@ -55002,6 +55129,239 @@ const Search = Extension.create({
|
|
|
55002
55129
|
};
|
|
55003
55130
|
}
|
|
55004
55131
|
});
|
|
55132
|
+
const NodeResizerKey = new PluginKey("node-resizer");
|
|
55133
|
+
const nodeResizer = (nodeNames = ["image"]) => {
|
|
55134
|
+
let resizeState = {
|
|
55135
|
+
dragging: false,
|
|
55136
|
+
startX: 0,
|
|
55137
|
+
startY: 0,
|
|
55138
|
+
startWidth: 0,
|
|
55139
|
+
handle: null,
|
|
55140
|
+
pos: null,
|
|
55141
|
+
resizableElement: null,
|
|
55142
|
+
aspectRatio: 1
|
|
55143
|
+
};
|
|
55144
|
+
let resizeContainer = null;
|
|
55145
|
+
let editorView = null;
|
|
55146
|
+
let globalClickHandler = null;
|
|
55147
|
+
let globalMousedownHandler = null;
|
|
55148
|
+
return new Plugin({
|
|
55149
|
+
key: NodeResizerKey,
|
|
55150
|
+
state: {
|
|
55151
|
+
init() {
|
|
55152
|
+
return DecorationSet.empty;
|
|
55153
|
+
},
|
|
55154
|
+
apply(tr, oldState, _, newState) {
|
|
55155
|
+
if (tr.getMeta(NodeResizerKey)) {
|
|
55156
|
+
return oldState;
|
|
55157
|
+
}
|
|
55158
|
+
const decorations = [];
|
|
55159
|
+
const { selection } = newState;
|
|
55160
|
+
if (nodeNames.includes(selection.node?.type.name)) {
|
|
55161
|
+
decorations.push(
|
|
55162
|
+
Decoration.node(selection.from, selection.to, {
|
|
55163
|
+
nodeName: "span",
|
|
55164
|
+
class: "sd-editor-resizable-wrapper",
|
|
55165
|
+
"data-pos": selection.from
|
|
55166
|
+
})
|
|
55167
|
+
);
|
|
55168
|
+
}
|
|
55169
|
+
return DecorationSet.create(newState.doc, decorations);
|
|
55170
|
+
}
|
|
55171
|
+
},
|
|
55172
|
+
props: {
|
|
55173
|
+
decorations(state2) {
|
|
55174
|
+
return this.getState(state2);
|
|
55175
|
+
}
|
|
55176
|
+
},
|
|
55177
|
+
view(view) {
|
|
55178
|
+
editorView = view;
|
|
55179
|
+
globalClickHandler = (event) => {
|
|
55180
|
+
if (!event.target.closest(".sd-editor-resizable-wrapper") && !event.target.closest(".sd-editor-resize-container")) {
|
|
55181
|
+
hideResizeHandles();
|
|
55182
|
+
}
|
|
55183
|
+
};
|
|
55184
|
+
document.addEventListener("click", globalClickHandler);
|
|
55185
|
+
globalMousedownHandler = (event) => {
|
|
55186
|
+
if (event.target.closest(".sd-editor-resize-handle")) {
|
|
55187
|
+
event.preventDefault();
|
|
55188
|
+
event.stopPropagation();
|
|
55189
|
+
startResize(editorView, event, event.target);
|
|
55190
|
+
return true;
|
|
55191
|
+
}
|
|
55192
|
+
};
|
|
55193
|
+
document.addEventListener("mousedown", globalMousedownHandler);
|
|
55194
|
+
return {
|
|
55195
|
+
update(view2, prevState) {
|
|
55196
|
+
const { selection } = view2.state;
|
|
55197
|
+
const prevSelection = prevState.selection;
|
|
55198
|
+
if (selection.from !== prevSelection.from || selection.to !== prevSelection.to) {
|
|
55199
|
+
setTimeout(() => {
|
|
55200
|
+
const selectedResizableWrapper = document.querySelector(".sd-editor-resizable-wrapper");
|
|
55201
|
+
if (selectedResizableWrapper) {
|
|
55202
|
+
showResizeHandles(view2, selectedResizableWrapper);
|
|
55203
|
+
} else {
|
|
55204
|
+
hideResizeHandles();
|
|
55205
|
+
}
|
|
55206
|
+
}, 10);
|
|
55207
|
+
}
|
|
55208
|
+
},
|
|
55209
|
+
destroy() {
|
|
55210
|
+
hideResizeHandles();
|
|
55211
|
+
cleanupEventListeners();
|
|
55212
|
+
if (globalClickHandler) {
|
|
55213
|
+
document.removeEventListener("click", globalClickHandler);
|
|
55214
|
+
globalClickHandler = null;
|
|
55215
|
+
}
|
|
55216
|
+
if (globalMousedownHandler) {
|
|
55217
|
+
document.removeEventListener("mousedown", globalMousedownHandler);
|
|
55218
|
+
globalMousedownHandler = null;
|
|
55219
|
+
}
|
|
55220
|
+
editorView = null;
|
|
55221
|
+
}
|
|
55222
|
+
};
|
|
55223
|
+
}
|
|
55224
|
+
});
|
|
55225
|
+
function showResizeHandles(view, wrapper) {
|
|
55226
|
+
hideResizeHandles();
|
|
55227
|
+
const pos = Number.parseInt(wrapper.getAttribute("data-pos"), 10);
|
|
55228
|
+
const node2 = view.state.doc.nodeAt(pos);
|
|
55229
|
+
if (!nodeNames.includes(node2?.type.name)) return;
|
|
55230
|
+
resizeContainer = document.createElement("div");
|
|
55231
|
+
resizeContainer.className = "sd-editor-resize-container";
|
|
55232
|
+
resizeContainer.style.position = "absolute";
|
|
55233
|
+
resizeContainer.style.pointerEvents = "none";
|
|
55234
|
+
resizeContainer.style.zIndex = "1000";
|
|
55235
|
+
const handles = ["nw", "ne", "sw", "se"];
|
|
55236
|
+
for (const handle of handles) {
|
|
55237
|
+
const handleEl = document.createElement("div");
|
|
55238
|
+
handleEl.className = `sd-editor-resize-handle sd-editor-resize-handle-${handle}`;
|
|
55239
|
+
handleEl.setAttribute("data-handle", handle);
|
|
55240
|
+
handleEl.setAttribute("data-pos", pos);
|
|
55241
|
+
handleEl.style.pointerEvents = "auto";
|
|
55242
|
+
resizeContainer.appendChild(handleEl);
|
|
55243
|
+
}
|
|
55244
|
+
document.body.appendChild(resizeContainer);
|
|
55245
|
+
updateHandlePositions(wrapper.firstElementChild);
|
|
55246
|
+
}
|
|
55247
|
+
function hideResizeHandles() {
|
|
55248
|
+
if (resizeContainer?.parentNode) {
|
|
55249
|
+
resizeContainer.parentNode.removeChild(resizeContainer);
|
|
55250
|
+
resizeContainer = null;
|
|
55251
|
+
}
|
|
55252
|
+
}
|
|
55253
|
+
function updateHandlePositions(resizableElement) {
|
|
55254
|
+
if (!resizeContainer || !resizableElement) return;
|
|
55255
|
+
const rect = resizableElement.getBoundingClientRect();
|
|
55256
|
+
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
55257
|
+
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
|
55258
|
+
resizeContainer.style.left = `${rect.left + scrollLeft}px`;
|
|
55259
|
+
resizeContainer.style.top = `${rect.top + scrollTop}px`;
|
|
55260
|
+
resizeContainer.style.width = `${rect.width}px`;
|
|
55261
|
+
resizeContainer.style.height = `${rect.height}px`;
|
|
55262
|
+
}
|
|
55263
|
+
function startResize(view, event, handleElement) {
|
|
55264
|
+
if (!view.hasFocus()) return;
|
|
55265
|
+
const handle = handleElement.getAttribute("data-handle");
|
|
55266
|
+
const pos = Number.parseInt(handleElement.getAttribute("data-pos"), 10);
|
|
55267
|
+
if (view.state.selection.from !== pos || !nodeNames.includes(view.state.selection.node?.type.name)) return;
|
|
55268
|
+
const resizableElement = view.nodeDOM(pos);
|
|
55269
|
+
if (!resizableElement) return;
|
|
55270
|
+
const rect = resizableElement.getBoundingClientRect();
|
|
55271
|
+
resizeState = {
|
|
55272
|
+
dragging: true,
|
|
55273
|
+
startX: event.clientX,
|
|
55274
|
+
startY: event.clientY,
|
|
55275
|
+
startWidth: rect.width,
|
|
55276
|
+
startHeight: rect.height,
|
|
55277
|
+
handle,
|
|
55278
|
+
pos,
|
|
55279
|
+
resizableElement,
|
|
55280
|
+
aspectRatio: rect.width / rect.height
|
|
55281
|
+
};
|
|
55282
|
+
document.addEventListener("mousemove", handleMouseMove2);
|
|
55283
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
55284
|
+
document.body.style.cursor = getResizeCursor(handle);
|
|
55285
|
+
document.body.style.userSelect = "none";
|
|
55286
|
+
}
|
|
55287
|
+
function handleMouseMove2(event) {
|
|
55288
|
+
if (!resizeState.dragging) return;
|
|
55289
|
+
event.preventDefault();
|
|
55290
|
+
event.stopPropagation();
|
|
55291
|
+
let deltaX = event.clientX - resizeState.startX;
|
|
55292
|
+
event.clientY - resizeState.startY;
|
|
55293
|
+
if (resizeState.handle.includes("w")) deltaX = -deltaX;
|
|
55294
|
+
if (resizeState.handle.includes("n")) ;
|
|
55295
|
+
const newWidth = Math.max(20, resizeState.startWidth + deltaX);
|
|
55296
|
+
if (resizeState.resizableElement) {
|
|
55297
|
+
resizeState.resizableElement.style.width = `${newWidth}px`;
|
|
55298
|
+
resizeState.resizableElement.style.height = "auto";
|
|
55299
|
+
updateHandlePositions(resizeState.resizableElement);
|
|
55300
|
+
}
|
|
55301
|
+
}
|
|
55302
|
+
function handleMouseUp(event) {
|
|
55303
|
+
if (!resizeState.dragging) return;
|
|
55304
|
+
cleanupEventListeners();
|
|
55305
|
+
let deltaX = event.clientX - resizeState.startX;
|
|
55306
|
+
event.clientY - resizeState.startY;
|
|
55307
|
+
if (resizeState.handle.includes("w")) deltaX = -deltaX;
|
|
55308
|
+
if (resizeState.handle.includes("n")) ;
|
|
55309
|
+
const newWidth = Math.max(20, resizeState.startWidth + deltaX);
|
|
55310
|
+
const newHeight = newWidth / resizeState.aspectRatio;
|
|
55311
|
+
if (editorView && resizeState.pos < editorView.state.doc.content.size) {
|
|
55312
|
+
const tr = editorView.state.tr;
|
|
55313
|
+
const node2 = tr.doc.nodeAt(resizeState.pos);
|
|
55314
|
+
if (nodeNames.includes(node2?.type.name)) {
|
|
55315
|
+
const attrs = {
|
|
55316
|
+
...node2.attrs,
|
|
55317
|
+
size: {
|
|
55318
|
+
...node2.attrs.size,
|
|
55319
|
+
width: Math.round(newWidth),
|
|
55320
|
+
height: Math.round(newHeight)
|
|
55321
|
+
}
|
|
55322
|
+
};
|
|
55323
|
+
tr.setNodeMarkup(resizeState.pos, null, attrs);
|
|
55324
|
+
tr.setMeta(NodeResizerKey, { action: "resize" });
|
|
55325
|
+
editorView.dispatch(tr);
|
|
55326
|
+
}
|
|
55327
|
+
}
|
|
55328
|
+
resizeState = {
|
|
55329
|
+
dragging: false,
|
|
55330
|
+
startX: 0,
|
|
55331
|
+
startY: 0,
|
|
55332
|
+
startWidth: 0,
|
|
55333
|
+
startHeight: 0,
|
|
55334
|
+
handle: null,
|
|
55335
|
+
pos: null,
|
|
55336
|
+
resizableElement: null,
|
|
55337
|
+
aspectRatio: 1
|
|
55338
|
+
};
|
|
55339
|
+
}
|
|
55340
|
+
function cleanupEventListeners() {
|
|
55341
|
+
document.removeEventListener("mousemove", handleMouseMove2);
|
|
55342
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
55343
|
+
document.body.style.cursor = "";
|
|
55344
|
+
document.body.style.userSelect = "";
|
|
55345
|
+
}
|
|
55346
|
+
function getResizeCursor(handle) {
|
|
55347
|
+
switch (handle) {
|
|
55348
|
+
case "nw":
|
|
55349
|
+
case "se":
|
|
55350
|
+
return "nwse-resize";
|
|
55351
|
+
case "ne":
|
|
55352
|
+
case "sw":
|
|
55353
|
+
return "nesw-resize";
|
|
55354
|
+
default:
|
|
55355
|
+
return "default";
|
|
55356
|
+
}
|
|
55357
|
+
}
|
|
55358
|
+
};
|
|
55359
|
+
const NodeResizer = Extension.create({
|
|
55360
|
+
name: "nodeResizer",
|
|
55361
|
+
addPmPlugins() {
|
|
55362
|
+
return [nodeResizer(["image"])];
|
|
55363
|
+
}
|
|
55364
|
+
});
|
|
55005
55365
|
const getRichTextExtensions = () => {
|
|
55006
55366
|
return [
|
|
55007
55367
|
Bold,
|
|
@@ -55039,7 +55399,8 @@ const getRichTextExtensions = () => {
|
|
|
55039
55399
|
TrackDelete,
|
|
55040
55400
|
TrackFormat,
|
|
55041
55401
|
AiPlugin,
|
|
55042
|
-
Image
|
|
55402
|
+
Image,
|
|
55403
|
+
NodeResizer
|
|
55043
55404
|
];
|
|
55044
55405
|
};
|
|
55045
55406
|
const getStarterExtensions = () => {
|
|
@@ -55103,7 +55464,8 @@ const getStarterExtensions = () => {
|
|
|
55103
55464
|
ShapeTextbox,
|
|
55104
55465
|
ContentBlock,
|
|
55105
55466
|
Search,
|
|
55106
|
-
StructuredContent
|
|
55467
|
+
StructuredContent,
|
|
55468
|
+
NodeResizer
|
|
55107
55469
|
];
|
|
55108
55470
|
};
|
|
55109
55471
|
const sanitizeNumber = (value, defaultNumber) => {
|
|
@@ -67813,140 +68175,6 @@ const makeDefaultItems = ({
|
|
|
67813
68175
|
overflowItems: overflowItems.filter((item) => item.type !== "separator")
|
|
67814
68176
|
};
|
|
67815
68177
|
};
|
|
67816
|
-
const ACCEPT_IMAGE_TYPES = [".jpg", ".jpeg", ".png", "image/jpeg", "image/png"];
|
|
67817
|
-
const getFileOpener = () => {
|
|
67818
|
-
let fileInput = document.createElement("input");
|
|
67819
|
-
fileInput.type = "file";
|
|
67820
|
-
let acceptTypes = ACCEPT_IMAGE_TYPES;
|
|
67821
|
-
fileInput.accept = acceptTypes.join(",");
|
|
67822
|
-
const openFile = () => {
|
|
67823
|
-
return new Promise((resolve, reject) => {
|
|
67824
|
-
fileInput.onchange = async () => {
|
|
67825
|
-
const files = fileInput.files;
|
|
67826
|
-
if (!files) return resolve(null);
|
|
67827
|
-
const file = files.item(0);
|
|
67828
|
-
if (!file) return resolve(null);
|
|
67829
|
-
return resolve({ file });
|
|
67830
|
-
};
|
|
67831
|
-
fileInput.oncancel = () => resolve(null);
|
|
67832
|
-
fileInput.onerror = reject;
|
|
67833
|
-
fileInput.click();
|
|
67834
|
-
});
|
|
67835
|
-
};
|
|
67836
|
-
return openFile;
|
|
67837
|
-
};
|
|
67838
|
-
const handleImageUpload = (file) => {
|
|
67839
|
-
return new Promise((resolve, reject) => {
|
|
67840
|
-
let reader = new FileReader();
|
|
67841
|
-
reader.onload = (event) => resolve(event.target.result);
|
|
67842
|
-
reader.onerror = reject;
|
|
67843
|
-
setTimeout(() => reader.readAsDataURL(file), 250);
|
|
67844
|
-
});
|
|
67845
|
-
};
|
|
67846
|
-
const processUploadedImage = (fileData, editor) => {
|
|
67847
|
-
return new Promise((resolve, reject) => {
|
|
67848
|
-
const img = new window.Image();
|
|
67849
|
-
img.onload = () => {
|
|
67850
|
-
const canvas = document.createElement("canvas");
|
|
67851
|
-
const { width, height } = getAllowedImageDimensions(
|
|
67852
|
-
img.width,
|
|
67853
|
-
img.height,
|
|
67854
|
-
editor
|
|
67855
|
-
);
|
|
67856
|
-
canvas.width = width;
|
|
67857
|
-
canvas.height = height;
|
|
67858
|
-
const ctx2 = canvas.getContext("2d");
|
|
67859
|
-
ctx2.drawImage(img, 0, 0, width, height);
|
|
67860
|
-
if (typeof fileData === "string") {
|
|
67861
|
-
const resizedBase64 = canvas.toDataURL();
|
|
67862
|
-
resolve(resizedBase64);
|
|
67863
|
-
} else {
|
|
67864
|
-
canvas.toBlob((blob) => {
|
|
67865
|
-
const updatedFile = new File([blob], fileData.name, {
|
|
67866
|
-
type: fileData.type,
|
|
67867
|
-
lastModified: Date.now()
|
|
67868
|
-
});
|
|
67869
|
-
resolve({ file: updatedFile, width, height });
|
|
67870
|
-
});
|
|
67871
|
-
}
|
|
67872
|
-
};
|
|
67873
|
-
img.onerror = (error) => reject(error);
|
|
67874
|
-
img.src = typeof fileData === "string" ? fileData : URL.createObjectURL(fileData);
|
|
67875
|
-
});
|
|
67876
|
-
};
|
|
67877
|
-
const getAllowedImageDimensions = (width, height, editor) => {
|
|
67878
|
-
const { width: maxWidth, height: maxHeight } = editor.getMaxContentSize();
|
|
67879
|
-
if (!maxWidth || !maxHeight) return { width, height };
|
|
67880
|
-
let adjustedWidth = width;
|
|
67881
|
-
let adjustedHeight = height;
|
|
67882
|
-
const aspectRatio = width / height;
|
|
67883
|
-
if (height > maxHeight) {
|
|
67884
|
-
adjustedHeight = maxHeight;
|
|
67885
|
-
adjustedWidth = Math.round(maxHeight * aspectRatio);
|
|
67886
|
-
}
|
|
67887
|
-
if (adjustedWidth > maxWidth) {
|
|
67888
|
-
adjustedWidth = maxWidth;
|
|
67889
|
-
adjustedHeight = Math.round(maxWidth / aspectRatio);
|
|
67890
|
-
}
|
|
67891
|
-
return { width: adjustedWidth, height: adjustedHeight };
|
|
67892
|
-
};
|
|
67893
|
-
const startImageUpload = async ({ editor, view, file }) => {
|
|
67894
|
-
let imageUploadHandler = typeof editor.options.handleImageUpload === "function" ? editor.options.handleImageUpload : handleImageUpload;
|
|
67895
|
-
let fileSizeMb = (file.size / (1024 * 1024)).toFixed(4);
|
|
67896
|
-
if (fileSizeMb > 5) {
|
|
67897
|
-
window.alert("Image size must be less than 5MB");
|
|
67898
|
-
return;
|
|
67899
|
-
}
|
|
67900
|
-
let width;
|
|
67901
|
-
let height;
|
|
67902
|
-
try {
|
|
67903
|
-
const processedImageResult = await processUploadedImage(file, editor);
|
|
67904
|
-
width = processedImageResult.width;
|
|
67905
|
-
height = processedImageResult.height;
|
|
67906
|
-
file = processedImageResult.file;
|
|
67907
|
-
} catch (err) {
|
|
67908
|
-
console.warn("Error processing image:", err);
|
|
67909
|
-
return;
|
|
67910
|
-
}
|
|
67911
|
-
let id = {};
|
|
67912
|
-
let { tr, schema } = view.state;
|
|
67913
|
-
if (!tr.selection.empty) {
|
|
67914
|
-
tr.deleteSelection();
|
|
67915
|
-
}
|
|
67916
|
-
let imageMeta = {
|
|
67917
|
-
type: "add",
|
|
67918
|
-
pos: tr.selection.from,
|
|
67919
|
-
id
|
|
67920
|
-
};
|
|
67921
|
-
tr.setMeta(ImagePlaceholderPluginKey, imageMeta);
|
|
67922
|
-
view.dispatch(tr);
|
|
67923
|
-
imageUploadHandler(file).then(
|
|
67924
|
-
(url) => {
|
|
67925
|
-
let fileName = file.name.replace(" ", "_");
|
|
67926
|
-
let placeholderPos = findPlaceholder(view.state, id);
|
|
67927
|
-
if (placeholderPos == null) {
|
|
67928
|
-
return;
|
|
67929
|
-
}
|
|
67930
|
-
let removeMeta = { type: "remove", id };
|
|
67931
|
-
let mediaPath = `word/media/${fileName}`;
|
|
67932
|
-
let imageNode = schema.nodes.image.create({
|
|
67933
|
-
src: mediaPath,
|
|
67934
|
-
size: { width, height }
|
|
67935
|
-
});
|
|
67936
|
-
editor.storage.image.media = Object.assign(editor.storage.image.media, { [mediaPath]: url });
|
|
67937
|
-
if (editor.options.ydoc) {
|
|
67938
|
-
editor.commands.addImageToCollaboration({ mediaPath, fileData: url });
|
|
67939
|
-
}
|
|
67940
|
-
view.dispatch(
|
|
67941
|
-
view.state.tr.replaceWith(placeholderPos, placeholderPos, imageNode).setMeta(ImagePlaceholderPluginKey, removeMeta)
|
|
67942
|
-
);
|
|
67943
|
-
},
|
|
67944
|
-
() => {
|
|
67945
|
-
let removeMeta = { type: "remove", id };
|
|
67946
|
-
view.dispatch(tr.setMeta(ImagePlaceholderPluginKey, removeMeta));
|
|
67947
|
-
}
|
|
67948
|
-
);
|
|
67949
|
-
};
|
|
67950
68178
|
const toolbarTexts = {
|
|
67951
68179
|
bold: "Bold",
|
|
67952
68180
|
fontFamily: "Font",
|