@limetech/lime-elements 38.11.1 → 38.12.1
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/CHANGELOG.md +16 -0
- package/dist/cjs/index.cjs.js +0 -9
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/limel-ai-avatar.cjs.entry.js +1 -1
- package/dist/cjs/limel-ai-avatar.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +209 -111
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-text-editor.cjs.entry.js +7 -1
- package/dist/cjs/limel-text-editor.cjs.entry.js.map +1 -1
- package/dist/collection/components/ai-avatar/ai-avatar.css +1 -3
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/inserter.js +15 -54
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/inserter.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/node.js +51 -43
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/node.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/view.js +10 -12
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/view.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/link-plugin.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +51 -5
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map +1 -1
- package/dist/collection/components/text-editor/text-editor.js +38 -4
- package/dist/collection/components/text-editor/text-editor.js.map +1 -1
- package/dist/collection/components/text-editor/text-editor.types.js +1 -9
- package/dist/collection/components/text-editor/text-editor.types.js.map +1 -1
- package/dist/collection/components/text-editor/utils/metadata-utils.js +108 -0
- package/dist/collection/components/text-editor/utils/metadata-utils.js.map +1 -0
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/limel-ai-avatar.entry.js +1 -1
- package/dist/esm/limel-ai-avatar.entry.js.map +1 -1
- package/dist/esm/limel-prosemirror-adapter.entry.js +209 -111
- package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
- package/dist/esm/limel-text-editor.entry.js +7 -1
- package/dist/esm/limel-text-editor.entry.js.map +1 -1
- package/dist/lime-elements/index.esm.js +1 -1
- package/dist/lime-elements/index.esm.js.map +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/p-7b039dab.entry.js +2 -0
- package/dist/lime-elements/p-7b039dab.entry.js.map +1 -0
- package/dist/lime-elements/{p-033fa919.entry.js → p-7f3045bd.entry.js} +2 -2
- package/dist/lime-elements/p-7f3045bd.entry.js.map +1 -0
- package/dist/lime-elements/p-f20b7faa.entry.js +2 -0
- package/dist/lime-elements/p-f20b7faa.entry.js.map +1 -0
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/image/inserter.d.ts +2 -7
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/image/node.d.ts +9 -0
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/link-plugin.d.ts +0 -4
- package/dist/types/components/text-editor/prosemirror-adapter/prosemirror-adapter.d.ts +10 -0
- package/dist/types/components/text-editor/text-editor.d.ts +10 -0
- package/dist/types/components/text-editor/text-editor.types.d.ts +32 -7
- package/dist/types/components/text-editor/utils/metadata-utils.d.ts +22 -0
- package/dist/types/components.d.ts +17 -4
- package/package.json +1 -1
- package/dist/cjs/text-editor.types-5e5567e2.js +0 -13
- package/dist/cjs/text-editor.types-5e5567e2.js.map +0 -1
- package/dist/esm/text-editor.types-e82469d1.js +0 -13
- package/dist/esm/text-editor.types-e82469d1.js.map +0 -1
- package/dist/lime-elements/p-033fa919.entry.js.map +0 -1
- package/dist/lime-elements/p-7006fafe.entry.js +0 -2
- package/dist/lime-elements/p-7006fafe.entry.js.map +0 -1
- package/dist/lime-elements/p-9ca516ed.js +0 -2
- package/dist/lime-elements/p-9ca516ed.js.map +0 -1
- package/dist/lime-elements/p-b7c52564.entry.js +0 -2
- package/dist/lime-elements/p-b7c52564.entry.js.map +0 -1
|
@@ -9,7 +9,6 @@ import { g as getPrototype } from './_getPrototype-8096728a.js';
|
|
|
9
9
|
import { i as isArray } from './isArray-80298bc7.js';
|
|
10
10
|
import { i as isObjectLike } from './isObjectLike-38996507.js';
|
|
11
11
|
import { d as decodeHTML, m as markdownToHTML, s as sanitizeHTML } from './markdown-parser-47476fc0.js';
|
|
12
|
-
import { I as ImageState } from './text-editor.types-e82469d1.js';
|
|
13
12
|
import { t as translate$1 } from './translations-489f20b3.js';
|
|
14
13
|
import { c as createRandomString } from './random-string-e74dc48d.js';
|
|
15
14
|
import { i as isItem } from './isItem-b0459122.js';
|
|
@@ -25929,39 +25928,38 @@ function hasImageNode(node) {
|
|
|
25929
25928
|
return false;
|
|
25930
25929
|
}
|
|
25931
25930
|
function createImageNodeMarkdownSerializer(language) {
|
|
25932
|
-
return (
|
|
25933
|
-
|
|
25934
|
-
|
|
25935
|
-
filename: node.attrs.alt || 'file',
|
|
25936
|
-
});
|
|
25937
|
-
state.write(`<span>${text}</span>`);
|
|
25931
|
+
return (markdownSerializerState, node) => {
|
|
25932
|
+
const { state, alt, src, width, maxWidth } = node.attrs;
|
|
25933
|
+
if (!isEditorImageState(state)) {
|
|
25938
25934
|
return;
|
|
25939
25935
|
}
|
|
25940
|
-
|
|
25941
|
-
const
|
|
25942
|
-
|
|
25943
|
-
});
|
|
25944
|
-
state.write(`<span>${text}</span>`);
|
|
25936
|
+
if (state === 'success') {
|
|
25937
|
+
const imageHTML = getImageHTML(src, alt, width, maxWidth);
|
|
25938
|
+
markdownSerializerState.write(imageHTML);
|
|
25945
25939
|
return;
|
|
25946
25940
|
}
|
|
25947
|
-
|
|
25948
|
-
|
|
25949
|
-
imageHTML += ` alt="${node.attrs.alt}"`;
|
|
25950
|
-
}
|
|
25951
|
-
const style = [];
|
|
25952
|
-
if (node.attrs.width) {
|
|
25953
|
-
style.push(`width: ${node.attrs.width};`);
|
|
25954
|
-
}
|
|
25955
|
-
if (node.attrs.maxWidth) {
|
|
25956
|
-
style.push(`max-width: ${node.attrs.maxWidth};`);
|
|
25957
|
-
}
|
|
25958
|
-
if (style.length > 0) {
|
|
25959
|
-
imageHTML += ` style="${style.join(' ')}"`;
|
|
25960
|
-
}
|
|
25961
|
-
imageHTML += ' />';
|
|
25962
|
-
state.write(imageHTML);
|
|
25941
|
+
const statusHTML = getStatusHTML(state, alt, language);
|
|
25942
|
+
markdownSerializerState.write(statusHTML);
|
|
25963
25943
|
};
|
|
25964
25944
|
}
|
|
25945
|
+
function getStatusHTML(state, alt, language) {
|
|
25946
|
+
const key = state === 'failed' ? 'failed' : 'loading';
|
|
25947
|
+
const text = translate$1.get(`editor-image-view.${key}`, language, {
|
|
25948
|
+
filename: alt || 'file',
|
|
25949
|
+
});
|
|
25950
|
+
return `<span>${text}</span>`;
|
|
25951
|
+
}
|
|
25952
|
+
function getImageHTML(src, alt, width, maxWidth) {
|
|
25953
|
+
const style = [];
|
|
25954
|
+
if (width) {
|
|
25955
|
+
style.push(`width: ${width};`);
|
|
25956
|
+
}
|
|
25957
|
+
if (maxWidth) {
|
|
25958
|
+
style.push(`max-width: ${maxWidth};`);
|
|
25959
|
+
}
|
|
25960
|
+
const styleAttribute = style.length > 0 ? ` style="${style.join(' ')}"` : '';
|
|
25961
|
+
return `<img src="${src}" alt="${alt}"${styleAttribute} />`;
|
|
25962
|
+
}
|
|
25965
25963
|
function createImageNodeSpec(language) {
|
|
25966
25964
|
return {
|
|
25967
25965
|
group: 'inline',
|
|
@@ -25972,24 +25970,16 @@ function createImageNodeSpec(language) {
|
|
|
25972
25970
|
fileInfoId: { default: '' },
|
|
25973
25971
|
width: { default: '' },
|
|
25974
25972
|
maxWidth: { default: '100%' },
|
|
25975
|
-
state: { default: '' },
|
|
25973
|
+
state: { default: 'success' },
|
|
25976
25974
|
},
|
|
25977
25975
|
toDOM: (node) => {
|
|
25978
|
-
if (node.attrs.state
|
|
25979
|
-
return
|
|
25980
|
-
}
|
|
25981
|
-
else if (node.attrs.state === ImageState.LOADING) {
|
|
25982
|
-
return createStatusSpan('loading', node, language);
|
|
25983
|
-
}
|
|
25984
|
-
let img = imageCache.get(node.attrs.fileInfoId);
|
|
25985
|
-
if (img) {
|
|
25986
|
-
updateImageElement(img, node);
|
|
25976
|
+
if (!isEditorImageState(node.attrs.state)) {
|
|
25977
|
+
return;
|
|
25987
25978
|
}
|
|
25988
|
-
|
|
25989
|
-
|
|
25990
|
-
imageCache.set(node.attrs.fileInfoId, img);
|
|
25979
|
+
if (node.attrs.state === 'success') {
|
|
25980
|
+
return getOrCreateImageElement(node.attrs.fileInfoId, node);
|
|
25991
25981
|
}
|
|
25992
|
-
return
|
|
25982
|
+
return createStatusSpanForState(node.attrs.state, node, language);
|
|
25993
25983
|
},
|
|
25994
25984
|
parseDOM: [
|
|
25995
25985
|
{
|
|
@@ -26000,7 +25990,7 @@ function createImageNodeSpec(language) {
|
|
|
26000
25990
|
alt: dom.getAttribute('alt') || 'file',
|
|
26001
25991
|
width: dom.style.width || '',
|
|
26002
25992
|
maxWidth: '100%',
|
|
26003
|
-
state:
|
|
25993
|
+
state: 'success',
|
|
26004
25994
|
fileInfoId: crypto.randomUUID(),
|
|
26005
25995
|
};
|
|
26006
25996
|
},
|
|
@@ -26008,6 +25998,24 @@ function createImageNodeSpec(language) {
|
|
|
26008
25998
|
],
|
|
26009
25999
|
};
|
|
26010
26000
|
}
|
|
26001
|
+
function isEditorImageState(state) {
|
|
26002
|
+
return state === 'loading' || state === 'failed' || state === 'success';
|
|
26003
|
+
}
|
|
26004
|
+
function getOrCreateImageElement(fileInfoId, node) {
|
|
26005
|
+
let img = imageCache.get(fileInfoId);
|
|
26006
|
+
if (img) {
|
|
26007
|
+
updateImageElement(img, node);
|
|
26008
|
+
}
|
|
26009
|
+
else {
|
|
26010
|
+
img = createImageElement(node);
|
|
26011
|
+
imageCache.set(fileInfoId, img);
|
|
26012
|
+
}
|
|
26013
|
+
return img;
|
|
26014
|
+
}
|
|
26015
|
+
function createStatusSpanForState(state, node, language) {
|
|
26016
|
+
const statusKey = state === 'failed' ? 'failed' : 'loading';
|
|
26017
|
+
return createStatusSpan(statusKey, node, language);
|
|
26018
|
+
}
|
|
26011
26019
|
function createStatusSpan(key, node, language) {
|
|
26012
26020
|
const text = translate$1.get(`editor-image-view.${key}`, language, {
|
|
26013
26021
|
filename: node.attrs.alt || 'file',
|
|
@@ -26299,7 +26307,7 @@ const createLinkPlugin = (updateLinkCallback) => {
|
|
|
26299
26307
|
};
|
|
26300
26308
|
|
|
26301
26309
|
const pluginKey = new PluginKey('imageInserterPlugin');
|
|
26302
|
-
const createImageInserterPlugin = (imagePastedCallback
|
|
26310
|
+
const createImageInserterPlugin = (imagePastedCallback) => {
|
|
26303
26311
|
return new Plugin({
|
|
26304
26312
|
key: pluginKey,
|
|
26305
26313
|
props: {
|
|
@@ -26312,40 +26320,7 @@ const createImageInserterPlugin = (imagePastedCallback, imageRemovedCallback) =>
|
|
|
26312
26320
|
},
|
|
26313
26321
|
},
|
|
26314
26322
|
},
|
|
26315
|
-
state: {
|
|
26316
|
-
init: () => {
|
|
26317
|
-
return { insertedImages: {} };
|
|
26318
|
-
},
|
|
26319
|
-
apply: (tr, pluginState) => {
|
|
26320
|
-
const newState = Object.assign({}, pluginState);
|
|
26321
|
-
newState.insertedImages = getImagesFromTransaction(tr);
|
|
26322
|
-
findAndHandleRemovedImages(imageRemovedCallback, pluginState.insertedImages, newState.insertedImages);
|
|
26323
|
-
return newState;
|
|
26324
|
-
},
|
|
26325
|
-
},
|
|
26326
|
-
});
|
|
26327
|
-
};
|
|
26328
|
-
const getImagesFromTransaction = (tr) => {
|
|
26329
|
-
const images = {};
|
|
26330
|
-
tr.doc.descendants((node) => {
|
|
26331
|
-
if (node.type.name === 'image') {
|
|
26332
|
-
images[node.attrs.fileInfoId] = node;
|
|
26333
|
-
}
|
|
26334
26323
|
});
|
|
26335
|
-
return images;
|
|
26336
|
-
};
|
|
26337
|
-
const findAndHandleRemovedImages = (imageRemovedCallback, previousImages, newImages) => {
|
|
26338
|
-
const removedKeys = Object.keys(previousImages).filter((key) => !(key in newImages));
|
|
26339
|
-
for (const removedKey of removedKeys) {
|
|
26340
|
-
const removedImage = previousImages[removedKey];
|
|
26341
|
-
const imageInfo = {
|
|
26342
|
-
fileInfoId: removedImage.attrs.fileInfoId,
|
|
26343
|
-
src: removedImage.attrs.src,
|
|
26344
|
-
state: removedImage.attrs.state,
|
|
26345
|
-
};
|
|
26346
|
-
imageRemovedCallback(imageInfo);
|
|
26347
|
-
imageCache.delete(removedImage.attrs.fileInfoId);
|
|
26348
|
-
}
|
|
26349
26324
|
};
|
|
26350
26325
|
const imageInserterFactory = (view, base64Data, fileInfo) => {
|
|
26351
26326
|
return {
|
|
@@ -26358,12 +26333,8 @@ const imageInserterFactory = (view, base64Data, fileInfo) => {
|
|
|
26358
26333
|
const createThumbnailInserter = (view, base64Data, fileInfo) => () => {
|
|
26359
26334
|
const { state, dispatch } = view;
|
|
26360
26335
|
const { schema } = state;
|
|
26361
|
-
const
|
|
26362
|
-
|
|
26363
|
-
alt: fileInfo.filename,
|
|
26364
|
-
fileInfoId: fileInfo.id,
|
|
26365
|
-
state: ImageState.LOADING,
|
|
26366
|
-
});
|
|
26336
|
+
const imageNodeAttrs = createImageNodeAttrs(base64Data, fileInfo, 'loading');
|
|
26337
|
+
const placeholderNode = schema.nodes.image.create(imageNodeAttrs);
|
|
26367
26338
|
const transaction = state.tr.replaceSelectionWith(placeholderNode);
|
|
26368
26339
|
dispatch(transaction);
|
|
26369
26340
|
};
|
|
@@ -26373,12 +26344,8 @@ const createImageInserter = (view, fileInfo) => (src) => {
|
|
|
26373
26344
|
const tr = state.tr;
|
|
26374
26345
|
state.doc.descendants((node, pos) => {
|
|
26375
26346
|
if (node.attrs.fileInfoId === fileInfo.id) {
|
|
26376
|
-
const
|
|
26377
|
-
|
|
26378
|
-
alt: fileInfo.filename,
|
|
26379
|
-
fileInfoId: fileInfo.id,
|
|
26380
|
-
state: ImageState.SUCCESS,
|
|
26381
|
-
});
|
|
26347
|
+
const imageNodeAttrs = createImageNodeAttrs(src ? src : node.attrs.src, fileInfo, 'success');
|
|
26348
|
+
const imageNode = schema.nodes.image.create(imageNodeAttrs);
|
|
26382
26349
|
tr.replaceWith(pos, pos + node.nodeSize, imageNode);
|
|
26383
26350
|
return false;
|
|
26384
26351
|
}
|
|
@@ -26391,31 +26358,35 @@ const createFailedThumbnailInserter = (view, fileInfo) => () => {
|
|
|
26391
26358
|
const tr = state.tr;
|
|
26392
26359
|
state.doc.descendants((node, pos) => {
|
|
26393
26360
|
if (node.attrs.fileInfoId === fileInfo.id) {
|
|
26394
|
-
const
|
|
26395
|
-
|
|
26396
|
-
alt: fileInfo.filename,
|
|
26397
|
-
fileInfoId: fileInfo.id,
|
|
26398
|
-
state: ImageState.FAILED,
|
|
26399
|
-
});
|
|
26361
|
+
const imageNodeAttrs = createImageNodeAttrs(node.attrs.src, fileInfo, 'failed');
|
|
26362
|
+
const errorPlaceholderNode = schema.nodes.image.create(imageNodeAttrs);
|
|
26400
26363
|
tr.replaceWith(pos, pos + node.nodeSize, errorPlaceholderNode);
|
|
26401
26364
|
return false;
|
|
26402
26365
|
}
|
|
26403
26366
|
});
|
|
26404
26367
|
dispatch(tr);
|
|
26405
26368
|
};
|
|
26369
|
+
function createImageNodeAttrs(src, fileInfo, state) {
|
|
26370
|
+
return {
|
|
26371
|
+
src: src,
|
|
26372
|
+
alt: fileInfo.filename,
|
|
26373
|
+
fileInfoId: fileInfo.id,
|
|
26374
|
+
state: state,
|
|
26375
|
+
};
|
|
26376
|
+
}
|
|
26406
26377
|
/**
|
|
26407
26378
|
* Check if a given ProseMirror node or fragment contains any image nodes.
|
|
26408
26379
|
* @param node - The ProseMirror node or fragment to check.
|
|
26409
26380
|
* @returns A boolean indicating whether the node contains any image nodes.
|
|
26410
26381
|
*/
|
|
26411
|
-
const isImageNode = (node) => {
|
|
26382
|
+
const isImageNode$1 = (node) => {
|
|
26412
26383
|
if (node instanceof Node$1) {
|
|
26413
26384
|
if (node.type.name === 'image') {
|
|
26414
26385
|
return true;
|
|
26415
26386
|
}
|
|
26416
26387
|
let found = false;
|
|
26417
26388
|
node.content.forEach((child) => {
|
|
26418
|
-
if (isImageNode(child)) {
|
|
26389
|
+
if (isImageNode$1(child)) {
|
|
26419
26390
|
found = true;
|
|
26420
26391
|
}
|
|
26421
26392
|
});
|
|
@@ -26424,7 +26395,7 @@ const isImageNode = (node) => {
|
|
|
26424
26395
|
else if (node instanceof Fragment) {
|
|
26425
26396
|
let found = false;
|
|
26426
26397
|
node.forEach((child) => {
|
|
26427
|
-
if (isImageNode(child)) {
|
|
26398
|
+
if (isImageNode$1(child)) {
|
|
26428
26399
|
found = true;
|
|
26429
26400
|
}
|
|
26430
26401
|
});
|
|
@@ -26440,7 +26411,7 @@ const isImageNode = (node) => {
|
|
|
26440
26411
|
const filterImageNodes = (fragment) => {
|
|
26441
26412
|
const filteredChildren = [];
|
|
26442
26413
|
fragment.forEach((child) => {
|
|
26443
|
-
if (!isImageNode(child)) {
|
|
26414
|
+
if (!isImageNode$1(child)) {
|
|
26444
26415
|
if (child.content.size > 0) {
|
|
26445
26416
|
const filteredContent = filterImageNodes(child.content);
|
|
26446
26417
|
const newNode = child.copy(filteredContent);
|
|
@@ -26579,21 +26550,20 @@ class ImageView {
|
|
|
26579
26550
|
});
|
|
26580
26551
|
};
|
|
26581
26552
|
this.transitionBetweenStates = () => {
|
|
26553
|
+
var _a;
|
|
26582
26554
|
this.cleanUpPreviousState();
|
|
26583
26555
|
this.dom.className = `image-wrapper state-${this.node.attrs.state}`;
|
|
26584
|
-
|
|
26585
|
-
this.createLoadingState
|
|
26586
|
-
|
|
26587
|
-
|
|
26588
|
-
|
|
26589
|
-
|
|
26590
|
-
|
|
26591
|
-
this.createFailedState();
|
|
26592
|
-
}
|
|
26556
|
+
const stateHandlers = {
|
|
26557
|
+
loading: this.createLoadingState,
|
|
26558
|
+
success: this.createSuccessState,
|
|
26559
|
+
failed: this.createFailedState,
|
|
26560
|
+
};
|
|
26561
|
+
const state = this.node.attrs.state;
|
|
26562
|
+
(_a = stateHandlers[state]) === null || _a === void 0 ? void 0 : _a.call(stateHandlers);
|
|
26593
26563
|
};
|
|
26594
26564
|
this.transitioningBetweenSuccessStates = (newNode) => {
|
|
26595
|
-
return (this.node.attrs.state ===
|
|
26596
|
-
newNode.attrs.state ===
|
|
26565
|
+
return (this.node.attrs.state === 'success' &&
|
|
26566
|
+
newNode.attrs.state === 'success');
|
|
26597
26567
|
};
|
|
26598
26568
|
this.node = node;
|
|
26599
26569
|
this.view = view;
|
|
@@ -28316,6 +28286,114 @@ const getTableNodes = () => {
|
|
|
28316
28286
|
});
|
|
28317
28287
|
};
|
|
28318
28288
|
|
|
28289
|
+
/**
|
|
28290
|
+
* Extracts metadata from a ProseMirror document node
|
|
28291
|
+
*
|
|
28292
|
+
* This function traverses the entire document tree and collects information about
|
|
28293
|
+
* special elements like images and links.
|
|
28294
|
+
*
|
|
28295
|
+
* @param doc - The ProseMirror document node to extract metadata from
|
|
28296
|
+
* @returns A metadata object containing arrays of images and links found in the document
|
|
28297
|
+
*/
|
|
28298
|
+
function getMetadataFromDoc(doc) {
|
|
28299
|
+
const metadata = { images: [], links: [] };
|
|
28300
|
+
doc.descendants((node) => {
|
|
28301
|
+
if (isImageNode(node)) {
|
|
28302
|
+
metadata.images.push(extractImageMetadata(node));
|
|
28303
|
+
}
|
|
28304
|
+
else if (isTextNodeWithMarks(node)) {
|
|
28305
|
+
extractLinkMetadata(node).forEach((link) => metadata.links.push(link));
|
|
28306
|
+
}
|
|
28307
|
+
return true;
|
|
28308
|
+
});
|
|
28309
|
+
return metadata;
|
|
28310
|
+
}
|
|
28311
|
+
function isImageNode(node) {
|
|
28312
|
+
return node.type.name === 'image' && !!node.attrs;
|
|
28313
|
+
}
|
|
28314
|
+
function extractImageMetadata(node) {
|
|
28315
|
+
return {
|
|
28316
|
+
src: node.attrs.src,
|
|
28317
|
+
state: node.attrs.state,
|
|
28318
|
+
fileInfoId: node.attrs.fileInfoId,
|
|
28319
|
+
};
|
|
28320
|
+
}
|
|
28321
|
+
function isTextNodeWithMarks(node) {
|
|
28322
|
+
var _a;
|
|
28323
|
+
return node.isText && ((_a = node.marks) === null || _a === void 0 ? void 0 : _a.length) > 0;
|
|
28324
|
+
}
|
|
28325
|
+
function extractLinkMetadata(node) {
|
|
28326
|
+
return node.marks
|
|
28327
|
+
.filter((mark) => mark.type.name === 'link' && mark.attrs)
|
|
28328
|
+
.map((mark) => ({
|
|
28329
|
+
href: mark.attrs.href,
|
|
28330
|
+
text: node.text,
|
|
28331
|
+
}));
|
|
28332
|
+
}
|
|
28333
|
+
/**
|
|
28334
|
+
* Determines if metadata has changed between two states
|
|
28335
|
+
* Handles duplicates correctly but is order-insensitive
|
|
28336
|
+
*
|
|
28337
|
+
* @param oldMetadata - The previous metadata state to compare against
|
|
28338
|
+
* @param newMetadata - The current metadata state
|
|
28339
|
+
* @returns True if there are any differences between the metadata objects, false otherwise
|
|
28340
|
+
*/
|
|
28341
|
+
function hasMetadataChanged(oldMetadata, newMetadata) {
|
|
28342
|
+
return (hasDifferentLengths(oldMetadata, newMetadata) ||
|
|
28343
|
+
hasDifferentLinks(oldMetadata.links, newMetadata.links) ||
|
|
28344
|
+
hasDifferentImages(oldMetadata.images, newMetadata.images));
|
|
28345
|
+
}
|
|
28346
|
+
function hasDifferentLengths(oldMetadata, newMetadata) {
|
|
28347
|
+
return (oldMetadata.images.length !== newMetadata.images.length ||
|
|
28348
|
+
oldMetadata.links.length !== newMetadata.links.length);
|
|
28349
|
+
}
|
|
28350
|
+
function hasDifferentLinks(oldLinks, newLinks) {
|
|
28351
|
+
const oldLinkCounts = getLinkFrequencyMap(oldLinks);
|
|
28352
|
+
const newLinkCounts = getLinkFrequencyMap(newLinks);
|
|
28353
|
+
return !areFrequencyMapsEqual(oldLinkCounts, newLinkCounts);
|
|
28354
|
+
}
|
|
28355
|
+
function hasDifferentImages(oldImages, newImages) {
|
|
28356
|
+
const oldImageCounts = getImageFrequencyMap(oldImages);
|
|
28357
|
+
const newImageCounts = getImageFrequencyMap(newImages);
|
|
28358
|
+
return !areFrequencyMapsEqual(oldImageCounts, newImageCounts);
|
|
28359
|
+
}
|
|
28360
|
+
/**
|
|
28361
|
+
* Creates a frequency map for images based on their key properties
|
|
28362
|
+
*/
|
|
28363
|
+
function getImageFrequencyMap(images) {
|
|
28364
|
+
const countMap = new Map();
|
|
28365
|
+
images.forEach((image) => {
|
|
28366
|
+
const key = `${image.fileInfoId}|${image.state}|${image.src}`;
|
|
28367
|
+
countMap.set(key, (countMap.get(key) || 0) + 1);
|
|
28368
|
+
});
|
|
28369
|
+
return countMap;
|
|
28370
|
+
}
|
|
28371
|
+
/**
|
|
28372
|
+
* Creates a frequency map for links based on their key properties
|
|
28373
|
+
*/
|
|
28374
|
+
function getLinkFrequencyMap(links) {
|
|
28375
|
+
const countMap = new Map();
|
|
28376
|
+
links.forEach((link) => {
|
|
28377
|
+
const key = `${link.href}|${link.text}`;
|
|
28378
|
+
countMap.set(key, (countMap.get(key) || 0) + 1);
|
|
28379
|
+
});
|
|
28380
|
+
return countMap;
|
|
28381
|
+
}
|
|
28382
|
+
/**
|
|
28383
|
+
* Compares two frequency maps for equality
|
|
28384
|
+
*/
|
|
28385
|
+
function areFrequencyMapsEqual(map1, map2) {
|
|
28386
|
+
if (map1.size !== map2.size) {
|
|
28387
|
+
return false;
|
|
28388
|
+
}
|
|
28389
|
+
for (const [key, count] of map1.entries()) {
|
|
28390
|
+
if (map2.get(key) !== count) {
|
|
28391
|
+
return false;
|
|
28392
|
+
}
|
|
28393
|
+
}
|
|
28394
|
+
return true;
|
|
28395
|
+
}
|
|
28396
|
+
|
|
28319
28397
|
const prosemirrorAdapterCss = "@charset \"UTF-8\";:host{--mdc-theme-primary:var(\n --lime-primary-color,\n rgb(var(--color-teal-default))\n );--mdc-theme-secondary:var(\n --lime-secondary-color,\n rgb(var(--contrast-1100))\n );--mdc-theme-on-primary:var(\n --lime-on-primary-color,\n rgb(var(--contrast-100))\n );--mdc-theme-on-secondary:var(\n --lime-on-secondary-color,\n rgb(var(--contrast-100))\n );--mdc-theme-text-disabled-on-background:var(\n --lime-text-disabled-on-background-color,\n rgba(var(--contrast-1700), 0.38)\n );--mdc-theme-text-primary-on-background:var(\n --lime-text-primary-on-background-color,\n rgba(var(--contrast-1700), 0.87)\n );--mdc-theme-text-secondary-on-background:var(\n --lime-text-secondary-on-background-color,\n rgba(var(--contrast-1700), 0.54)\n );--mdc-theme-error:var(\n --lime-error-background-color,\n rgb(var(--color-red-dark))\n );--lime-error-text-color:rgb(var(--color-red-darker));--mdc-theme-surface:var(\n --lime-surface-background-color,\n rgb(var(--contrast-100))\n );--mdc-theme-on-surface:var(\n --lime-on-surface-color,\n rgb(var(--contrast-1500))\n )}blockquote{position:relative;font-weight:100;font-size:0.875rem;max-width:100%;line-height:1.4;margin:0;padding:0.5rem 1.25rem;border-radius:0.05rem 0.75rem;background-color:rgb(var(--contrast-300))}blockquote:before,blockquote:after{position:absolute;font-size:2.75rem;opacity:0.4}blockquote:before{content:\"“\";left:0;top:-0.75rem}blockquote:after{content:\"”\";right:0;bottom:-2rem}:host(limel-markdown.truncate-paragraphs) p{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}p,li{font-size:0.875rem;word-break:break-word}a{word-break:break-all}p{margin-top:0;margin-bottom:0.5rem}p:only-child{margin-bottom:0}a{transition:color 0.2s ease;color:var(--markdown-hyperlink-color, rgb(var(--color-blue-dark)));text-decoration:none}a:hover{color:var(--markdown-hyperlink-color--hovered, rgb(var(--color-blue-default)))}hr{margin:1.75rem 0 2rem 0;border-width:0;border-top:1px solid rgb(var(--contrast-500))}dl{display:grid;grid-template-columns:1fr 2fr;grid-template-rows:1fr;margin-bottom:2rem;border:1px solid rgb(var(--contrast-400));border-radius:0.375rem;background-color:rgb(var(--contrast-200))}dl dt,dl dd{padding:0.375rem 0.5rem;font-size:0.875rem;margin:0}dl dt:nth-of-type(even),dl dd:nth-of-type(even){background-color:rgb(var(--contrast-300))}dl dt:first-child{border-top-left-radius:0.375rem}dl dt:last-child{border-bottom-left-radius:0.375rem}dl dd:first-child{border-top-right-radius:0.375rem}dl dd:last-child{border-bottom-right-radius:0.375rem}h1{font-size:1.5rem}h2{font-size:1.25rem}h3{font-size:1.125rem}h4{font-size:1rem}h5{font-size:0.875rem}h6{font-size:0.75rem}h1,h2{margin-top:0.5rem;margin-bottom:0.5rem;letter-spacing:-0.03125rem;font-weight:500}h3,h4{margin-top:0.75rem;margin-bottom:0.25rem;font-weight:600}h5,h6{margin-top:0.5rem;margin-bottom:0.125rem;font-weight:600}h1,h2,h3,h4,h5,h6{word-break:break-word;hyphens:auto;-webkit-hyphens:auto}:not([contenteditable=true]) h1,:not([contenteditable=true]) h2,:not([contenteditable=true]) h3,:not([contenteditable=true]) h4,:not([contenteditable=true]) h5,:not([contenteditable=true]) h6{text-wrap:balance}[contenteditable=true] h1,[contenteditable=true] h2,[contenteditable=true] h3,[contenteditable=true] h4,[contenteditable=true] h5,[contenteditable=true] h6{text-wrap:initial}ul{list-style:none}ul li{position:relative;margin-left:0.75rem}ul li:before{content:\"\";position:absolute;left:-0.5rem;top:0.5rem;width:0.25rem;height:0.25rem;border-radius:50%;background-color:rgb(var(--contrast-700));display:block}ol{margin-top:0.25rem;padding-left:1rem}ul{margin-top:0.25rem;padding-left:0}ul ul,ul ol,ol ol,ol ul{margin-left:0}li{margin-bottom:0.25rem}code{font-family:ui-monospace, \"Cascadia Code\", \"Source Code Pro\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace;font-size:0.8125rem;letter-spacing:-0.0125rem;color:rgb(var(--contrast-1300));-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;display:inline-block;border-radius:0.25rem;padding:0.03125rem 0.25rem;background-color:rgb(var(--contrast-600))}pre>code{display:block;margin:0.5rem 0;padding:0.5rem 0.75rem;overflow:auto;white-space:pre-wrap}:host(limel-markdown:not(.no-table-styles)) table{table-layout:auto;min-width:100%;border-collapse:collapse;border-spacing:0;background:transparent;margin:0.75rem 0}:host(limel-markdown:not(.no-table-styles)) tbody{border:1px solid rgb(var(--contrast-400));border-radius:0.25rem}:host(limel-markdown:not(.no-table-styles)) th,:host(limel-markdown:not(.no-table-styles)) td{text-align:left;vertical-align:top;transition:background-color 0.2s ease;font-size:0.875rem}:host(limel-markdown:not(.no-table-styles)) td{padding:0.5rem 0.375rem 0.75rem 0.375rem}:host(limel-markdown:not(.no-table-styles)) tr th{background-color:rgb(var(--contrast-400));padding:0.25rem 0.375rem;font-weight:normal}:host(limel-markdown:not(.no-table-styles)) tr th:only-child{text-align:center}:host(limel-markdown:not(.no-table-styles)) tbody tr:nth-child(odd) td{background-color:rgb(var(--contrast-200))}:host(limel-markdown:not(.no-table-styles)) tbody tr:hover td{background-color:rgb(var(--contrast-300))}table{display:block;box-sizing:border-box;overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}kbd{font-family:ui-monospace, \"Cascadia Code\", \"Source Code Pro\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace;font-weight:600;color:rgb(var(--contrast-1100));background-color:rgb(var(--contrast-200));white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:normal;padding:0.125rem 0.5rem;margin:0 0.25rem;box-shadow:var(--button-shadow-normal), 0 0.03125rem 0.21875rem 0 rgba(var(--contrast-100), 0.5) inset;border-radius:0.125rem;border-style:solid;border-color:rgba(var(--contrast-600), 0.8);border-width:0 1px 0.125rem 1px}img{max-width:100%;border-radius:0.25rem}.image-wrapper{display:inline-flex;position:relative}.image-wrapper limel-linear-progress{position:absolute;inset:0.25rem auto auto 0.25rem;width:calc(100% - 0.5rem)}.image-wrapper img{transition:opacity 0.2s ease, scale 0.6s ease}.image-wrapper.state-failed,.image-wrapper.state-loading{background:url(\"data:image/svg+xml;charset=utf-8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' style='fill-rule:evenodd;'><path fill='rgba(186,186,192,0.16)' d='M0 0h4v4H0zM4 4h4v4H4z'/></svg>\");background-size:0.5rem}.image-wrapper.state-failed img,.image-wrapper.state-loading img{opacity:0.3;scale:0.98}.image-wrapper::before{pointer-events:none;content:\"\";display:block;position:absolute;inset:0;border-radius:0.25rem;transition:border-color 0.4s ease, opacity 0.2s ease, box-shadow 0.6s ease;border:1px dashed transparent;opacity:0.2}.image-wrapper.state-failed img{filter:grayscale(0.8)}.image-wrapper.state-failed:before{opacity:0.8;box-shadow:var(--shadow-error-state)}.image-wrapper:hover::before{opacity:0.8;box-shadow:var(--shadow-depth-8)}.image-wrapper:has(.resize-handle[aria-grabbed=true])::before{border-color:var(--mdc-theme-primary);opacity:0.8;box-shadow:var(--shadow-depth-16), var(--shadow-depth-8)}.resize-handle{transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);cursor:pointer;color:var(--mdc-theme-on-surface);background-color:rgb(var(--contrast-900));box-shadow:var(--button-shadow-normal);cursor:nwse-resize;position:absolute;display:flex;align-items:center;justify-content:center;width:0.5rem;height:0.5rem;border-radius:50%;opacity:0.6}.resize-handle:hover,.resize-handle:focus,.resize-handle:focus-visible{will-change:color, background-color, box-shadow, transform}.resize-handle:hover{transform:translate3d(0, -0.04rem, 0);color:var(--mdc-theme-on-surface);background-color:var(--lime-elevated-surface-background-color);box-shadow:var(--button-shadow-hovered)}.resize-handle:active{--limel-clickable-transform-timing-function:cubic-bezier(\n 0.83,\n -0.15,\n 0.49,\n 1.16\n );transform:translate3d(0, 0.05rem, 0);box-shadow:var(--button-shadow-pressed)}.resize-handle:hover,.resize-handle:active{--limel-clickable-transition-speed:0.2s;--limel-clickable-transform-speed:0.16s}.resize-handle:focus{outline:none}.resize-handle:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}.resize-handle.top-left{left:-0.25rem;top:-0.25rem;translate:-50%, -50%}.resize-handle.bottom-right{right:-0.25rem;bottom:-0.25rem;translate:50%, 50%}.resize-wrapper:has(.resize-handle[aria-grabbed=true]) .resize-handle,.resize-wrapper:hover .resize-handle,.resize-handle:hover,.resize-handle:focus-visible{opacity:1}.resize-handle[aria-grabbed=true],.resize-handle:hover,.resize-handle:focus-visible{opacity:1;background-color:var(--mdc-theme-primary)}.resize-handle:hover,.resize-handle[aria-grabbed=true]{scale:1.4}.resize-handle:hover:before,.resize-handle[aria-grabbed=true]:before{background-color:rgb(var(--color-white))}.resize-handle:before{content:\"\";display:block;position:absolute;inset:0;margin:auto;border-radius:50%;width:0.25rem;height:0.25rem;background-color:rgb(var(--contrast-100))}:host(limel-prosemirror-adapter){display:flex;flex-direction:column}:host(limel-prosemirror-adapter) .toolbar{order:1}:host(limel-prosemirror-adapter) div#editor{order:2;height:100%;flex-grow:1}:host(limel-prosemirror-adapter) div[contenteditable=true]{height:100%}*{box-sizing:border-box}:host(limel-prosemirror-adapter:hover) .toolbar,:host(limel-prosemirror-adapter:focus-within) .toolbar{will-change:grid-template-rows}:host(limel-prosemirror-adapter:hover) limel-action-bar,:host(limel-prosemirror-adapter:focus-within) limel-action-bar{will-change:opacity, padding}.ProseMirror-menubar-wrapper{display:grid;grid-template-rows:auto 1fr}.ProseMirror-textblock-dropdown{min-width:3em}.ProseMirror-tooltip .ProseMirror-menu{width:-webkit-fit-content;width:fit-content;white-space:pre}.toolbar{--action-bar-border-radius:0.25rem;border-radius:var(--action-bar-border-radius);flex-shrink:0;position:sticky;z-index:1;top:0;width:100%;display:grid;grid-template-rows:var(--limel-prosemirror-adapter-toolbar-grid-template-rows);transition-property:grid-template-rows;transition-duration:var(--limel-prosemirror-adapter-toolbar-grid-template-rows-transition-duration);transition-timing-function:var(--limel-prosemirror-adapter-toolbar-transition-timing-function);background-color:rgba(var(--contrast-200), 0.5);backdrop-filter:blur(0.5rem);-webkit-backdrop-filter:blur(0.5rem)}limel-action-bar{min-width:0;transition-property:padding, opacity;transition-duration:var(--limel-prosemirror-adapter-toolbar-grid-template-rows-transition-duration);transition-timing-function:var(--limel-prosemirror-adapter-toolbar-transition-timing-function);opacity:var(--limel-prosemirror-adapter-toolbar-opacity);padding:var(--limel-prosemirror-adapter-action-bar-padding-top-bottom, 0.125rem) 0.25rem;background-color:transparent;overflow:hidden}.ProseMirror{position:relative;word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:\"liga\" 0;padding:var(--limel-text-editor-padding)}.ProseMirror [draggable][contenteditable=false]{user-select:text}.ProseMirror:focus-visible{outline:none}.ProseMirror-hideselection{caret-color:transparent}.ProseMirror-hideselection *::selection{background:transparent}.ProseMirror-hideselection *::-moz-selection{background:transparent}.ProseMirror-selectednode{outline:0.125rem solid rgb(var(--color-sky-light))}li.ProseMirror-selectednode{outline:none}li.ProseMirror-selectednode:after{content:\"\";position:absolute;left:-2rem;right:-0.125rem;top:-0.125rem;bottom:-0.125rem;border:0.125rem solid rgb(var(--color-sky-light));pointer-events:none}img.ProseMirror-separator{display:inline !important;border:none !important;margin:0 !important}limel-portal{width:25rem}";
|
|
28320
28398
|
|
|
28321
28399
|
const DEBOUNCE_TIMEOUT = 300;
|
|
@@ -28325,7 +28403,9 @@ const ProsemirrorAdapter = class {
|
|
|
28325
28403
|
this.change = createEvent(this, "change", 7);
|
|
28326
28404
|
this.imagePasted = createEvent(this, "imagePasted", 7);
|
|
28327
28405
|
this.imageRemoved = createEvent(this, "imageRemoved", 7);
|
|
28406
|
+
this.metadataChange = createEvent(this, "metadataChange", 7);
|
|
28328
28407
|
this.changeWaiting = false;
|
|
28408
|
+
this.metadata = { images: [], links: [] };
|
|
28329
28409
|
/**
|
|
28330
28410
|
* Used to stop change event emitting as result of getting updated value from consumer
|
|
28331
28411
|
*/
|
|
@@ -28362,6 +28442,8 @@ const ProsemirrorAdapter = class {
|
|
|
28362
28442
|
if (content === this.lastEmittedValue) {
|
|
28363
28443
|
return;
|
|
28364
28444
|
}
|
|
28445
|
+
const metadata = getMetadataFromDoc(newState.doc);
|
|
28446
|
+
this.metadataEmitter(metadata);
|
|
28365
28447
|
this.lastEmittedValue = content;
|
|
28366
28448
|
this.changeWaiting = true;
|
|
28367
28449
|
this.changeEmitter(content);
|
|
@@ -28553,7 +28635,7 @@ const ProsemirrorAdapter = class {
|
|
|
28553
28635
|
keymap(this.menuCommandFactory.buildKeymap()),
|
|
28554
28636
|
createTriggerPlugin(this.triggerCharacters, this.contentConverter),
|
|
28555
28637
|
createLinkPlugin(this.handleNewLinkSelection),
|
|
28556
|
-
createImageInserterPlugin(this.imagePasted.emit
|
|
28638
|
+
createImageInserterPlugin(this.imagePasted.emit),
|
|
28557
28639
|
createImageViewPlugin(this.language),
|
|
28558
28640
|
createMenuStateTrackingPlugin(editorMenuTypesArray, this.menuCommandFactory, this.updateActiveActionBarItems),
|
|
28559
28641
|
createActionBarInteractionPlugin(this.menuCommandFactory),
|
|
@@ -28571,8 +28653,24 @@ const ProsemirrorAdapter = class {
|
|
|
28571
28653
|
const tr = this.view.state.tr;
|
|
28572
28654
|
tr.replaceWith(0, tr.doc.content.size, prosemirrorDoc.content);
|
|
28573
28655
|
this.view.dispatch(tr);
|
|
28656
|
+
const metadata = getMetadataFromDoc(this.view.state.doc);
|
|
28657
|
+
this.metadataEmitter(metadata);
|
|
28574
28658
|
this.suppressChangeEvent = false;
|
|
28575
28659
|
}
|
|
28660
|
+
metadataEmitter(metadata) {
|
|
28661
|
+
if (hasMetadataChanged(this.metadata, metadata)) {
|
|
28662
|
+
this.removeImagesFromCache(this.metadata, metadata);
|
|
28663
|
+
this.metadata = metadata;
|
|
28664
|
+
this.metadataChange.emit(metadata);
|
|
28665
|
+
}
|
|
28666
|
+
}
|
|
28667
|
+
removeImagesFromCache(oldMetadata, newMetadata) {
|
|
28668
|
+
const removedImages = oldMetadata.images.filter((oldImage) => !newMetadata.images.some((newImage) => newImage.fileInfoId === oldImage.fileInfoId));
|
|
28669
|
+
removedImages.forEach((image) => {
|
|
28670
|
+
imageCache.delete(image.fileInfoId);
|
|
28671
|
+
this.imageRemoved.emit(image);
|
|
28672
|
+
});
|
|
28673
|
+
}
|
|
28576
28674
|
static get delegatesFocus() { return true; }
|
|
28577
28675
|
get host() { return getElement(this); }
|
|
28578
28676
|
static get watchers() { return {
|