@limetech/lime-elements 38.2.3 → 38.3.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.
Files changed (145) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/files-c08d24d4.js +44 -0
  3. package/dist/cjs/files-c08d24d4.js.map +1 -0
  4. package/dist/cjs/index.cjs.js +9 -0
  5. package/dist/cjs/index.cjs.js.map +1 -1
  6. package/dist/cjs/limel-action-bar_2.cjs.entry.js +1 -1
  7. package/dist/cjs/limel-callout.cjs.entry.js +1 -1
  8. package/dist/cjs/limel-chart.cjs.entry.js +1 -1
  9. package/dist/cjs/limel-chip_2.cjs.entry.js +1 -1
  10. package/dist/cjs/limel-file-dropzone_2.cjs.entry.js +8 -43
  11. package/dist/cjs/limel-file-dropzone_2.cjs.entry.js.map +1 -1
  12. package/dist/cjs/limel-file-viewer.cjs.entry.js +1 -1
  13. package/dist/cjs/limel-file.cjs.entry.js +1 -1
  14. package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +1 -1
  15. package/dist/cjs/limel-linear-progress.cjs.entry.js +1 -1
  16. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +404 -19
  17. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
  18. package/dist/cjs/limel-snackbar.cjs.entry.js +1 -1
  19. package/dist/cjs/limel-text-editor.cjs.entry.js +11 -1
  20. package/dist/cjs/limel-text-editor.cjs.entry.js.map +1 -1
  21. package/dist/cjs/text-editor.types-5e5567e2.js +13 -0
  22. package/dist/cjs/text-editor.types-5e5567e2.js.map +1 -0
  23. package/dist/cjs/{translations-0d53f9bc.js → translations-b5da5dcd.js} +55 -4
  24. package/dist/cjs/translations-b5da5dcd.js.map +1 -0
  25. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/inserter.js +195 -0
  26. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/inserter.js.map +1 -0
  27. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/node.js +128 -0
  28. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/node.js.map +1 -0
  29. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/view.js +139 -0
  30. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image/view.js.map +1 -0
  31. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.css +187 -0
  32. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +60 -3
  33. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map +1 -1
  34. package/dist/collection/components/text-editor/text-editor.js +63 -1
  35. package/dist/collection/components/text-editor/text-editor.js.map +1 -1
  36. package/dist/collection/components/text-editor/text-editor.types.js +9 -1
  37. package/dist/collection/components/text-editor/text-editor.types.js.map +1 -1
  38. package/dist/collection/components/text-editor/utils/html-converter.js +7 -4
  39. package/dist/collection/components/text-editor/utils/html-converter.js.map +1 -1
  40. package/dist/collection/components/text-editor/utils/markdown-converter.js +8 -8
  41. package/dist/collection/components/text-editor/utils/markdown-converter.js.map +1 -1
  42. package/dist/collection/global/translations.js +9 -2
  43. package/dist/collection/global/translations.js.map +1 -1
  44. package/dist/collection/translations/da.js +6 -0
  45. package/dist/collection/translations/da.js.map +1 -1
  46. package/dist/collection/translations/de.js +5 -0
  47. package/dist/collection/translations/de.js.map +1 -1
  48. package/dist/collection/translations/en.js +5 -0
  49. package/dist/collection/translations/en.js.map +1 -1
  50. package/dist/collection/translations/fi.js +7 -1
  51. package/dist/collection/translations/fi.js.map +1 -1
  52. package/dist/collection/translations/fr.js +5 -0
  53. package/dist/collection/translations/fr.js.map +1 -1
  54. package/dist/collection/translations/nl.js +6 -0
  55. package/dist/collection/translations/nl.js.map +1 -1
  56. package/dist/collection/translations/no.js +6 -0
  57. package/dist/collection/translations/no.js.map +1 -1
  58. package/dist/collection/translations/sv.js +5 -0
  59. package/dist/collection/translations/sv.js.map +1 -1
  60. package/dist/esm/files-2be62a61.js +41 -0
  61. package/dist/esm/files-2be62a61.js.map +1 -0
  62. package/dist/esm/index.js +2 -0
  63. package/dist/esm/index.js.map +1 -1
  64. package/dist/esm/limel-action-bar_2.entry.js +1 -1
  65. package/dist/esm/limel-callout.entry.js +1 -1
  66. package/dist/esm/limel-chart.entry.js +1 -1
  67. package/dist/esm/limel-chip_2.entry.js +1 -1
  68. package/dist/esm/limel-file-dropzone_2.entry.js +2 -37
  69. package/dist/esm/limel-file-dropzone_2.entry.js.map +1 -1
  70. package/dist/esm/limel-file-viewer.entry.js +1 -1
  71. package/dist/esm/limel-file.entry.js +1 -1
  72. package/dist/esm/limel-flatpickr-adapter.entry.js +1 -1
  73. package/dist/esm/limel-linear-progress.entry.js +1 -1
  74. package/dist/esm/limel-prosemirror-adapter.entry.js +404 -19
  75. package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
  76. package/dist/esm/limel-snackbar.entry.js +1 -1
  77. package/dist/esm/limel-text-editor.entry.js +11 -1
  78. package/dist/esm/limel-text-editor.entry.js.map +1 -1
  79. package/dist/esm/text-editor.types-e82469d1.js +13 -0
  80. package/dist/esm/text-editor.types-e82469d1.js.map +1 -0
  81. package/dist/esm/{translations-7ad188e0.js → translations-8b7272f2.js} +55 -4
  82. package/dist/esm/translations-8b7272f2.js.map +1 -0
  83. package/dist/lime-elements/index.esm.js +1 -1
  84. package/dist/lime-elements/index.esm.js.map +1 -1
  85. package/dist/lime-elements/lime-elements.esm.js +1 -1
  86. package/dist/lime-elements/{p-fc7f9e93.entry.js → p-24a46d85.entry.js} +2 -2
  87. package/dist/lime-elements/{p-54b4a06b.entry.js → p-2ca8f253.entry.js} +2 -2
  88. package/dist/lime-elements/{p-0468e34c.entry.js → p-3479aa66.entry.js} +2 -2
  89. package/dist/lime-elements/{p-b78a9a5c.entry.js → p-54710fb8.entry.js} +2 -2
  90. package/dist/lime-elements/{p-180675a5.entry.js → p-5ac99c32.entry.js} +2 -2
  91. package/dist/lime-elements/{p-7fdab6b0.entry.js → p-62a21e92.entry.js} +2 -2
  92. package/dist/lime-elements/p-62a21e92.entry.js.map +1 -0
  93. package/dist/lime-elements/{p-28c6b698.entry.js → p-8c15a058.entry.js} +2 -2
  94. package/dist/lime-elements/p-9ca516ed.js +2 -0
  95. package/dist/lime-elements/p-9ca516ed.js.map +1 -0
  96. package/dist/lime-elements/{p-fefef194.entry.js → p-ae417884.entry.js} +2 -2
  97. package/dist/lime-elements/{p-ffe954d4.entry.js → p-bda61285.entry.js} +2 -2
  98. package/dist/lime-elements/{p-8ada443f.entry.js → p-c348740c.entry.js} +2 -2
  99. package/dist/lime-elements/p-dbcde7db.entry.js +2 -0
  100. package/dist/lime-elements/p-dbcde7db.entry.js.map +1 -0
  101. package/dist/lime-elements/p-dc3d2ee1.js +2 -0
  102. package/dist/lime-elements/p-dc3d2ee1.js.map +1 -0
  103. package/dist/lime-elements/p-e3d7aba7.js +2 -0
  104. package/dist/lime-elements/p-e3d7aba7.js.map +1 -0
  105. package/dist/lime-elements/p-f641bcb0.entry.js +2 -0
  106. package/dist/lime-elements/p-f641bcb0.entry.js.map +1 -0
  107. package/dist/types/components/text-editor/prosemirror-adapter/plugins/image/inserter.d.ts +15 -0
  108. package/dist/types/components/text-editor/prosemirror-adapter/plugins/image/node.d.ts +14 -0
  109. package/dist/types/components/text-editor/prosemirror-adapter/plugins/image/view.d.ts +4 -0
  110. package/dist/types/components/text-editor/prosemirror-adapter/prosemirror-adapter.d.ts +14 -0
  111. package/dist/types/components/text-editor/text-editor.d.ts +18 -0
  112. package/dist/types/components/text-editor/text-editor.types.d.ts +51 -0
  113. package/dist/types/components/text-editor/utils/markdown-converter.d.ts +2 -1
  114. package/dist/types/components.d.ts +34 -2
  115. package/dist/types/global/translations.d.ts +1 -1
  116. package/dist/types/translations/da.d.ts +6 -0
  117. package/dist/types/translations/de.d.ts +5 -0
  118. package/dist/types/translations/en.d.ts +5 -0
  119. package/dist/types/translations/fi.d.ts +7 -1
  120. package/dist/types/translations/fr.d.ts +5 -0
  121. package/dist/types/translations/nl.d.ts +6 -0
  122. package/dist/types/translations/no.d.ts +6 -0
  123. package/dist/types/translations/sv.d.ts +5 -0
  124. package/package.json +1 -1
  125. package/dist/cjs/translations-0d53f9bc.js.map +0 -1
  126. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image-remover-plugin.js +0 -78
  127. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/image-remover-plugin.js.map +0 -1
  128. package/dist/esm/translations-7ad188e0.js.map +0 -1
  129. package/dist/lime-elements/p-7fdab6b0.entry.js.map +0 -1
  130. package/dist/lime-elements/p-ad9801f8.entry.js +0 -2
  131. package/dist/lime-elements/p-ad9801f8.entry.js.map +0 -1
  132. package/dist/lime-elements/p-e5545944.entry.js +0 -2
  133. package/dist/lime-elements/p-e5545944.entry.js.map +0 -1
  134. package/dist/lime-elements/p-efd753ba.js +0 -2
  135. package/dist/lime-elements/p-efd753ba.js.map +0 -1
  136. package/dist/types/components/text-editor/prosemirror-adapter/plugins/image-remover-plugin.d.ts +0 -4
  137. /package/dist/lime-elements/{p-fc7f9e93.entry.js.map → p-24a46d85.entry.js.map} +0 -0
  138. /package/dist/lime-elements/{p-54b4a06b.entry.js.map → p-2ca8f253.entry.js.map} +0 -0
  139. /package/dist/lime-elements/{p-0468e34c.entry.js.map → p-3479aa66.entry.js.map} +0 -0
  140. /package/dist/lime-elements/{p-b78a9a5c.entry.js.map → p-54710fb8.entry.js.map} +0 -0
  141. /package/dist/lime-elements/{p-180675a5.entry.js.map → p-5ac99c32.entry.js.map} +0 -0
  142. /package/dist/lime-elements/{p-28c6b698.entry.js.map → p-8c15a058.entry.js.map} +0 -0
  143. /package/dist/lime-elements/{p-fefef194.entry.js.map → p-ae417884.entry.js.map} +0 -0
  144. /package/dist/lime-elements/{p-ffe954d4.entry.js.map → p-bda61285.entry.js.map} +0 -0
  145. /package/dist/lime-elements/{p-8ada443f.entry.js.map → p-c348740c.entry.js.map} +0 -0
@@ -13,9 +13,11 @@ const _getPrototype = require('./_getPrototype-18d2118e.js');
13
13
  const isArray = require('./isArray-d188a04f.js');
14
14
  const isObjectLike = require('./isObjectLike-3e3f0cba.js');
15
15
  const markdownParser = require('./markdown-parser-89b425cf.js');
16
- const translations = require('./translations-0d53f9bc.js');
16
+ const textEditor_types = require('./text-editor.types-5e5567e2.js');
17
+ const translations = require('./translations-b5da5dcd.js');
17
18
  const randomString = require('./random-string-e8ad4419.js');
18
19
  const isItem = require('./isItem-3f8ad629.js');
20
+ const files = require('./files-c08d24d4.js');
19
21
  const isEqual = require('./isEqual-a4bccf32.js');
20
22
  const debounce = require('./debounce-2e5f4b7e.js');
21
23
  require('./eq-9a943b00.js');
@@ -24,6 +26,8 @@ require('./_isIndex-b40f4fc5.js');
24
26
  require('./isArrayLike-e840b044.js');
25
27
  require('./_defineProperty-8f56146d.js');
26
28
  require('./_commonjsHelpers-0c557e26.js');
29
+ require('./file-metadata-e309a7a4.js');
30
+ require('./get-icon-props-65f39e40.js');
27
31
  require('./toNumber-062ea29c.js');
28
32
  require('./isSymbol-d22b2798.js');
29
33
 
@@ -25903,6 +25907,132 @@ class MarkdownSerializerState {
25903
25907
  }
25904
25908
  }
25905
25909
 
25910
+ const imageCache = new Map();
25911
+ function getImageNode(language) {
25912
+ return { image: createImageNodeSpec(language) };
25913
+ }
25914
+ function getImageNodeMarkdownSerializer(language) {
25915
+ return { image: createImageNodeMarkdownSerializer(language) };
25916
+ }
25917
+ /**
25918
+ * Recursively checks if a ProseMirror node or
25919
+ * any of its child nodes is an image node.
25920
+ */
25921
+ function hasImageNode(node) {
25922
+ if (node.type.name === 'image') {
25923
+ return true;
25924
+ }
25925
+ for (let i = 0; i < node.childCount; i++) {
25926
+ const childNode = node.child(i);
25927
+ if (hasImageNode(childNode)) {
25928
+ return true;
25929
+ }
25930
+ }
25931
+ return false;
25932
+ }
25933
+ function createImageNodeMarkdownSerializer(language) {
25934
+ return (state, node) => {
25935
+ if (node.attrs.state === textEditor_types.ImageState.FAILED) {
25936
+ const text = translations.translate.get('editor-image-view.failed', language, {
25937
+ filename: node.attrs.alt || 'file',
25938
+ });
25939
+ state.write(`<span>${text}</span>`);
25940
+ return;
25941
+ }
25942
+ else if (node.attrs.state === textEditor_types.ImageState.LOADING) {
25943
+ const text = translations.translate.get('editor-image-view.loading', language, {
25944
+ filename: node.attrs.alt || 'file',
25945
+ });
25946
+ state.write(`<span>${text}</span>`);
25947
+ return;
25948
+ }
25949
+ let imageHTML = `<img src="${node.attrs.src}"`;
25950
+ if (node.attrs.alt) {
25951
+ imageHTML += ` alt="${node.attrs.alt}"`;
25952
+ }
25953
+ const style = [];
25954
+ if (node.attrs.width) {
25955
+ style.push(`width: ${node.attrs.width};`);
25956
+ }
25957
+ if (node.attrs.maxWidth) {
25958
+ style.push(`max-width: ${node.attrs.maxWidth};`);
25959
+ }
25960
+ if (style.length > 0) {
25961
+ imageHTML += ` style="${style.join(' ')}"`;
25962
+ }
25963
+ imageHTML += ' />';
25964
+ state.write(imageHTML);
25965
+ };
25966
+ }
25967
+ function createImageNodeSpec(language) {
25968
+ return {
25969
+ group: 'inline',
25970
+ inline: true,
25971
+ attrs: {
25972
+ src: { default: '' },
25973
+ alt: { default: '' },
25974
+ fileInfoId: { default: '' },
25975
+ width: { default: '' },
25976
+ maxWidth: { default: '100%' },
25977
+ state: { default: '' },
25978
+ },
25979
+ toDOM: (node) => {
25980
+ if (node.attrs.state === textEditor_types.ImageState.FAILED) {
25981
+ return createStatusSpan('failed', node, language);
25982
+ }
25983
+ else if (node.attrs.state === textEditor_types.ImageState.LOADING) {
25984
+ return createStatusSpan('loading', node, language);
25985
+ }
25986
+ let img = imageCache.get(node.attrs.fileInfoId);
25987
+ if (img) {
25988
+ updateImageElement(img, node);
25989
+ }
25990
+ else {
25991
+ img = createImageElement(node);
25992
+ imageCache.set(node.attrs.fileInfoId, img);
25993
+ }
25994
+ return img;
25995
+ },
25996
+ parseDOM: [
25997
+ {
25998
+ tag: 'img',
25999
+ getAttrs: (dom) => {
26000
+ return {
26001
+ src: dom.getAttribute('src') || '',
26002
+ alt: dom.getAttribute('alt') || 'file',
26003
+ width: dom.style.width || '',
26004
+ maxWidth: '100%',
26005
+ state: textEditor_types.ImageState.SUCCESS,
26006
+ fileInfoId: crypto.randomUUID(),
26007
+ };
26008
+ },
26009
+ },
26010
+ ],
26011
+ };
26012
+ }
26013
+ function createStatusSpan(key, node, language) {
26014
+ const text = translations.translate.get(`editor-image-view.${key}`, language, {
26015
+ filename: node.attrs.alt || 'file',
26016
+ });
26017
+ const span = document.createElement('span');
26018
+ span.textContent = text;
26019
+ return span;
26020
+ }
26021
+ function updateImageElement(img, node) {
26022
+ img.alt = node.attrs.alt;
26023
+ img.style.maxWidth = node.attrs.maxWidth;
26024
+ img.style.width = node.attrs.width;
26025
+ return img;
26026
+ }
26027
+ function createImageElement(node) {
26028
+ const img = document.createElement('img');
26029
+ img.src = node.attrs.src;
26030
+ img.alt = node.attrs.alt;
26031
+ img.style.maxWidth = node.attrs.maxWidth;
26032
+ img.style.width = node.attrs.width;
26033
+ return img;
26034
+ }
26035
+
25906
26036
  const createMarkdownSerializerFunction = (config) => {
25907
26037
  return (state, node) => {
25908
26038
  const tagOpen = `<${config.tagName}` +
@@ -25916,12 +26046,12 @@ const createMarkdownSerializerFunction = (config) => {
25916
26046
  state.write(tagClose);
25917
26047
  };
25918
26048
  };
25919
- const buildMarkdownSerializer = (plugins) => {
26049
+ const buildMarkdownSerializer = (plugins, language) => {
25920
26050
  const customNodes = {};
25921
26051
  plugins.forEach((plugin) => {
25922
26052
  customNodes[plugin.tagName] = createMarkdownSerializerFunction(plugin);
25923
26053
  });
25924
- const nodes = Object.assign(Object.assign({}, defaultMarkdownSerializer.nodes), customNodes);
26054
+ const nodes = Object.assign(Object.assign(Object.assign({}, defaultMarkdownSerializer.nodes), getImageNodeMarkdownSerializer(language)), customNodes);
25925
26055
  const marks = Object.assign(Object.assign({}, defaultMarkdownSerializer.marks), { strikethrough: {
25926
26056
  open: '~~',
25927
26057
  close: '~~',
@@ -25934,19 +26064,18 @@ const buildMarkdownSerializer = (plugins) => {
25934
26064
  * @private
25935
26065
  */
25936
26066
  class MarkdownConverter {
25937
- constructor(plugins) {
26067
+ constructor(plugins, language) {
25938
26068
  this.parseAsHTML = (text) => {
25939
26069
  return markdownParser.markdownToHTML(text, { whitelist: this.customNodes });
25940
26070
  };
25941
26071
  this.serialize = (view) => {
25942
- if (view.dom.textContent === '') {
26072
+ if (view.dom.textContent.trim() === '' &&
26073
+ !hasImageNode(view.state.doc)) {
25943
26074
  return '';
25944
26075
  }
25945
- else {
25946
- return this.markdownSerializer.serialize(view.state.doc);
25947
- }
26076
+ return this.markdownSerializer.serialize(view.state.doc);
25948
26077
  };
25949
- this.markdownSerializer = buildMarkdownSerializer(plugins);
26078
+ this.markdownSerializer = buildMarkdownSerializer(plugins, language);
25950
26079
  this.customNodes = plugins;
25951
26080
  }
25952
26081
  }
@@ -25960,12 +26089,13 @@ class HTMLConverter {
25960
26089
  return markdownParser.sanitizeHTML(text, this.customNodes);
25961
26090
  };
25962
26091
  this.serialize = (view) => {
25963
- if (view.dom.textContent === '') {
26092
+ if (view.dom.textContent.trim() === '' &&
26093
+ !hasImageNode(view.state.doc)) {
25964
26094
  return '';
25965
26095
  }
25966
- else {
25967
- return view.dom.innerHTML;
25968
- }
26096
+ const div = document.createElement('div');
26097
+ div.appendChild(DOMSerializer.fromSchema(view.state.schema).serializeFragment(view.state.doc.content));
26098
+ return div.innerHTML;
25969
26099
  };
25970
26100
  this.customNodes = plugins;
25971
26101
  }
@@ -26170,16 +26300,110 @@ const createLinkPlugin = (updateLinkCallback) => {
26170
26300
  });
26171
26301
  };
26172
26302
 
26173
- const pluginKey = new PluginKey('imageRemoverPlugin');
26174
- const createImageRemoverPlugin = () => {
26303
+ const pluginKey = new PluginKey('imageInserterPlugin');
26304
+ const createImageInserterPlugin = (imagePastedCallback, imageRemovedCallback) => {
26175
26305
  return new Plugin({
26176
26306
  key: pluginKey,
26177
26307
  props: {
26178
26308
  handlePaste: (view, event, slice) => {
26179
26309
  return processPasteEvent(view, event, slice);
26180
26310
  },
26311
+ handleDOMEvents: {
26312
+ imagePasted: (_, event) => {
26313
+ imagePastedCallback(event.detail);
26314
+ },
26315
+ },
26181
26316
  },
26317
+ state: {
26318
+ init: () => {
26319
+ return { insertedImages: {} };
26320
+ },
26321
+ apply: (tr, pluginState) => {
26322
+ const newState = Object.assign({}, pluginState);
26323
+ newState.insertedImages = getImagesFromTransaction(tr);
26324
+ findAndHandleRemovedImages(imageRemovedCallback, pluginState.insertedImages, newState.insertedImages);
26325
+ return newState;
26326
+ },
26327
+ },
26328
+ });
26329
+ };
26330
+ const getImagesFromTransaction = (tr) => {
26331
+ const images = {};
26332
+ tr.doc.descendants((node) => {
26333
+ if (node.type.name === 'image') {
26334
+ images[node.attrs.fileInfoId] = node;
26335
+ }
26336
+ });
26337
+ return images;
26338
+ };
26339
+ const findAndHandleRemovedImages = (imageRemovedCallback, previousImages, newImages) => {
26340
+ const removedKeys = Object.keys(previousImages).filter((key) => !(key in newImages));
26341
+ for (const removedKey of removedKeys) {
26342
+ const removedImage = previousImages[removedKey];
26343
+ const imageInfo = {
26344
+ fileInfoId: removedImage.attrs.fileInfoId,
26345
+ src: removedImage.attrs.src,
26346
+ state: removedImage.attrs.state,
26347
+ };
26348
+ imageRemovedCallback(imageInfo);
26349
+ imageCache.delete(removedImage.attrs.fileInfoId);
26350
+ }
26351
+ };
26352
+ const imageInserterFactory = (view, base64Data, fileInfo) => {
26353
+ return {
26354
+ fileInfo: fileInfo,
26355
+ insertThumbnail: createThumbnailInserter(view, base64Data, fileInfo),
26356
+ insertImage: createImageInserter(view, fileInfo),
26357
+ insertFailedThumbnail: createFailedThumbnailInserter(view, fileInfo),
26358
+ };
26359
+ };
26360
+ const createThumbnailInserter = (view, base64Data, fileInfo) => () => {
26361
+ const { state, dispatch } = view;
26362
+ const { schema } = state;
26363
+ const placeholderNode = schema.nodes.image.create({
26364
+ src: base64Data,
26365
+ alt: fileInfo.filename,
26366
+ fileInfoId: fileInfo.id,
26367
+ state: textEditor_types.ImageState.LOADING,
26368
+ });
26369
+ const transaction = state.tr.replaceSelectionWith(placeholderNode);
26370
+ dispatch(transaction);
26371
+ };
26372
+ const createImageInserter = (view, fileInfo) => (src) => {
26373
+ const { state, dispatch } = view;
26374
+ const { schema } = state;
26375
+ const tr = state.tr;
26376
+ state.doc.descendants((node, pos) => {
26377
+ if (node.attrs.fileInfoId === fileInfo.id) {
26378
+ const imageNode = schema.nodes.image.create({
26379
+ src: src ? src : node.attrs.src,
26380
+ alt: fileInfo.filename,
26381
+ fileInfoId: fileInfo.id,
26382
+ state: textEditor_types.ImageState.SUCCESS,
26383
+ });
26384
+ tr.replaceWith(pos, pos + node.nodeSize, imageNode);
26385
+ return false;
26386
+ }
26387
+ });
26388
+ dispatch(tr);
26389
+ };
26390
+ const createFailedThumbnailInserter = (view, fileInfo) => () => {
26391
+ const { state, dispatch } = view;
26392
+ const { schema } = state;
26393
+ const tr = state.tr;
26394
+ state.doc.descendants((node, pos) => {
26395
+ if (node.attrs.fileInfoId === fileInfo.id) {
26396
+ const errorPlaceholderNode = schema.nodes.image.create({
26397
+ src: node.attrs.src,
26398
+ alt: fileInfo.filename,
26399
+ fileInfoId: fileInfo.id,
26400
+ state: textEditor_types.ImageState.FAILED,
26401
+ });
26402
+ tr.replaceWith(pos, pos + node.nodeSize, errorPlaceholderNode);
26403
+ return false;
26404
+ }
26182
26405
  });
26406
+ dispatch(tr);
26183
26407
  };
26184
26408
  /**
26185
26409
  * Check if a given ProseMirror node or fragment contains any image nodes.
@@ -26231,11 +26455,31 @@ const filterImageNodes = (fragment) => {
26231
26455
  });
26232
26456
  return Fragment.fromArray(filteredChildren);
26233
26457
  };
26458
+ /**
26459
+ * Process a paste event and trigger an imagePasted event if an image file is pasted.
26460
+ * If an HTML image element is pasted, this image is filtered out from the slice content.
26461
+ *
26462
+ * @param view - The ProseMirror editor view.
26463
+ * @param event - The paste event.
26464
+ * @returns A boolean; True if an image file was pasted to prevent default paste behavior, otherwise false.
26465
+ */
26234
26466
  const processPasteEvent = (view, event, slice) => {
26235
26467
  const clipboardData = event.clipboardData;
26236
26468
  if (!clipboardData) {
26237
26469
  return false;
26238
26470
  }
26471
+ const files$1 = Array.from(clipboardData.files || []);
26472
+ for (const file of files$1) {
26473
+ if (file.type.startsWith('image/')) {
26474
+ const reader = new FileReader();
26475
+ reader.onloadend = () => {
26476
+ view.dom.dispatchEvent(new CustomEvent('imagePasted', {
26477
+ detail: imageInserterFactory(view, reader.result, files.createFileInfo(file)),
26478
+ }));
26479
+ };
26480
+ reader.readAsDataURL(file);
26481
+ }
26482
+ }
26239
26483
  const filteredSlice = new Slice(filterImageNodes(slice.content), slice.openStart, slice.openEnd);
26240
26484
  if (filteredSlice.content.childCount < slice.content.childCount) {
26241
26485
  const { state, dispatch } = view;
@@ -26243,8 +26487,144 @@ const processPasteEvent = (view, event, slice) => {
26243
26487
  dispatch(tr);
26244
26488
  return true;
26245
26489
  }
26246
- return false;
26490
+ return files$1.length > 0;
26491
+ };
26492
+
26493
+ const MIN_WIDTH = 10;
26494
+ const createImageViewPlugin = (language) => {
26495
+ return new Plugin({
26496
+ props: {
26497
+ nodeViews: {
26498
+ image: (node, view, getPos) => {
26499
+ return new ImageView(node, view, getPos, language);
26500
+ },
26501
+ },
26502
+ },
26503
+ });
26247
26504
  };
26505
+ class ImageView {
26506
+ constructor(node, view, getPos, language) {
26507
+ this.createResizeHandle = (position) => {
26508
+ const handle = document.createElement('div');
26509
+ handle.className = `resize-handle ${position}`;
26510
+ handle.setAttribute('role', 'slider');
26511
+ handle.setAttribute('aria-label', translations.translate.get('editor-image-view.resize-handle', this.language));
26512
+ handle.setAttribute('tabindex', '0');
26513
+ handle.setAttribute('aria-valuemin', MIN_WIDTH.toString());
26514
+ handle.setAttribute('aria-valuenow', this.img.offsetWidth.toString());
26515
+ handle.setAttribute('aria-valuetext', `${this.img.offsetWidth} pixels`);
26516
+ handle.setAttribute('aria-grabbed', 'false');
26517
+ handle.addEventListener('pointerdown', (e) => {
26518
+ handle.setAttribute('aria-grabbed', 'true');
26519
+ this.onResizeStart(e, position);
26520
+ });
26521
+ return handle;
26522
+ };
26523
+ this.onResizeStart = (event, position) => {
26524
+ event.preventDefault();
26525
+ const handle = event.target;
26526
+ const startX = event.clientX;
26527
+ const startWidth = this.img.offsetWidth;
26528
+ const onPointerMove = (e) => {
26529
+ const delta = e.clientX - startX;
26530
+ const widthDelta = position === 'top-left' ? -delta : delta;
26531
+ const newWidth = Math.max(MIN_WIDTH, startWidth + widthDelta);
26532
+ this.img.style.width = `${newWidth}px`;
26533
+ const handles = this.dom.querySelectorAll('.resize-handle');
26534
+ handles.forEach((resizeHandle) => {
26535
+ resizeHandle.setAttribute('aria-valuenow', newWidth.toString());
26536
+ resizeHandle.setAttribute('aria-valuetext', `${newWidth} pixels`);
26537
+ });
26538
+ };
26539
+ const onPointerUp = () => {
26540
+ window.removeEventListener('pointermove', onPointerMove);
26541
+ window.removeEventListener('pointerup', onPointerUp);
26542
+ handle.setAttribute('aria-grabbed', 'false');
26543
+ this.view.dispatch(this.view.state.tr.setNodeMarkup(this.getPos(), undefined, Object.assign(Object.assign({}, this.node.attrs), { width: this.img.style.width, height: this.node.attrs.height })));
26544
+ };
26545
+ window.addEventListener('pointermove', onPointerMove);
26546
+ window.addEventListener('pointerup', onPointerUp);
26547
+ };
26548
+ this.createLoadingState = () => {
26549
+ this.dom.setAttribute('aria-live', 'polite');
26550
+ this.dom.setAttribute('aria-busy', 'true');
26551
+ this.dom.setAttribute('aria-label', translations.translate.get('editor-image-view.loading', this.language, {
26552
+ filename: this.node.attrs.alt || 'file',
26553
+ }));
26554
+ const spinnerElement = document.createElement('limel-linear-progress');
26555
+ spinnerElement.setAttribute('indeterminate', 'true');
26556
+ this.dom.appendChild(spinnerElement);
26557
+ };
26558
+ this.createSuccessState = () => {
26559
+ this.dom.setAttribute('aria-live', 'polite');
26560
+ this.dom.setAttribute('aria-busy', 'false');
26561
+ this.dom.setAttribute('aria-label', translations.translate.get('editor-image-view.success', this.language, {
26562
+ filename: this.node.attrs.alt || 'file',
26563
+ }));
26564
+ const bottomRightHandle = this.createResizeHandle('bottom-right');
26565
+ const topLeftHandle = this.createResizeHandle('top-left');
26566
+ this.dom.appendChild(bottomRightHandle);
26567
+ this.dom.appendChild(topLeftHandle);
26568
+ };
26569
+ this.createFailedState = () => {
26570
+ this.dom.setAttribute('aria-live', 'assertive');
26571
+ this.dom.setAttribute('aria-busy', 'false');
26572
+ this.dom.setAttribute('aria-label', translations.translate.get('editor-image-view.failed', this.language, {
26573
+ filename: this.node.attrs.alt || 'file',
26574
+ }));
26575
+ };
26576
+ this.cleanUpPreviousState = () => {
26577
+ Array.from(this.dom.childNodes).forEach((child) => {
26578
+ if (!(child instanceof HTMLImageElement)) {
26579
+ child.remove();
26580
+ }
26581
+ });
26582
+ };
26583
+ this.transitionBetweenStates = () => {
26584
+ this.cleanUpPreviousState();
26585
+ this.dom.className = `image-wrapper state-${this.node.attrs.state}`;
26586
+ if (this.node.attrs.state === textEditor_types.ImageState.LOADING) {
26587
+ this.createLoadingState();
26588
+ }
26589
+ else if (this.node.attrs.state === textEditor_types.ImageState.SUCCESS) {
26590
+ this.createSuccessState();
26591
+ }
26592
+ else if (this.node.attrs.state === textEditor_types.ImageState.FAILED) {
26593
+ this.createFailedState();
26594
+ }
26595
+ };
26596
+ this.transitioningBetweenSuccessStates = (newNode) => {
26597
+ return (this.node.attrs.state === textEditor_types.ImageState.SUCCESS &&
26598
+ newNode.attrs.state === textEditor_types.ImageState.SUCCESS);
26599
+ };
26600
+ this.node = node;
26601
+ this.view = view;
26602
+ this.getPos = getPos;
26603
+ this.language = language;
26604
+ this.dom = document.createElement('div');
26605
+ this.dom.className = `image-wrapper state-${node.attrs.state}`;
26606
+ this.img = document.createElement('img');
26607
+ this.img.src = node.attrs.src;
26608
+ this.img.alt = node.attrs.alt;
26609
+ this.img.style.maxWidth = node.attrs.maxWidth;
26610
+ this.img.style.width = node.attrs.width;
26611
+ this.dom.appendChild(this.img);
26612
+ this.transitionBetweenStates();
26613
+ }
26614
+ // Ensure that the existing NodeView is reused rather than recreated.
26615
+ // Recreating the NodeView will cause flickering between states.
26616
+ update(node) {
26617
+ if (!this.transitioningBetweenSuccessStates(node)) {
26618
+ this.img.src = node.attrs.src;
26619
+ this.img.alt = node.attrs.alt;
26620
+ this.img.style.maxWidth = node.attrs.maxWidth;
26621
+ this.img.style.width = node.attrs.width;
26622
+ }
26623
+ this.node = node;
26624
+ this.transitionBetweenStates();
26625
+ return true;
26626
+ }
26627
+ }
26248
26628
 
26249
26629
  const actionBarPluginKey = new PluginKey('actionBarPlugin');
26250
26630
  const getMenuItemStates = (menuTypes, menuCommandFactory, view) => {
@@ -27936,13 +28316,15 @@ const getTableNodes = () => {
27936
28316
  });
27937
28317
  };
27938
28318
 
27939
- 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 )}: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}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;hyphens:auto;-webkit-hyphens:auto}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}";
28319
+ 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 )}: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}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;hyphens:auto;-webkit-hyphens:auto}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))}";
27940
28320
 
27941
28321
  const DEBOUNCE_TIMEOUT = 300;
27942
28322
  const ProsemirrorAdapter = class {
27943
28323
  constructor(hostRef) {
27944
28324
  index.registerInstance(this, hostRef);
27945
28325
  this.change = index.createEvent(this, "change", 7);
28326
+ this.imagePasted = index.createEvent(this, "imagePasted", 7);
28327
+ this.imageRemoved = index.createEvent(this, "imageRemoved", 7);
27946
28328
  this.changeWaiting = false;
27947
28329
  /**
27948
28330
  * Used to stop change event emitting as result of getting updated value from consumer
@@ -28088,6 +28470,7 @@ const ProsemirrorAdapter = class {
28088
28470
  }
28089
28471
  disconnectedCallback() {
28090
28472
  var _a, _b, _c;
28473
+ imageCache.clear();
28091
28474
  this.host.removeEventListener('open-editor-link-menu', this.handleOpenLinkMenu);
28092
28475
  (_b = (_a = this.view) === null || _a === void 0 ? void 0 : _a.dom) === null || _b === void 0 ? void 0 : _b.removeEventListener('blur', this.handleBlur);
28093
28476
  (_c = this.view) === null || _c === void 0 ? void 0 : _c.destroy();
@@ -28103,7 +28486,7 @@ const ProsemirrorAdapter = class {
28103
28486
  }
28104
28487
  setupContentConverter() {
28105
28488
  if (this.contentType === 'markdown') {
28106
- this.contentConverter = new MarkdownConverter(this.customElements);
28489
+ this.contentConverter = new MarkdownConverter(this.customElements, this.language);
28107
28490
  }
28108
28491
  else if (this.contentType === 'html') {
28109
28492
  this.contentConverter = new HTMLConverter(this.customElements);
@@ -28136,6 +28519,7 @@ const ProsemirrorAdapter = class {
28136
28519
  if (this.contentType === 'html') {
28137
28520
  nodes = nodes.append(getTableNodes());
28138
28521
  }
28522
+ nodes = nodes.append(getImageNode(this.language));
28139
28523
  return new Schema({
28140
28524
  nodes: nodes,
28141
28525
  marks: schema$1.spec.marks.append({
@@ -28162,7 +28546,8 @@ const ProsemirrorAdapter = class {
28162
28546
  keymap(this.menuCommandFactory.buildKeymap()),
28163
28547
  createTriggerPlugin(this.triggerCharacters, this.contentConverter),
28164
28548
  createLinkPlugin(this.handleNewLinkSelection),
28165
- createImageRemoverPlugin(),
28549
+ createImageInserterPlugin(this.imagePasted.emit, this.imageRemoved.emit),
28550
+ createImageViewPlugin(this.language),
28166
28551
  createMenuStateTrackingPlugin(editorMenuTypesArray, this.menuCommandFactory, this.updateActiveActionBarItems),
28167
28552
  createActionBarInteractionPlugin(this.menuCommandFactory),
28168
28553
  ...getTableEditingPlugins(this.contentType === 'html'),