@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.
- package/lib/cjs/{index-D7RdBXAA.js → index-BgxbH3r2.js} +68 -41
- package/lib/cjs/index-BgxbH3r2.js.map +1 -0
- package/lib/cjs/{index-nYYQ5dvl.js → index-DU8JMAfc.js} +2 -2
- package/lib/cjs/{index-nYYQ5dvl.js.map → index-DU8JMAfc.js.map} +1 -1
- package/lib/cjs/index.js +1 -1
- package/lib/esm/extensions/markdown/image/image-decoration.js +7 -4
- package/lib/esm/extensions/markdown/image/image-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/image/image-widget.js +24 -10
- package/lib/esm/extensions/markdown/image/image-widget.js.map +1 -1
- package/lib/esm/extensions/markdown/italic/italic-decoration.js +6 -4
- package/lib/esm/extensions/markdown/italic/italic-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/link/auto-link-decoration.js +3 -2
- package/lib/esm/extensions/markdown/link/auto-link-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/link/link-decoration.js +5 -4
- package/lib/esm/extensions/markdown/link/link-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/link/link-widget.js +4 -2
- package/lib/esm/extensions/markdown/link/link-widget.js.map +1 -1
- package/lib/esm/extensions/markdown/markdown-decoration.js +5 -10
- package/lib/esm/extensions/markdown/markdown-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/markdown-state.js +4 -5
- package/lib/esm/extensions/markdown/markdown-state.js.map +1 -1
- package/lib/esm/lib/utils/random-string.js +13 -0
- package/lib/esm/lib/utils/random-string.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/package.json +1 -1
- 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
|
|
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
|
|
889
|
-
|
|
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
|
|
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
|
-
|
|
903
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 = (
|
|
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-
|
|
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-
|
|
2028
|
+
//# sourceMappingURL=index-BgxbH3r2.js.map
|