@krainovsd/markdown-editor 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/lib/cjs/{index-D7RdBXAA.js → index-BgxbH3r2.js} +68 -41
  2. package/lib/cjs/index-BgxbH3r2.js.map +1 -0
  3. package/lib/cjs/{index-nYYQ5dvl.js → index-DU8JMAfc.js} +2 -2
  4. package/lib/cjs/{index-nYYQ5dvl.js.map → index-DU8JMAfc.js.map} +1 -1
  5. package/lib/cjs/index.js +1 -1
  6. package/lib/esm/extensions/markdown/image/image-decoration.js +7 -4
  7. package/lib/esm/extensions/markdown/image/image-decoration.js.map +1 -1
  8. package/lib/esm/extensions/markdown/image/image-widget.js +24 -10
  9. package/lib/esm/extensions/markdown/image/image-widget.js.map +1 -1
  10. package/lib/esm/extensions/markdown/italic/italic-decoration.js +6 -4
  11. package/lib/esm/extensions/markdown/italic/italic-decoration.js.map +1 -1
  12. package/lib/esm/extensions/markdown/link/auto-link-decoration.js +3 -2
  13. package/lib/esm/extensions/markdown/link/auto-link-decoration.js.map +1 -1
  14. package/lib/esm/extensions/markdown/link/link-decoration.js +5 -4
  15. package/lib/esm/extensions/markdown/link/link-decoration.js.map +1 -1
  16. package/lib/esm/extensions/markdown/link/link-widget.js +4 -2
  17. package/lib/esm/extensions/markdown/link/link-widget.js.map +1 -1
  18. package/lib/esm/extensions/markdown/markdown-decoration.js +5 -10
  19. package/lib/esm/extensions/markdown/markdown-decoration.js.map +1 -1
  20. package/lib/esm/extensions/markdown/markdown-state.js +4 -5
  21. package/lib/esm/extensions/markdown/markdown-state.js.map +1 -1
  22. package/lib/esm/lib/utils/random-string.js +13 -0
  23. package/lib/esm/lib/utils/random-string.js.map +1 -0
  24. package/lib/index.d.ts +5 -0
  25. package/package.json +1 -1
  26. package/lib/cjs/index-D7RdBXAA.js.map +0 -1
@@ -75,6 +75,17 @@ function isInRange(ranges, text) {
75
75
  return ranges.some((range) => isRangeOverlap([range.from, range.to], text));
76
76
  }
77
77
 
78
+ function randomString(length = 10) {
79
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
80
+ let result = "";
81
+ let counter = 0;
82
+ while (counter < length) {
83
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
84
+ counter += 1;
85
+ }
86
+ return result;
87
+ }
88
+
78
89
  function saveDispatch(dispatch) {
79
90
  queueMicrotask(() => {
80
91
  dispatch();
@@ -806,13 +817,12 @@ const horizontalDecorationPlugin = {
806
817
 
807
818
  const openedImageEffect = state.StateEffect.define();
808
819
  const openedLinkEffect = state.StateEffect.define();
809
- const imageSrcGetterEffect = state.StateEffect.define();
810
820
  const markdownState = state.StateField.define({
811
821
  create() {
812
822
  return {
813
823
  openedImage: undefined,
814
- imageSrcGetter: undefined,
815
824
  openedLink: undefined,
825
+ uniqueId: randomString(10),
816
826
  };
817
827
  },
818
828
  update(value, transaction) {
@@ -820,8 +830,6 @@ const markdownState = state.StateField.define({
820
830
  for (const effect of transaction.effects) {
821
831
  if (effect.is(openedImageEffect))
822
832
  newValue.openedImage = effect.value;
823
- if (effect.is(imageSrcGetterEffect))
824
- newValue.imageSrcGetter = effect.value;
825
833
  if (effect.is(openedLinkEffect))
826
834
  newValue.openedLink = effect.value;
827
835
  }
@@ -835,8 +843,8 @@ const CODE_OF_END_IMAGE_TEXT = 93; // ]
835
843
  const CODE_OF_START_IMAGE_URL = 40; // (
836
844
  const CODE_OF_END_IMAGE_URL = 41; // )
837
845
 
838
- const INTERVAL_DELAY = 10000;
839
846
  const IMAGE_NODES = {};
847
+ const INTERVAL_DELAY = 10000;
840
848
  const EXISTING_WIDGETS = new Set();
841
849
  let interval = null;
842
850
  class ImageWidget extends view.WidgetType {
@@ -844,25 +852,30 @@ class ImageWidget extends view.WidgetType {
844
852
  link;
845
853
  from;
846
854
  to;
855
+ uniqueId;
856
+ fullLine;
847
857
  imageSrcGetter;
848
858
  view;
849
- constructor(text, link, from, to, imageSrcGetter, view) {
859
+ constructor(text, link, from, to, uniqueId, fullLine, imageSrcGetter, view) {
850
860
  super();
851
861
  this.text = text;
852
862
  this.link = link;
853
863
  this.from = from;
854
864
  this.to = to;
865
+ this.uniqueId = uniqueId;
866
+ this.fullLine = fullLine;
855
867
  this.imageSrcGetter = imageSrcGetter;
856
868
  this.view = view;
857
869
  }
858
870
  get key() {
859
- return `${this.link}:${this.text}:${this.from}:${this.to}`;
871
+ return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;
860
872
  }
861
873
  get src() {
862
874
  return this.imageSrcGetter ? this.imageSrcGetter(this.link) : this.link;
863
875
  }
864
876
  eq(widget) {
865
- const image = IMAGE_NODES[this.key];
877
+ const container = IMAGE_NODES[this.key];
878
+ const image = container?.image;
866
879
  if (!image)
867
880
  return false;
868
881
  delete IMAGE_NODES[this.key];
@@ -885,25 +898,33 @@ class ImageWidget extends view.WidgetType {
885
898
  }
886
899
  toDOM() {
887
900
  EXISTING_WIDGETS.add(this.key);
888
- let image = IMAGE_NODES[this.key];
889
- if (image) {
901
+ let container = IMAGE_NODES[this.key];
902
+ let image = container?.image;
903
+ if (image && container) {
890
904
  if (image.src !== this.src) {
891
905
  image.src = this.src;
892
906
  }
893
907
  if (image.alt !== this.text)
894
908
  image.alt = this.text;
895
- return image;
909
+ return container;
896
910
  }
897
911
  image = document.createElement("img");
898
912
  image.classList.add(styles.image);
899
913
  image.alt = this.text;
900
914
  image.src = this.src;
901
915
  image.style.maxWidth = "100%";
902
- this.registerListeners(image);
903
- IMAGE_NODES[this.key] = image;
916
+ container = document.createElement("span");
917
+ container.appendChild(image);
918
+ container.image = image;
919
+ if (this.fullLine) {
920
+ container.style.width = "100%";
921
+ container.style.display = "inline-block";
922
+ }
923
+ this.registerListeners(container);
924
+ IMAGE_NODES[this.key] = container;
904
925
  if (!interval)
905
926
  interval = setInterval(garbageCollectorInterval, INTERVAL_DELAY);
906
- return image;
927
+ return container;
907
928
  }
908
929
  destroy() {
909
930
  EXISTING_WIDGETS.delete(this.key);
@@ -921,6 +942,7 @@ class ImageWidget extends view.WidgetType {
921
942
  };
922
943
  }
923
944
  }
945
+ /** for disable cache */
924
946
  function garbageCollectorInterval() {
925
947
  for (const [key, node] of Object.entries(IMAGE_NODES)) {
926
948
  if (EXISTING_WIDGETS.has(key) || !node)
@@ -1020,15 +1042,17 @@ function handleClick$1(view, text, link, key, event) {
1020
1042
  return false;
1021
1043
  }
1022
1044
 
1023
- function getImageDecorations({ decorations, node, view }) {
1045
+ function getImageDecorations({ decorations, node, view, settings }) {
1024
1046
  if (node.name !== NAME_OF_IMAGE) {
1025
1047
  return;
1026
1048
  }
1027
1049
  const { text, url } = parseInfo(view, node);
1028
- const imageSrcGetter = view.state.field(markdownState).imageSrcGetter;
1050
+ const uniqueId = view.state.field(markdownState).uniqueId;
1051
+ const line = view.lineBlockAt(node.from);
1052
+ const fullLine = line.from === node.from && line.to === node.to;
1029
1053
  decorations.push(getWidgetDecorationOptions({
1030
1054
  range: [node.to],
1031
- widget: new ImageWidget(text, url, node.from, node.to, imageSrcGetter, view),
1055
+ widget: new ImageWidget(text, url, node.from, node.to, uniqueId, fullLine, settings.imageSrcGetter, view),
1032
1056
  }));
1033
1057
  }
1034
1058
  function getImageSelectionDecorations({ decorations, node, view, forceActive, }) {
@@ -1037,7 +1061,8 @@ function getImageSelectionDecorations({ decorations, node, view, forceActive, })
1037
1061
  }
1038
1062
  const { text, url } = parseInfo(view, node);
1039
1063
  const openedImage = view.state.field(markdownState).openedImage;
1040
- const key = `${url}:${text}:${node.from}:${node.to}`;
1064
+ const uniqueId = view.state.field(markdownState).uniqueId;
1065
+ const key = `${url}:${text}:${uniqueId}:${node.from}:${node.to}`;
1041
1066
  const isOpened = openedImage && openedImage === key;
1042
1067
  if (isOpened) {
1043
1068
  return void decorations.push(getMarkDecoration({
@@ -1105,12 +1130,12 @@ function getItalicDecorations({ decorations, node }) {
1105
1130
  range: [node.from, node.to],
1106
1131
  }));
1107
1132
  }
1108
- function getItalicSelectionDecorations({ decorations, node, view, forceActive, }) {
1133
+ function getItalicSelectionDecorations({ decorations, node, view, forceActive, settings, }) {
1109
1134
  if (node.name !== NAME_OF_ITALIC) {
1110
1135
  return;
1111
1136
  }
1112
- if (checkIsSeveralEmphasis({ decorations, node, view, forceActive })) {
1113
- return void splitEmphasis({ decorations, node, view, forceActive });
1137
+ if (checkIsSeveralEmphasis({ decorations, node, view, forceActive, settings })) {
1138
+ return void splitEmphasis({ decorations, node, view, forceActive, settings });
1114
1139
  }
1115
1140
  let step = 1;
1116
1141
  const startText = view.state.doc.sliceString(node.from, node.from + 3);
@@ -1139,7 +1164,7 @@ function checkIsSeveralEmphasis({ node, view }) {
1139
1164
  return true;
1140
1165
  return false;
1141
1166
  }
1142
- function splitEmphasis({ decorations, node, view, forceActive }) {
1167
+ function splitEmphasis({ decorations, node, view, forceActive, settings, }) {
1143
1168
  const text = view.state.doc.sliceString(node.from, node.to);
1144
1169
  let marks = 0;
1145
1170
  let pos = 0;
@@ -1153,12 +1178,14 @@ function splitEmphasis({ decorations, node, view, forceActive }) {
1153
1178
  view,
1154
1179
  node: { ...node, name: node.name, from: node.from, to: node.from + pos },
1155
1180
  forceActive,
1181
+ settings,
1156
1182
  });
1157
1183
  getItalicSelectionDecorations({
1158
1184
  decorations,
1159
1185
  view,
1160
1186
  node: { ...node, name: node.name, from: node.from + pos, to: node.to },
1161
1187
  forceActive,
1188
+ settings,
1162
1189
  });
1163
1190
  }
1164
1191
  const italicDecorationPlugin = {
@@ -1196,17 +1223,19 @@ class LinkWidget extends view.WidgetType {
1196
1223
  link;
1197
1224
  from;
1198
1225
  to;
1226
+ uniqueId;
1199
1227
  view;
1200
- constructor(text, link, from, to, view) {
1228
+ constructor(text, link, from, to, uniqueId, view) {
1201
1229
  super();
1202
1230
  this.text = text;
1203
1231
  this.link = link;
1204
1232
  this.from = from;
1205
1233
  this.to = to;
1234
+ this.uniqueId = uniqueId;
1206
1235
  this.view = view;
1207
1236
  }
1208
1237
  get key() {
1209
- return `${this.link}:${this.text}:${this.from}:${this.to}`;
1238
+ return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;
1210
1239
  }
1211
1240
  eq(widget) {
1212
1241
  const anchor = LINK_NODES[this.key];
@@ -1348,7 +1377,7 @@ function handleClick(view, text, link, key, event) {
1348
1377
  return false;
1349
1378
  }
1350
1379
 
1351
- function getLinkSelectionDecorations({ decorations, node, view, forceActive, }) {
1380
+ function getLinkSelectionDecorations({ decorations, node, view, forceActive, settings, }) {
1352
1381
  if (node.name !== NAME_OF_LINK) {
1353
1382
  return;
1354
1383
  }
@@ -1375,11 +1404,12 @@ function getLinkSelectionDecorations({ decorations, node, view, forceActive, })
1375
1404
  urlCoordinates.to = pos;
1376
1405
  }
1377
1406
  if (urlCoordinates.from === -1 || urlCoordinates.to === -1)
1378
- return void getLinkLabelSelectionDecoration({ decorations, forceActive, node, view });
1407
+ return void getLinkLabelSelectionDecoration({ decorations, forceActive, node, view, settings });
1379
1408
  const text = content.substring(textCoordinates.from, textCoordinates.to);
1380
1409
  const url = content.substring(urlCoordinates.from, urlCoordinates.to);
1381
1410
  const openedLink = view.state.field(markdownState).openedLink;
1382
- const key = `${url}:${text}:${node.from}:${node.to}`;
1411
+ const uniqueId = view.state.field(markdownState).uniqueId;
1412
+ const key = `${url}:${text}:${uniqueId}:${node.from}:${node.to}`;
1383
1413
  const isOpened = openedLink && openedLink === key;
1384
1414
  if (isOpened) {
1385
1415
  return void decorations.push(getMarkDecoration({
@@ -1394,7 +1424,7 @@ function getLinkSelectionDecorations({ decorations, node, view, forceActive, })
1394
1424
  !isInRange(view.state.selection.ranges, [node.from, node.to])) {
1395
1425
  decorations.push(getReplaceDecoration({
1396
1426
  range: [node.from, node.to],
1397
- widget: new LinkWidget(text, url, node.from, node.to, view),
1427
+ widget: new LinkWidget(text, url, node.from, node.to, uniqueId, view),
1398
1428
  }));
1399
1429
  }
1400
1430
  else {
@@ -1415,7 +1445,8 @@ function getAutoLinkSelectionDecorations({ decorations, node, view, forceActive,
1415
1445
  return;
1416
1446
  const url = view.state.doc.sliceString(node.from + 1, node.to - 1);
1417
1447
  const openedLink = view.state.field(markdownState).openedLink;
1418
- const key = `${url}:${url}:${node.from}:${node.to}`;
1448
+ const uniqueId = view.state.field(markdownState).uniqueId;
1449
+ const key = `${url}:${url}:${uniqueId}:${node.from}:${node.to}`;
1419
1450
  const isOpened = openedLink && openedLink === key;
1420
1451
  if (isOpened) {
1421
1452
  return void decorations.push(getMarkDecoration({
@@ -1430,7 +1461,7 @@ function getAutoLinkSelectionDecorations({ decorations, node, view, forceActive,
1430
1461
  !isInRange(view.state.selection.ranges, [node.from, node.to])) {
1431
1462
  decorations.push(getReplaceDecoration({
1432
1463
  range: [node.from, node.to],
1433
- widget: new LinkWidget(url, url, node.from, node.to, view),
1464
+ widget: new LinkWidget(url, url, node.from, node.to, uniqueId, view),
1434
1465
  }));
1435
1466
  }
1436
1467
  else {
@@ -1679,7 +1710,7 @@ const SKIP_MARKS = new Set([
1679
1710
  "HeaderMark",
1680
1711
  "TaskMarker",
1681
1712
  ]);
1682
- function createDecorationsGetter() {
1713
+ function createDecorationsGetter(settings) {
1683
1714
  let markdownDecorationsCache = [];
1684
1715
  let markdownSelectionDecorationsCache = [];
1685
1716
  function getDecorations(view$1, isChanged, mouseReleased) {
@@ -1700,7 +1731,7 @@ function createDecorationsGetter() {
1700
1731
  return;
1701
1732
  /** Decoration by change content */
1702
1733
  if (processDecorations)
1703
- decorationFunctions.forEach((f) => f({ decorations, node, view: view$1 }));
1734
+ decorationFunctions.forEach((f) => f({ decorations, node, view: view$1, settings }));
1704
1735
  /** Decoration by selection content */
1705
1736
  if (processSelectionDecorations)
1706
1737
  selectionDecorationFunctions.forEach((f) => f({
@@ -1708,6 +1739,7 @@ function createDecorationsGetter() {
1708
1739
  node,
1709
1740
  view: view$1,
1710
1741
  forceActive: isReadonly,
1742
+ settings,
1711
1743
  }));
1712
1744
  },
1713
1745
  });
@@ -1722,7 +1754,7 @@ function createDecorationsGetter() {
1722
1754
  }
1723
1755
  return getDecorations;
1724
1756
  }
1725
- const markdownDecorationPlugin = (stateConfig) => {
1757
+ const markdownDecorationPlugin = (settings) => {
1726
1758
  return view.ViewPlugin.fromClass(class DecorationMarkdown {
1727
1759
  decorations;
1728
1760
  mouseReleased = true;
@@ -1730,17 +1762,12 @@ const markdownDecorationPlugin = (stateConfig) => {
1730
1762
  view;
1731
1763
  decorationGetter;
1732
1764
  constructor(view) {
1733
- this.decorationGetter = createDecorationsGetter();
1765
+ this.decorationGetter = createDecorationsGetter(settings);
1734
1766
  this.decorations = this.decorationGetter(view, true, this.mouseReleased);
1735
1767
  this.dom = view.dom;
1736
1768
  this.view = view;
1737
1769
  document.addEventListener("mousedown", this.onMouseDown.bind(this));
1738
1770
  document.addEventListener("mouseup", this.onMouseUp.bind(this));
1739
- saveDispatch(() => {
1740
- this.view.dispatch(this.view.state.update({
1741
- effects: [imageSrcGetterEffect.of(stateConfig.imageSrcGetter)],
1742
- }));
1743
- });
1744
1771
  }
1745
1772
  update(update) {
1746
1773
  const isDocumentChanged = update.docChanged ||
@@ -1797,7 +1824,7 @@ const initExtensions = async ({ onBlur, onChange, onFocus, onEnter, onEscape, re
1797
1824
  light,
1798
1825
  }),
1799
1826
  new Promise((resolve) => {
1800
- void Promise.resolve().then(() => require('./index-nYYQ5dvl.js')).then(({ initMarkdown }) => {
1827
+ void Promise.resolve().then(() => require('./index-DU8JMAfc.js')).then(({ initMarkdown }) => {
1801
1828
  resolve(initMarkdown({ languages, imageSrcGetter }));
1802
1829
  });
1803
1830
  }),
@@ -1998,4 +2025,4 @@ exports.Editor = Editor;
1998
2025
  exports.NAME_OF_MENTION = NAME_OF_MENTION;
1999
2026
  exports.markdownDecorationPlugin = markdownDecorationPlugin;
2000
2027
  exports.markdownState = markdownState;
2001
- //# sourceMappingURL=index-D7RdBXAA.js.map
2028
+ //# sourceMappingURL=index-BgxbH3r2.js.map