@krainovsd/markdown-editor 0.3.1 → 0.4.0
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-DXevyHeZ.js → index-CXENq_0E.js} +10 -6
- package/lib/cjs/index-CXENq_0E.js.map +1 -0
- package/lib/cjs/{index-nRNnOuav.js → index-Dj0jRUGF.js} +465 -38
- package/lib/cjs/index-Dj0jRUGF.js.map +1 -0
- package/lib/cjs/index.js +2 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/extensions/auto-completes/custom/tag-auto-complete.js +33 -0
- package/lib/esm/extensions/auto-completes/custom/tag-auto-complete.js.map +1 -0
- package/lib/esm/extensions/auto-completes/init-auto-complete.js +27 -0
- package/lib/esm/extensions/auto-completes/init-auto-complete.js.map +1 -0
- package/lib/esm/extensions/init-extensions.js +3 -1
- package/lib/esm/extensions/init-extensions.js.map +1 -1
- package/lib/esm/extensions/keymaps/custom/bold-key-map.js +56 -0
- package/lib/esm/extensions/keymaps/custom/bold-key-map.js.map +1 -0
- package/lib/esm/extensions/keymaps/custom/italic-key-map.js +57 -0
- package/lib/esm/extensions/keymaps/custom/italic-key-map.js.map +1 -0
- package/lib/esm/extensions/keymaps/custom/link-key-map.js +28 -0
- package/lib/esm/extensions/keymaps/custom/link-key-map.js.map +1 -0
- package/lib/esm/extensions/keymaps/init-key-map.js +4 -1
- package/lib/esm/extensions/keymaps/init-key-map.js.map +1 -1
- package/lib/esm/extensions/markdown/blockquote/blockquote-constants.js +1 -1
- package/lib/esm/extensions/markdown/blockquote/blockquote-constants.js.map +1 -1
- package/lib/esm/extensions/markdown/bold/bold-constants.js +1 -1
- package/lib/esm/extensions/markdown/bold/bold-constants.js.map +1 -1
- package/lib/esm/extensions/markdown/code/code-constants.js +3 -1
- package/lib/esm/extensions/markdown/code/code-constants.js.map +1 -1
- package/lib/esm/extensions/markdown/code/code-decoration.js +32 -1
- package/lib/esm/extensions/markdown/code/code-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/image/image-decoration.js +2 -3
- package/lib/esm/extensions/markdown/image/image-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/image/image-widget.js +47 -4
- 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/link-decoration.js +2 -2
- package/lib/esm/extensions/markdown/link/link-decoration.js.map +1 -1
- package/lib/esm/extensions/markdown/link/link-widget.js +23 -0
- 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 +1 -5
- package/lib/esm/extensions/markdown/markdown-state.js.map +1 -1
- package/lib/esm/extensions/markdown/mention/mention-constants.js +4 -3
- package/lib/esm/extensions/markdown/mention/mention-constants.js.map +1 -1
- package/lib/esm/extensions/markdown/mention/mention-parser.js +8 -5
- package/lib/esm/extensions/markdown/mention/mention-parser.js.map +1 -1
- package/lib/esm/extensions/markdown/styles.module.scss.js +2 -2
- package/lib/esm/extensions/theme/theme-constants.js +2 -0
- package/lib/esm/extensions/theme/theme-constants.js.map +1 -1
- package/lib/esm/extensions/theme/themes/get-dark-theme.js +2 -0
- package/lib/esm/extensions/theme/themes/get-dark-theme.js.map +1 -1
- package/lib/esm/extensions/theme/themes/get-light-theme.js +2 -0
- package/lib/esm/extensions/theme/themes/get-light-theme.js.map +1 -1
- package/lib/esm/extensions/theme/themes/get-theme-template.js +6 -0
- package/lib/esm/extensions/theme/themes/get-theme-template.js.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/lib/utils/overlap-mark.js +148 -0
- package/lib/esm/lib/utils/overlap-mark.js.map +1 -0
- package/lib/esm/module/Editor/Editor.js +1 -0
- package/lib/esm/module/Editor/Editor.js.map +1 -1
- package/lib/index.d.ts +14 -1
- package/package.json +2 -1
- package/lib/cjs/index-DXevyHeZ.js.map +0 -1
- package/lib/cjs/index-nRNnOuav.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import '@codemirror/state';
|
|
2
|
+
import '@codemirror/view';
|
|
3
|
+
import { saveDispatch } from '../../../lib/utils/save-dispatch.js';
|
|
4
|
+
import { overlapMark } from '../../../lib/utils/overlap-mark.js';
|
|
5
|
+
|
|
6
|
+
const BOLD_MARK_STAR = "*".codePointAt(0);
|
|
7
|
+
const BOLD_MARK_DASH = "_".codePointAt(0);
|
|
8
|
+
const SHIFT = 2;
|
|
9
|
+
const insertBoldMarker = ({ state, dispatch }) => {
|
|
10
|
+
const changes = [];
|
|
11
|
+
const { from, to } = state.selection.ranges[0];
|
|
12
|
+
if (from === to)
|
|
13
|
+
return true;
|
|
14
|
+
const { end, start, marked, originalText } = overlapMark({
|
|
15
|
+
marks: [BOLD_MARK_DASH, BOLD_MARK_STAR],
|
|
16
|
+
requireMatched: [SHIFT],
|
|
17
|
+
shift: SHIFT,
|
|
18
|
+
state,
|
|
19
|
+
});
|
|
20
|
+
if (marked) {
|
|
21
|
+
if (~start) {
|
|
22
|
+
changes.push({ from: start, to: start + SHIFT, insert: "" });
|
|
23
|
+
}
|
|
24
|
+
if (~end) {
|
|
25
|
+
changes.push({ from: end, to: end + SHIFT, insert: "" });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const markedText = `**${originalText}**`;
|
|
30
|
+
changes.push({ from, to, insert: markedText });
|
|
31
|
+
}
|
|
32
|
+
saveDispatch(() => {
|
|
33
|
+
const startSelection = ~start ? start : from;
|
|
34
|
+
const endSelection = ~end ? end - (~start ? SHIFT : 0) : to - (~start ? SHIFT : 0);
|
|
35
|
+
dispatch(state.update({
|
|
36
|
+
changes,
|
|
37
|
+
selection: !marked
|
|
38
|
+
? {
|
|
39
|
+
anchor: from + SHIFT,
|
|
40
|
+
head: to + SHIFT,
|
|
41
|
+
}
|
|
42
|
+
: {
|
|
43
|
+
anchor: startSelection,
|
|
44
|
+
head: endSelection,
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
});
|
|
48
|
+
return true;
|
|
49
|
+
};
|
|
50
|
+
const boldKeymap = {
|
|
51
|
+
key: "Mod-b",
|
|
52
|
+
run: insertBoldMarker,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { boldKeymap };
|
|
56
|
+
//# sourceMappingURL=bold-key-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bold-key-map.js","sources":["../../../../../src/extensions/keymaps/custom/bold-key-map.ts"],"sourcesContent":["import { type ChangeSpec, type StateCommand } from \"@codemirror/state\";\nimport { type KeyBinding } from \"@codemirror/view\";\nimport { utils } from \"@/lib\";\nimport { saveDispatch } from \"@/lib/utils\";\n\nconst BOLD_MARK_STAR = \"*\".codePointAt(0);\nconst BOLD_MARK_DASH = \"_\".codePointAt(0);\nconst SHIFT = 2;\n\nconst insertBoldMarker: StateCommand = ({ state, dispatch }) => {\n const changes: ChangeSpec[] = [];\n const { from, to } = state.selection.ranges[0];\n if (from === to) return true;\n\n const { end, start, marked, originalText } = utils.overlapMark({\n marks: [BOLD_MARK_DASH, BOLD_MARK_STAR],\n requireMatched: [SHIFT],\n shift: SHIFT,\n state,\n });\n\n if (marked) {\n if (~start) {\n changes.push({ from: start, to: start + SHIFT, insert: \"\" });\n }\n if (~end) {\n changes.push({ from: end, to: end + SHIFT, insert: \"\" });\n }\n } else {\n const markedText = `**${originalText}**`;\n changes.push({ from, to, insert: markedText });\n }\n\n saveDispatch(() => {\n const startSelection = ~start ? start : from;\n const endSelection = ~end ? end - (~start ? SHIFT : 0) : to - (~start ? SHIFT : 0);\n\n dispatch(\n state.update({\n changes,\n selection: !marked\n ? {\n anchor: from + SHIFT,\n head: to + SHIFT,\n }\n : {\n anchor: startSelection,\n head: endSelection,\n },\n }),\n );\n });\n\n return true;\n};\n\nexport const boldKeymap: KeyBinding = {\n key: \"Mod-b\",\n run: insertBoldMarker,\n};\n"],"names":["utils.overlapMark"],"mappings":";;;;;AAKA,MAAM,cAAc,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;AACzC,MAAM,cAAc,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;AACzC,MAAM,KAAK,GAAG,CAAC;AAEf,MAAM,gBAAgB,GAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAI;IAC7D,MAAM,OAAO,GAAiB,EAAE;AAChC,IAAA,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AAE5B,IAAA,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAGA,WAAiB,CAAC;AAC7D,QAAA,KAAK,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;QACvC,cAAc,EAAE,CAAC,KAAK,CAAC;AACvB,QAAA,KAAK,EAAE,KAAK;QACZ,KAAK;AACN,KAAA,CAAC;IAEF,IAAI,MAAM,EAAE;QACV,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;QAE9D,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;;SAErD;AACL,QAAA,MAAM,UAAU,GAAG,CAAK,EAAA,EAAA,YAAY,IAAI;AACxC,QAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;;IAGhD,YAAY,CAAC,MAAK;AAChB,QAAA,MAAM,cAAc,GAAG,CAAC,KAAK,GAAG,KAAK,GAAG,IAAI;AAC5C,QAAA,MAAM,YAAY,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;AAElF,QAAA,QAAQ,CACN,KAAK,CAAC,MAAM,CAAC;YACX,OAAO;YACP,SAAS,EAAE,CAAC;AACV,kBAAE;oBACE,MAAM,EAAE,IAAI,GAAG,KAAK;oBACpB,IAAI,EAAE,EAAE,GAAG,KAAK;AACjB;AACH,kBAAE;AACE,oBAAA,MAAM,EAAE,cAAc;AACtB,oBAAA,IAAI,EAAE,YAAY;AACnB,iBAAA;AACN,SAAA,CAAC,CACH;AACH,KAAC,CAAC;AAEF,IAAA,OAAO,IAAI;AACb,CAAC;AAEY,MAAA,UAAU,GAAe;AACpC,IAAA,GAAG,EAAE,OAAO;AACZ,IAAA,GAAG,EAAE,gBAAgB;;;;;"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import '@codemirror/state';
|
|
2
|
+
import '@codemirror/view';
|
|
3
|
+
import { saveDispatch } from '../../../lib/utils/save-dispatch.js';
|
|
4
|
+
import { overlapMark } from '../../../lib/utils/overlap-mark.js';
|
|
5
|
+
|
|
6
|
+
const ITALIC_MARK_STAR = "*".codePointAt(0);
|
|
7
|
+
const ITALIC_MARK_DASH = "_".codePointAt(0);
|
|
8
|
+
const SHIFT_COUPLE = 3;
|
|
9
|
+
const SHIFT_ALONE = 1;
|
|
10
|
+
const insertItalicMarker = ({ state, dispatch }) => {
|
|
11
|
+
const changes = [];
|
|
12
|
+
const { from, to } = state.selection.ranges[0];
|
|
13
|
+
if (from === to)
|
|
14
|
+
return true;
|
|
15
|
+
const { end, start, marked, originalText } = overlapMark({
|
|
16
|
+
marks: [ITALIC_MARK_STAR, ITALIC_MARK_DASH],
|
|
17
|
+
requireMatched: [SHIFT_ALONE, SHIFT_COUPLE],
|
|
18
|
+
shift: SHIFT_COUPLE,
|
|
19
|
+
state,
|
|
20
|
+
});
|
|
21
|
+
if (marked) {
|
|
22
|
+
if (~start) {
|
|
23
|
+
changes.push({ from: start, to: start + SHIFT_ALONE, insert: "" });
|
|
24
|
+
}
|
|
25
|
+
if (~end) {
|
|
26
|
+
changes.push({ from: end, to: end + SHIFT_ALONE, insert: "" });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const markedText = `*${originalText}*`;
|
|
31
|
+
changes.push({ from, to, insert: markedText });
|
|
32
|
+
}
|
|
33
|
+
saveDispatch(() => {
|
|
34
|
+
const startSelection = ~start ? start : from;
|
|
35
|
+
const endSelection = ~end ? end - (~start ? SHIFT_ALONE : 0) : to - (~start ? SHIFT_ALONE : 0);
|
|
36
|
+
dispatch(state.update({
|
|
37
|
+
changes,
|
|
38
|
+
selection: !marked
|
|
39
|
+
? {
|
|
40
|
+
anchor: from + SHIFT_ALONE,
|
|
41
|
+
head: to + SHIFT_ALONE,
|
|
42
|
+
}
|
|
43
|
+
: {
|
|
44
|
+
anchor: startSelection,
|
|
45
|
+
head: endSelection,
|
|
46
|
+
},
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
49
|
+
return true;
|
|
50
|
+
};
|
|
51
|
+
const italicKeymap = {
|
|
52
|
+
key: "Mod-i",
|
|
53
|
+
run: insertItalicMarker,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export { italicKeymap };
|
|
57
|
+
//# sourceMappingURL=italic-key-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"italic-key-map.js","sources":["../../../../../src/extensions/keymaps/custom/italic-key-map.ts"],"sourcesContent":["import { type ChangeSpec, type StateCommand } from \"@codemirror/state\";\nimport { type KeyBinding } from \"@codemirror/view\";\nimport { utils } from \"@/lib\";\nimport { saveDispatch } from \"@/lib/utils\";\n\nconst ITALIC_MARK_STAR = \"*\".codePointAt(0);\nconst ITALIC_MARK_DASH = \"_\".codePointAt(0);\nconst SHIFT_COUPLE = 3;\nconst SHIFT_ALONE = 1;\n\nconst insertItalicMarker: StateCommand = ({ state, dispatch }) => {\n const changes: ChangeSpec[] = [];\n const { from, to } = state.selection.ranges[0];\n if (from === to) return true;\n\n const { end, start, marked, originalText } = utils.overlapMark({\n marks: [ITALIC_MARK_STAR, ITALIC_MARK_DASH],\n requireMatched: [SHIFT_ALONE, SHIFT_COUPLE],\n shift: SHIFT_COUPLE,\n state,\n });\n\n if (marked) {\n if (~start) {\n changes.push({ from: start, to: start + SHIFT_ALONE, insert: \"\" });\n }\n if (~end) {\n changes.push({ from: end, to: end + SHIFT_ALONE, insert: \"\" });\n }\n } else {\n const markedText = `*${originalText}*`;\n changes.push({ from, to, insert: markedText });\n }\n\n saveDispatch(() => {\n const startSelection = ~start ? start : from;\n const endSelection = ~end ? end - (~start ? SHIFT_ALONE : 0) : to - (~start ? SHIFT_ALONE : 0);\n\n dispatch(\n state.update({\n changes,\n selection: !marked\n ? {\n anchor: from + SHIFT_ALONE,\n head: to + SHIFT_ALONE,\n }\n : {\n anchor: startSelection,\n head: endSelection,\n },\n }),\n );\n });\n\n return true;\n};\n\nexport const italicKeymap: KeyBinding = {\n key: \"Mod-i\",\n run: insertItalicMarker,\n};\n"],"names":["utils.overlapMark"],"mappings":";;;;;AAKA,MAAM,gBAAgB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,MAAM,gBAAgB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,MAAM,YAAY,GAAG,CAAC;AACtB,MAAM,WAAW,GAAG,CAAC;AAErB,MAAM,kBAAkB,GAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAI;IAC/D,MAAM,OAAO,GAAiB,EAAE;AAChC,IAAA,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AAE5B,IAAA,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAGA,WAAiB,CAAC;AAC7D,QAAA,KAAK,EAAE,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;AAC3C,QAAA,cAAc,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;AAC3C,QAAA,KAAK,EAAE,YAAY;QACnB,KAAK;AACN,KAAA,CAAC;IAEF,IAAI,MAAM,EAAE;QACV,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;QAEpE,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;;SAE3D;AACL,QAAA,MAAM,UAAU,GAAG,CAAI,CAAA,EAAA,YAAY,GAAG;AACtC,QAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;;IAGhD,YAAY,CAAC,MAAK;AAChB,QAAA,MAAM,cAAc,GAAG,CAAC,KAAK,GAAG,KAAK,GAAG,IAAI;AAC5C,QAAA,MAAM,YAAY,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC;AAE9F,QAAA,QAAQ,CACN,KAAK,CAAC,MAAM,CAAC;YACX,OAAO;YACP,SAAS,EAAE,CAAC;AACV,kBAAE;oBACE,MAAM,EAAE,IAAI,GAAG,WAAW;oBAC1B,IAAI,EAAE,EAAE,GAAG,WAAW;AACvB;AACH,kBAAE;AACE,oBAAA,MAAM,EAAE,cAAc;AACtB,oBAAA,IAAI,EAAE,YAAY;AACnB,iBAAA;AACN,SAAA,CAAC,CACH;AACH,KAAC,CAAC;AAEF,IAAA,OAAO,IAAI;AACb,CAAC;AAEY,MAAA,YAAY,GAAe;AACtC,IAAA,GAAG,EAAE,OAAO;AACZ,IAAA,GAAG,EAAE,kBAAkB;;;;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import '@codemirror/view';
|
|
2
|
+
import { saveDispatch } from '../../../lib/utils/save-dispatch.js';
|
|
3
|
+
|
|
4
|
+
const insertLinkWrapper = ({ state, dispatch }) => {
|
|
5
|
+
const changes = [];
|
|
6
|
+
const { from, to } = state.selection.ranges[0];
|
|
7
|
+
if (from === to)
|
|
8
|
+
return true;
|
|
9
|
+
const content = state.sliceDoc(from, to);
|
|
10
|
+
const wrapper = `[${content}]()`;
|
|
11
|
+
changes.push({ from, to, insert: wrapper });
|
|
12
|
+
saveDispatch(() => {
|
|
13
|
+
dispatch(state.update({
|
|
14
|
+
changes,
|
|
15
|
+
selection: {
|
|
16
|
+
anchor: to + 3,
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
});
|
|
20
|
+
return true;
|
|
21
|
+
};
|
|
22
|
+
const linkKeymap = {
|
|
23
|
+
key: "Mod-k",
|
|
24
|
+
run: insertLinkWrapper,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { linkKeymap };
|
|
28
|
+
//# sourceMappingURL=link-key-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-key-map.js","sources":["../../../../../src/extensions/keymaps/custom/link-key-map.ts"],"sourcesContent":["import type { ChangeSpec, StateCommand } from \"@codemirror/state\";\nimport type { KeyBinding } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\n\nconst insertLinkWrapper: StateCommand = ({ state, dispatch }) => {\n const changes: ChangeSpec[] = [];\n const { from, to } = state.selection.ranges[0];\n if (from === to) return true;\n const content = state.sliceDoc(from, to);\n\n const wrapper = `[${content}]()`;\n changes.push({ from, to, insert: wrapper });\n\n saveDispatch(() => {\n dispatch(\n state.update({\n changes,\n selection: {\n anchor: to + 3,\n },\n }),\n );\n });\n\n return true;\n};\n\nexport const linkKeymap: KeyBinding = {\n key: \"Mod-k\",\n run: insertLinkWrapper,\n};\n"],"names":[],"mappings":";;;AAIA,MAAM,iBAAiB,GAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAI;IAC9D,MAAM,OAAO,GAAiB,EAAE;AAChC,IAAA,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;AAExC,IAAA,MAAM,OAAO,GAAG,CAAI,CAAA,EAAA,OAAO,KAAK;AAChC,IAAA,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAE3C,YAAY,CAAC,MAAK;AAChB,QAAA,QAAQ,CACN,KAAK,CAAC,MAAM,CAAC;YACX,OAAO;AACP,YAAA,SAAS,EAAE;gBACT,MAAM,EAAE,EAAE,GAAG,CAAC;AACf,aAAA;AACF,SAAA,CAAC,CACH;AACH,KAAC,CAAC;AAEF,IAAA,OAAO,IAAI;AACb,CAAC;AAEY,MAAA,UAAU,GAAe;AACpC,IAAA,GAAG,EAAE,OAAO;AACZ,IAAA,GAAG,EAAE,iBAAiB;;;;;"}
|
|
@@ -4,6 +4,9 @@ import { saveDispatch } from '../../lib/utils/save-dispatch.js';
|
|
|
4
4
|
import { VimModeCompartment, ThemeCompartment } from '../compartments/index.js';
|
|
5
5
|
import { getDarkTheme } from '../theme/themes/get-dark-theme.js';
|
|
6
6
|
import { getLightTheme } from '../theme/themes/get-light-theme.js';
|
|
7
|
+
import { boldKeymap } from './custom/bold-key-map.js';
|
|
8
|
+
import { italicKeymap } from './custom/italic-key-map.js';
|
|
9
|
+
import { linkKeymap } from './custom/link-key-map.js';
|
|
7
10
|
|
|
8
11
|
let vimMode = false;
|
|
9
12
|
let theme = "light";
|
|
@@ -11,7 +14,7 @@ const initKeyMaps = async ({ onEnter, onEscape, multiCursorMode, keyMaps, defaul
|
|
|
11
14
|
vimMode = initialVimMode;
|
|
12
15
|
theme = initialTheme;
|
|
13
16
|
/** tab */
|
|
14
|
-
const keyBindings = [indentWithTab];
|
|
17
|
+
const keyBindings = [indentWithTab, boldKeymap, italicKeymap, linkKeymap];
|
|
15
18
|
/** standard */
|
|
16
19
|
keyBindings.push(...standardKeymap.map((keyMap) => {
|
|
17
20
|
if (keyMap.key === "Enter" && onEnter) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-key-map.js","sources":["../../../../src/extensions/keymaps/init-key-map.ts"],"sourcesContent":["import { historyKeymap, indentWithTab, standardKeymap } from \"@codemirror/commands\";\nimport type { Extension } from \"@codemirror/state\";\nimport { type EditorView, type KeyBinding, drawSelection, keymap } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { ThemeCompartment, VimModeCompartment } from \"../compartments\";\nimport { type EditorTheme, type ThemeOptions, getDarkTheme, getLightTheme } from \"../theme\";\n\nexport type InitKeyMapsOptions = {\n onEnter?: HandleEnterKeyMapEditorFunction;\n onEscape?: HandleEscapeKeyMapEditorFunction;\n keyMaps?: CustomKeyMap[];\n defaultKeyMaps?: DefaultKeyMapsOptions;\n};\n\nexport type CustomKeyMap = KeyBinding;\nexport type HandleEnterKeyMapEditorFunction = (view: EditorView) => boolean;\nexport type HandleEscapeKeyMapEditorFunction = (view: EditorView) => boolean;\nexport type DefaultKeyMapsOptions = {\n vim?: boolean;\n theme?: boolean;\n};\n\nlet vimMode = false;\nlet theme: EditorTheme = \"light\";\n\nexport const initKeyMaps = async ({\n onEnter,\n onEscape,\n multiCursorMode,\n keyMaps,\n defaultKeyMaps,\n theme: initialTheme,\n vimMode: initialVimMode,\n dark,\n light,\n}: InitKeyMapsOptions & {\n multiCursorMode: boolean;\n vimMode: boolean;\n theme: EditorTheme;\n dark?: ThemeOptions;\n light?: ThemeOptions;\n}): Promise<Extension> => {\n vimMode = initialVimMode;\n theme = initialTheme;\n\n /** tab */\n const keyBindings: CustomKeyMap[] = [indentWithTab];\n\n /** standard */\n keyBindings.push(\n ...standardKeymap.map<CustomKeyMap>((keyMap) => {\n if (keyMap.key === \"Enter\" && onEnter) {\n return {\n key: \"Enter\",\n shift: keyMap.run,\n run: (view) => {\n const response = onEnter(view);\n\n if (response) keyMap.run?.(view);\n\n return response;\n },\n };\n }\n\n return keyMap;\n }),\n );\n\n /** vim */\n if (defaultKeyMaps?.vim)\n keyBindings.push({\n key: \"Mod-Alt-v\",\n run: (view) => {\n vimMode = !vimMode;\n\n void import(\"@replit/codemirror-vim\").then(({ vim }) => {\n saveDispatch(() => {\n view.dispatch({\n effects: VimModeCompartment.reconfigure(\n vimMode ? [vim({ status: true }), drawSelection()] : [],\n ),\n });\n });\n });\n\n return true;\n },\n });\n\n /** theme */\n if (defaultKeyMaps?.theme)\n keyBindings.push({\n key: \"Mod-Alt-a\",\n run: (view) => {\n theme = theme === \"light\" ? \"dark\" : \"light\";\n saveDispatch(() => {\n view.dispatch({\n effects: ThemeCompartment.reconfigure(\n theme === \"dark\"\n ? getDarkTheme({\n dark,\n light,\n theme,\n })\n : getLightTheme({\n dark,\n light,\n theme,\n }),\n ),\n });\n });\n\n return true;\n },\n });\n\n /** escape */\n if (onEscape) {\n keyBindings.push({\n key: \"Escape\",\n run: (view) => {\n return onEscape(view);\n },\n });\n }\n\n /** custom */\n if (keyMaps) {\n keyBindings.push(...keyMaps);\n }\n\n /** history */\n if (multiCursorMode) {\n const { yUndoManagerKeymap } = await import(\"y-codemirror.next\");\n keyBindings.push(...yUndoManagerKeymap);\n } else {\n keyBindings.push(...historyKeymap);\n }\n\n return keymap.of(keyBindings);\n};\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init-key-map.js","sources":["../../../../src/extensions/keymaps/init-key-map.ts"],"sourcesContent":["import { historyKeymap, indentWithTab, standardKeymap } from \"@codemirror/commands\";\nimport type { Extension } from \"@codemirror/state\";\nimport { type EditorView, type KeyBinding, drawSelection, keymap } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { ThemeCompartment, VimModeCompartment } from \"../compartments\";\nimport { type EditorTheme, type ThemeOptions, getDarkTheme, getLightTheme } from \"../theme\";\nimport { boldKeymap, italicKeymap, linkKeymap } from \"./custom\";\n\nexport type InitKeyMapsOptions = {\n onEnter?: HandleEnterKeyMapEditorFunction;\n onEscape?: HandleEscapeKeyMapEditorFunction;\n keyMaps?: CustomKeyMap[];\n defaultKeyMaps?: DefaultKeyMapsOptions;\n};\n\nexport type CustomKeyMap = KeyBinding;\nexport type HandleEnterKeyMapEditorFunction = (view: EditorView) => boolean;\nexport type HandleEscapeKeyMapEditorFunction = (view: EditorView) => boolean;\nexport type DefaultKeyMapsOptions = {\n vim?: boolean;\n theme?: boolean;\n};\n\nlet vimMode = false;\nlet theme: EditorTheme = \"light\";\n\nexport const initKeyMaps = async ({\n onEnter,\n onEscape,\n multiCursorMode,\n keyMaps,\n defaultKeyMaps,\n theme: initialTheme,\n vimMode: initialVimMode,\n dark,\n light,\n}: InitKeyMapsOptions & {\n multiCursorMode: boolean;\n vimMode: boolean;\n theme: EditorTheme;\n dark?: ThemeOptions;\n light?: ThemeOptions;\n}): Promise<Extension> => {\n vimMode = initialVimMode;\n theme = initialTheme;\n\n /** tab */\n const keyBindings: CustomKeyMap[] = [indentWithTab, boldKeymap, italicKeymap, linkKeymap];\n\n /** standard */\n keyBindings.push(\n ...standardKeymap.map<CustomKeyMap>((keyMap) => {\n if (keyMap.key === \"Enter\" && onEnter) {\n return {\n key: \"Enter\",\n shift: keyMap.run,\n run: (view) => {\n const response = onEnter(view);\n\n if (response) keyMap.run?.(view);\n\n return response;\n },\n };\n }\n\n return keyMap;\n }),\n );\n\n /** vim */\n if (defaultKeyMaps?.vim)\n keyBindings.push({\n key: \"Mod-Alt-v\",\n run: (view) => {\n vimMode = !vimMode;\n\n void import(\"@replit/codemirror-vim\").then(({ vim }) => {\n saveDispatch(() => {\n view.dispatch({\n effects: VimModeCompartment.reconfigure(\n vimMode ? [vim({ status: true }), drawSelection()] : [],\n ),\n });\n });\n });\n\n return true;\n },\n });\n\n /** theme */\n if (defaultKeyMaps?.theme)\n keyBindings.push({\n key: \"Mod-Alt-a\",\n run: (view) => {\n theme = theme === \"light\" ? \"dark\" : \"light\";\n saveDispatch(() => {\n view.dispatch({\n effects: ThemeCompartment.reconfigure(\n theme === \"dark\"\n ? getDarkTheme({\n dark,\n light,\n theme,\n })\n : getLightTheme({\n dark,\n light,\n theme,\n }),\n ),\n });\n });\n\n return true;\n },\n });\n\n /** escape */\n if (onEscape) {\n keyBindings.push({\n key: \"Escape\",\n run: (view) => {\n return onEscape(view);\n },\n });\n }\n\n /** custom */\n if (keyMaps) {\n keyBindings.push(...keyMaps);\n }\n\n /** history */\n if (multiCursorMode) {\n const { yUndoManagerKeymap } = await import(\"y-codemirror.next\");\n keyBindings.push(...yUndoManagerKeymap);\n } else {\n keyBindings.push(...historyKeymap);\n }\n\n return keymap.of(keyBindings);\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blockquote-constants.js","sources":["../../../../../src/extensions/markdown/blockquote/blockquote-constants.ts"],"sourcesContent":["export const NAME_OF_BLOCKQUOTE_MARK = \"QuoteMark\";\nexport const CODE_OF_SPACE =
|
|
1
|
+
{"version":3,"file":"blockquote-constants.js","sources":["../../../../../src/extensions/markdown/blockquote/blockquote-constants.ts"],"sourcesContent":["export const NAME_OF_BLOCKQUOTE_MARK = \"QuoteMark\";\nexport const CODE_OF_SPACE = \" \".codePointAt(0);\nexport const CODE_OF_BLOCKQUOTE_MARK = 62; // >\n"],"names":[],"mappings":"AAAO,MAAM,uBAAuB,GAAG;AAC1B,MAAA,aAAa,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;AACjC,MAAA,uBAAuB,GAAG,GAAG;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bold-constants.js","sources":["../../../../../src/extensions/markdown/bold/bold-constants.ts"],"sourcesContent":["export const NAME_OF_BOLD = \"StrongEmphasis\";\nexport const LIST_OF_BOLD_MARKS = new Set([
|
|
1
|
+
{"version":3,"file":"bold-constants.js","sources":["../../../../../src/extensions/markdown/bold/bold-constants.ts"],"sourcesContent":["export const NAME_OF_BOLD = \"StrongEmphasis\";\nexport const LIST_OF_BOLD_MARKS = new Set([\"_\".codePointAt(0), \"*\".codePointAt(0)]);\n"],"names":[],"mappings":"AAAO,MAAM,YAAY,GAAG;MACf,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;;;;"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const NAME_OF_FENCED_CODE = "FencedCode";
|
|
2
2
|
const NAME_OF_INLINE_CODE = "InlineCode";
|
|
3
|
+
const NAME_OF_BLOCK_CODE = "CodeBlock";
|
|
4
|
+
const CODE_OF_SPACE = " ".codePointAt(0);
|
|
3
5
|
const CODE_OF_CODE_MARK = 96; // `
|
|
4
6
|
|
|
5
|
-
export { CODE_OF_CODE_MARK, NAME_OF_FENCED_CODE, NAME_OF_INLINE_CODE };
|
|
7
|
+
export { CODE_OF_CODE_MARK, CODE_OF_SPACE, NAME_OF_BLOCK_CODE, NAME_OF_FENCED_CODE, NAME_OF_INLINE_CODE };
|
|
6
8
|
//# sourceMappingURL=code-constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-constants.js","sources":["../../../../../src/extensions/markdown/code/code-constants.ts"],"sourcesContent":["export const NAME_OF_FENCED_CODE = \"FencedCode\";\nexport const NAME_OF_INLINE_CODE = \"InlineCode\";\nexport const CODE_OF_CODE_MARK = 96; // `\n"],"names":[],"mappings":"AAAO,MAAM,mBAAmB,GAAG;AAC5B,MAAM,mBAAmB,GAAG;
|
|
1
|
+
{"version":3,"file":"code-constants.js","sources":["../../../../../src/extensions/markdown/code/code-constants.ts"],"sourcesContent":["export const NAME_OF_FENCED_CODE = \"FencedCode\";\nexport const NAME_OF_INLINE_CODE = \"InlineCode\";\nexport const NAME_OF_BLOCK_CODE = \"CodeBlock\";\nexport const CODE_OF_SPACE = \" \".codePointAt(0);\nexport const CODE_OF_CODE_MARK = 96; // `\n"],"names":[],"mappings":"AAAO,MAAM,mBAAmB,GAAG;AAC5B,MAAM,mBAAmB,GAAG;AAC5B,MAAM,kBAAkB,GAAG;AACrB,MAAA,aAAa,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;AACjC,MAAA,iBAAiB,GAAG,GAAG;;;;"}
|
|
@@ -8,7 +8,7 @@ import { getLineDecoration, getMarkDecoration, getHideDecoration, getWidgetDecor
|
|
|
8
8
|
import { isInRange } from '../../../lib/utils/is-in-range.js';
|
|
9
9
|
import { isRangeOverlap } from '../../../lib/utils/is-range-overlap.js';
|
|
10
10
|
import styles from '../styles.module.scss.js';
|
|
11
|
-
import { NAME_OF_FENCED_CODE, NAME_OF_INLINE_CODE, CODE_OF_CODE_MARK } from './code-constants.js';
|
|
11
|
+
import { NAME_OF_FENCED_CODE, NAME_OF_INLINE_CODE, CODE_OF_CODE_MARK, NAME_OF_BLOCK_CODE, CODE_OF_SPACE } from './code-constants.js';
|
|
12
12
|
import { CodeWidget } from './code-widget.js';
|
|
13
13
|
|
|
14
14
|
function getCodeSelectionDecorations({ decorations, node, view, forceActive, }) {
|
|
@@ -101,8 +101,39 @@ function getCodeSelectionDecorations({ decorations, node, view, forceActive, })
|
|
|
101
101
|
decorations.push(getHideDecoration({ range: [endMarkPosition.from, endMarkPosition.to] }));
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
+
function getCodeBlockDecorations({ decorations, node, view }) {
|
|
105
|
+
if (node.name !== NAME_OF_BLOCK_CODE)
|
|
106
|
+
return;
|
|
107
|
+
const lines = view.viewportLineBlocks.filter((line) => {
|
|
108
|
+
const isOverlap = isRangeOverlap([node.from, node.to], [line.from, line.to]);
|
|
109
|
+
return isOverlap;
|
|
110
|
+
});
|
|
111
|
+
lines.forEach((line) => {
|
|
112
|
+
const content = view.state.sliceDoc(line.from, line.to);
|
|
113
|
+
let startContent = 0;
|
|
114
|
+
let pos = 0;
|
|
115
|
+
while (pos < content.length) {
|
|
116
|
+
if (content.codePointAt(pos) === CODE_OF_SPACE) {
|
|
117
|
+
pos++;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
startContent = pos;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
decorations.push(getMarkDecoration({
|
|
125
|
+
range: [line.from + startContent, line.to],
|
|
126
|
+
style: clsx(styles.code__block, CLASSES.codeBlock),
|
|
127
|
+
}));
|
|
128
|
+
decorations.push(getLineDecoration({
|
|
129
|
+
range: [line.from],
|
|
130
|
+
style: clsx(styles.code__block_line, CLASSES.codeBlockLine),
|
|
131
|
+
}));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
104
134
|
const codeDecorationPlugin = {
|
|
105
135
|
selectionDecorations: [getCodeSelectionDecorations],
|
|
136
|
+
decorations: [getCodeBlockDecorations],
|
|
106
137
|
};
|
|
107
138
|
|
|
108
139
|
export { codeDecorationPlugin };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-decoration.js","sources":["../../../../../src/extensions/markdown/code/code-decoration.ts"],"sourcesContent":["import clsx from \"clsx\";\nimport { CLASSES } from \"@/extensions/theme\";\nimport { utils } from \"@/lib\";\nimport type { DecorationPlugin, GetSelectionDecorationOptions } from \"../markdown-types\";\nimport styles from \"../styles.module.scss\";\nimport { CODE_OF_CODE_MARK, NAME_OF_FENCED_CODE, NAME_OF_INLINE_CODE } from \"./code-constants\";\nimport { CodeWidget } from \"./code-widget\";\n\nfunction getCodeSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_FENCED_CODE && node.name !== NAME_OF_INLINE_CODE) {\n return;\n }\n\n let isOverlapLine = false;\n const startMarkPosition = { from: -1, to: -1 };\n const endMarkPosition = { from: -1, to: -1 };\n const lines = view.viewportLineBlocks.filter((line) => {\n const isOverlap = utils.isRangeOverlap([node.from, node.to], [line.from, line.to]);\n if (isOverlap && utils.isInRange(view.state.selection.ranges, [line.from, line.to]))\n isOverlapLine = true;\n\n return isOverlap;\n });\n let languagePos: [number, number] | undefined;\n let language: string | undefined;\n let codeContent: string | undefined;\n\n const content = view.state.doc.sliceString(node.from, node.to);\n let pos = -1;\n while (\n (startMarkPosition.from === -1 || startMarkPosition.to === -1) &&\n pos >= -1 &&\n pos < content.length\n ) {\n pos++;\n const code = content.charCodeAt(pos);\n\n if (code !== CODE_OF_CODE_MARK && startMarkPosition.from === -1) continue;\n else if (code === CODE_OF_CODE_MARK && startMarkPosition.from === -1)\n startMarkPosition.from = node.from + pos;\n else if (code !== CODE_OF_CODE_MARK && startMarkPosition.from !== -1)\n startMarkPosition.to = node.from + pos;\n }\n\n pos = content.length;\n\n while (\n (endMarkPosition.from === -1 || endMarkPosition.to === -1) &&\n pos >= -1 &&\n pos <= content.length\n ) {\n pos--;\n const code = content.charCodeAt(pos);\n\n if (code !== CODE_OF_CODE_MARK && endMarkPosition.to === -1) continue;\n else if (code === CODE_OF_CODE_MARK && endMarkPosition.to === -1)\n endMarkPosition.to = node.from + pos + 1;\n else if (code !== CODE_OF_CODE_MARK && endMarkPosition.to !== -1)\n endMarkPosition.from = node.from + pos + 1;\n }\n\n if (node.name === NAME_OF_FENCED_CODE) {\n const codeInfo = node.node.getChild(\"CodeInfo\");\n const codeText = node.node.getChild(\"CodeText\");\n\n if (codeInfo) {\n language = view.state.doc.sliceString(codeInfo.from, codeInfo.to);\n languagePos = [codeInfo.from, codeInfo.to];\n }\n if (codeText) codeContent = view.state.doc.sliceString(codeText.from, codeText.to);\n else codeContent = \"\";\n }\n if (node.name === NAME_OF_INLINE_CODE) {\n codeContent = view.state.doc.sliceString(startMarkPosition.to, endMarkPosition.from).trim();\n }\n if (!language) language = \"copy\";\n\n if (lines.length > 1) {\n lines.forEach((line) => {\n decorations.push(\n utils.getLineDecoration({\n style: clsx(styles.code__line, CLASSES.code),\n range: [line.from],\n }),\n );\n });\n } else {\n decorations.push(\n utils.getMarkDecoration({\n style: clsx(styles.code__single, CLASSES.code),\n range: [node.from, node.to],\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n (lines.length > 1 && !isOverlapLine) ||\n (lines.length === 1 && !utils.isInRange(view.state.selection.ranges, [node.from, node.to]))\n ) {\n if (lines.length > 1 && language) {\n if (languagePos) decorations.push(utils.getHideDecoration({ range: languagePos }));\n decorations.push(\n utils.getWidgetDecorationOptions({\n widget: new CodeWidget(language, codeContent),\n range: [node.from],\n }),\n );\n }\n decorations.push(\n utils.getHideDecoration({ range: [startMarkPosition.from, startMarkPosition.to] }),\n );\n decorations.push(\n utils.getHideDecoration({ range: [endMarkPosition.from, endMarkPosition.to] }),\n );\n }\n}\n\nexport const codeDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getCodeSelectionDecorations],\n};\n"],"names":["utils.isRangeOverlap","utils.isInRange","utils.getLineDecoration","utils.getMarkDecoration","utils.getHideDecoration","utils.getWidgetDecorationOptions"],"mappings":";;;;;;;;;;;;;AAQA,SAAS,2BAA2B,CAAC,EACnC,WAAW,EACX,IAAI,EACJ,IAAI,EACJ,WAAW,GACmB,EAAA;AAC9B,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE;QAC1E;;IAGF,IAAI,aAAa,GAAG,KAAK;AACzB,IAAA,MAAM,iBAAiB,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE;AAC9C,IAAA,MAAM,eAAe,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;QACpD,MAAM,SAAS,GAAGA,cAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAClF,IAAI,SAAS,IAAIC,SAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACjF,aAAa,GAAG,IAAI;AAEtB,QAAA,OAAO,SAAS;AAClB,KAAC,CAAC;AACF,IAAA,IAAI,WAAyC;AAC7C,IAAA,IAAI,QAA4B;AAChC,IAAA,IAAI,WAA+B;AAEnC,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC9D,IAAA,IAAI,GAAG,GAAG,CAAC,CAAC;AACZ,IAAA,OACE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,iBAAiB,CAAC,EAAE,KAAK,CAAC,CAAC;QAC7D,GAAG,IAAI,CAAC,CAAC;AACT,QAAA,GAAG,GAAG,OAAO,CAAC,MAAM,EACpB;AACA,QAAA,GAAG,EAAE;QACL,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAEpC,IAAI,IAAI,KAAK,iBAAiB,IAAI,iBAAiB,CAAC,IAAI,KAAK,CAAC,CAAC;YAAE;aAC5D,IAAI,IAAI,KAAK,iBAAiB,IAAI,iBAAiB,CAAC,IAAI,KAAK,CAAC,CAAC;YAClE,iBAAiB,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG;aACrC,IAAI,IAAI,KAAK,iBAAiB,IAAI,iBAAiB,CAAC,IAAI,KAAK,CAAC,CAAC;YAClE,iBAAiB,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG;;AAG1C,IAAA,GAAG,GAAG,OAAO,CAAC,MAAM;AAEpB,IAAA,OACE,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;QACzD,GAAG,IAAI,CAAC,CAAC;AACT,QAAA,GAAG,IAAI,OAAO,CAAC,MAAM,EACrB;AACA,QAAA,GAAG,EAAE;QACL,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAEpC,IAAI,IAAI,KAAK,iBAAiB,IAAI,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;YAAE;aACxD,IAAI,IAAI,KAAK,iBAAiB,IAAI,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;YAC9D,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC;aACrC,IAAI,IAAI,KAAK,iBAAiB,IAAI,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;YAC9D,eAAe,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC;;AAG9C,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAE/C,IAAI,QAAQ,EAAE;AACZ,YAAA,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;YACjE,WAAW,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;;AAE5C,QAAA,IAAI,QAAQ;AAAE,YAAA,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;;YAC7E,WAAW,GAAG,EAAE;;AAEvB,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE;QACrC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE;;AAE7F,IAAA,IAAI,CAAC,QAAQ;QAAE,QAAQ,GAAG,MAAM;AAEhC,IAAA,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AACpB,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACrB,YAAA,WAAW,CAAC,IAAI,CACdC,iBAAuB,CAAC;gBACtB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC;AAC5C,gBAAA,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACnB,aAAA,CAAC,CACH;AACH,SAAC,CAAC;;SACG;AACL,QAAA,WAAW,CAAC,IAAI,CACdC,iBAAuB,CAAC;YACtB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC;YAC9C,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC5B,SAAA,CAAC,CACH;;AAGH,IAAA,IACE,WAAW;QACX,CAAC,IAAI,CAAC,QAAQ;SACb,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;AACpC,SAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAACF,SAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAC3F;QACA,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,EAAE;AAChC,YAAA,IAAI,WAAW;AAAE,gBAAA,WAAW,CAAC,IAAI,CAACG,iBAAuB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;AAClF,YAAA,WAAW,CAAC,IAAI,CACdC,0BAAgC,CAAC;AAC/B,gBAAA,MAAM,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC;AAC7C,gBAAA,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACnB,aAAA,CAAC,CACH;;QAEH,WAAW,CAAC,IAAI,CACdD,iBAAuB,CAAC,EAAE,KAAK,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,CACnF;QACD,WAAW,CAAC,IAAI,CACdA,iBAAuB,CAAC,EAAE,KAAK,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,CAC/E;;AAEL;AAEa,MAAA,oBAAoB,GAAqB;IACpD,oBAAoB,EAAE,CAAC,2BAA2B,CAAC;;;;;"}
|
|
1
|
+
{"version":3,"file":"code-decoration.js","sources":["../../../../../src/extensions/markdown/code/code-decoration.ts"],"sourcesContent":["import clsx from \"clsx\";\nimport { CLASSES } from \"@/extensions/theme\";\nimport { utils } from \"@/lib\";\nimport type {\n DecorationPlugin,\n GetDecorationOptions,\n GetSelectionDecorationOptions,\n} from \"../markdown-types\";\nimport styles from \"../styles.module.scss\";\nimport {\n CODE_OF_CODE_MARK,\n CODE_OF_SPACE,\n NAME_OF_BLOCK_CODE,\n NAME_OF_FENCED_CODE,\n NAME_OF_INLINE_CODE,\n} from \"./code-constants\";\nimport { CodeWidget } from \"./code-widget\";\n\nfunction getCodeSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_FENCED_CODE && node.name !== NAME_OF_INLINE_CODE) {\n return;\n }\n\n let isOverlapLine = false;\n const startMarkPosition = { from: -1, to: -1 };\n const endMarkPosition = { from: -1, to: -1 };\n const lines = view.viewportLineBlocks.filter((line) => {\n const isOverlap = utils.isRangeOverlap([node.from, node.to], [line.from, line.to]);\n if (isOverlap && utils.isInRange(view.state.selection.ranges, [line.from, line.to]))\n isOverlapLine = true;\n\n return isOverlap;\n });\n let languagePos: [number, number] | undefined;\n let language: string | undefined;\n let codeContent: string | undefined;\n\n const content = view.state.doc.sliceString(node.from, node.to);\n let pos = -1;\n while (\n (startMarkPosition.from === -1 || startMarkPosition.to === -1) &&\n pos >= -1 &&\n pos < content.length\n ) {\n pos++;\n const code = content.charCodeAt(pos);\n\n if (code !== CODE_OF_CODE_MARK && startMarkPosition.from === -1) continue;\n else if (code === CODE_OF_CODE_MARK && startMarkPosition.from === -1)\n startMarkPosition.from = node.from + pos;\n else if (code !== CODE_OF_CODE_MARK && startMarkPosition.from !== -1)\n startMarkPosition.to = node.from + pos;\n }\n\n pos = content.length;\n\n while (\n (endMarkPosition.from === -1 || endMarkPosition.to === -1) &&\n pos >= -1 &&\n pos <= content.length\n ) {\n pos--;\n const code = content.charCodeAt(pos);\n\n if (code !== CODE_OF_CODE_MARK && endMarkPosition.to === -1) continue;\n else if (code === CODE_OF_CODE_MARK && endMarkPosition.to === -1)\n endMarkPosition.to = node.from + pos + 1;\n else if (code !== CODE_OF_CODE_MARK && endMarkPosition.to !== -1)\n endMarkPosition.from = node.from + pos + 1;\n }\n\n if (node.name === NAME_OF_FENCED_CODE) {\n const codeInfo = node.node.getChild(\"CodeInfo\");\n const codeText = node.node.getChild(\"CodeText\");\n\n if (codeInfo) {\n language = view.state.doc.sliceString(codeInfo.from, codeInfo.to);\n languagePos = [codeInfo.from, codeInfo.to];\n }\n if (codeText) codeContent = view.state.doc.sliceString(codeText.from, codeText.to);\n else codeContent = \"\";\n }\n if (node.name === NAME_OF_INLINE_CODE) {\n codeContent = view.state.doc.sliceString(startMarkPosition.to, endMarkPosition.from).trim();\n }\n if (!language) language = \"copy\";\n\n if (lines.length > 1) {\n lines.forEach((line) => {\n decorations.push(\n utils.getLineDecoration({\n style: clsx(styles.code__line, CLASSES.code),\n range: [line.from],\n }),\n );\n });\n } else {\n decorations.push(\n utils.getMarkDecoration({\n style: clsx(styles.code__single, CLASSES.code),\n range: [node.from, node.to],\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n (lines.length > 1 && !isOverlapLine) ||\n (lines.length === 1 && !utils.isInRange(view.state.selection.ranges, [node.from, node.to]))\n ) {\n if (lines.length > 1 && language) {\n if (languagePos) decorations.push(utils.getHideDecoration({ range: languagePos }));\n decorations.push(\n utils.getWidgetDecorationOptions({\n widget: new CodeWidget(language, codeContent),\n range: [node.from],\n }),\n );\n }\n decorations.push(\n utils.getHideDecoration({ range: [startMarkPosition.from, startMarkPosition.to] }),\n );\n decorations.push(\n utils.getHideDecoration({ range: [endMarkPosition.from, endMarkPosition.to] }),\n );\n }\n}\n\nfunction getCodeBlockDecorations({ decorations, node, view }: GetDecorationOptions) {\n if (node.name !== NAME_OF_BLOCK_CODE) return;\n\n const lines = view.viewportLineBlocks.filter((line) => {\n const isOverlap = utils.isRangeOverlap([node.from, node.to], [line.from, line.to]);\n\n return isOverlap;\n });\n\n lines.forEach((line) => {\n const content = view.state.sliceDoc(line.from, line.to);\n let startContent = 0;\n let pos = 0;\n\n while (pos < content.length) {\n if (content.codePointAt(pos) === CODE_OF_SPACE) {\n pos++;\n } else {\n startContent = pos;\n break;\n }\n }\n\n decorations.push(\n utils.getMarkDecoration({\n range: [line.from + startContent, line.to],\n style: clsx(styles.code__block, CLASSES.codeBlock),\n }),\n );\n\n decorations.push(\n utils.getLineDecoration({\n range: [line.from],\n style: clsx(styles.code__block_line, CLASSES.codeBlockLine),\n }),\n );\n });\n}\n\nexport const codeDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getCodeSelectionDecorations],\n decorations: [getCodeBlockDecorations],\n};\n"],"names":["utils.isRangeOverlap","utils.isInRange","utils.getLineDecoration","utils.getMarkDecoration","utils.getHideDecoration","utils.getWidgetDecorationOptions"],"mappings":"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"}
|
|
@@ -5,18 +5,17 @@ import { markdownState } from '../markdown-state.js';
|
|
|
5
5
|
import { NAME_OF_IMAGE, CODE_OF_START_IMAGE_TEXT, CODE_OF_START_IMAGE_URL, CODE_OF_END_IMAGE_TEXT, CODE_OF_END_IMAGE_URL } from './image-constants.js';
|
|
6
6
|
import { ImageWidget } from './image-widget.js';
|
|
7
7
|
|
|
8
|
-
function getImageDecorations({ decorations, node, view }) {
|
|
8
|
+
function getImageDecorations({ decorations, node, view, settings }) {
|
|
9
9
|
if (node.name !== NAME_OF_IMAGE) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
const { text, url } = parseInfo(view, node);
|
|
13
|
-
const imageSrcGetter = view.state.field(markdownState).imageSrcGetter;
|
|
14
13
|
const uniqueId = view.state.field(markdownState).uniqueId;
|
|
15
14
|
const line = view.lineBlockAt(node.from);
|
|
16
15
|
const fullLine = line.from === node.from && line.to === node.to;
|
|
17
16
|
decorations.push(getWidgetDecorationOptions({
|
|
18
17
|
range: [node.to],
|
|
19
|
-
widget: new ImageWidget(text, url, node.from, node.to, uniqueId, fullLine, imageSrcGetter, view),
|
|
18
|
+
widget: new ImageWidget(text, url, node.from, node.to, uniqueId, fullLine, settings.imageSrcGetter, view),
|
|
20
19
|
}));
|
|
21
20
|
}
|
|
22
21
|
function getImageSelectionDecorations({ decorations, node, view, forceActive, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-decoration.js","sources":["../../../../../src/extensions/markdown/image/image-decoration.ts"],"sourcesContent":["import { type EditorView } from \"@codemirror/view\";\nimport type { SyntaxNodeRef } from \"@lezer/common\";\nimport { utils } from \"@/lib\";\nimport { markdownState } from \"../markdown-state\";\nimport type {\n DecorationPlugin,\n GetDecorationOptions,\n GetSelectionDecorationOptions,\n} from \"../markdown-types\";\nimport {\n CODE_OF_END_IMAGE_TEXT,\n CODE_OF_END_IMAGE_URL,\n CODE_OF_START_IMAGE_TEXT,\n CODE_OF_START_IMAGE_URL,\n NAME_OF_IMAGE,\n} from \"./image-constants\";\nimport { ImageWidget } from \"./image-widget\";\n\nfunction getImageDecorations({ decorations, node, view }: GetDecorationOptions) {\n if (node.name !== NAME_OF_IMAGE) {\n return;\n }\n\n const { text, url } = parseInfo(view, node);\n const
|
|
1
|
+
{"version":3,"file":"image-decoration.js","sources":["../../../../../src/extensions/markdown/image/image-decoration.ts"],"sourcesContent":["import { type EditorView } from \"@codemirror/view\";\nimport type { SyntaxNodeRef } from \"@lezer/common\";\nimport { utils } from \"@/lib\";\nimport { markdownState } from \"../markdown-state\";\nimport type {\n DecorationPlugin,\n GetDecorationOptions,\n GetSelectionDecorationOptions,\n} from \"../markdown-types\";\nimport {\n CODE_OF_END_IMAGE_TEXT,\n CODE_OF_END_IMAGE_URL,\n CODE_OF_START_IMAGE_TEXT,\n CODE_OF_START_IMAGE_URL,\n NAME_OF_IMAGE,\n} from \"./image-constants\";\nimport { ImageWidget } from \"./image-widget\";\n\nfunction getImageDecorations({ decorations, node, view, settings }: GetDecorationOptions) {\n if (node.name !== NAME_OF_IMAGE) {\n return;\n }\n\n const { text, url } = parseInfo(view, node);\n const uniqueId = view.state.field(markdownState).uniqueId;\n const line = view.lineBlockAt(node.from);\n const fullLine = line.from === node.from && line.to === node.to;\n\n decorations.push(\n utils.getWidgetDecorationOptions({\n range: [node.to],\n widget: new ImageWidget(\n text,\n url,\n node.from,\n node.to,\n uniqueId,\n fullLine,\n settings.imageSrcGetter,\n view,\n ),\n }),\n );\n}\n\nfunction getImageSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_IMAGE) {\n return;\n }\n\n const { text, url } = parseInfo(view, node);\n const openedImage = view.state.field(markdownState).openedImage;\n const uniqueId = view.state.field(markdownState).uniqueId;\n const key = `${url}:${text}:${uniqueId}:${node.from}:${node.to}`;\n const isOpened = openedImage && openedImage === key;\n\n if (isOpened) {\n return void decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n !utils.isInRange(view.state.selection.ranges, [node.from, node.to])\n ) {\n decorations.push(utils.getHideDecoration({ range: [node.from, node.to] }));\n } else {\n decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n}\n\nfunction parseInfo(view: EditorView, node: SyntaxNodeRef) {\n const content = view.state.doc.sliceString(node.from, node.to);\n const textCoordinates = { from: -1, to: -1 };\n const urlCoordinates = { from: -1, to: -1 };\n let pos = -1;\n\n while (pos < content.length) {\n pos++;\n const code = content.charCodeAt(pos);\n\n if (textCoordinates.from === -1 && code === CODE_OF_START_IMAGE_TEXT)\n textCoordinates.from = pos + 1;\n else if (\n urlCoordinates.from === -1 &&\n textCoordinates.to !== -1 &&\n code === CODE_OF_START_IMAGE_URL\n )\n urlCoordinates.from = pos + 1;\n else if (\n textCoordinates.from !== -1 &&\n textCoordinates.to === -1 &&\n code === CODE_OF_END_IMAGE_TEXT\n )\n textCoordinates.to = pos;\n else if (\n urlCoordinates.from !== -1 &&\n urlCoordinates.to === -1 &&\n code === CODE_OF_END_IMAGE_URL\n )\n urlCoordinates.to = pos;\n }\n\n const text = content.substring(textCoordinates.from, textCoordinates.to);\n const url = content.substring(urlCoordinates.from, urlCoordinates.to);\n\n return { text, url };\n}\n\nexport const imageDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getImageSelectionDecorations],\n decorations: [getImageDecorations],\n};\n"],"names":["utils.getWidgetDecorationOptions","utils.getMarkDecoration","utils.isInRange","utils.getHideDecoration"],"mappings":"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"}
|
|
@@ -2,8 +2,12 @@ import { WidgetType } from '@codemirror/view';
|
|
|
2
2
|
import { saveDispatch } from '../../../lib/utils/save-dispatch.js';
|
|
3
3
|
import { openedImageEffect } from '../markdown-state.js';
|
|
4
4
|
import styles from '../styles.module.scss.js';
|
|
5
|
+
import { CODE_OF_START_IMAGE_URL } from './image-constants.js';
|
|
5
6
|
|
|
6
7
|
const IMAGE_NODES = {};
|
|
8
|
+
const INTERVAL_DELAY = 10000;
|
|
9
|
+
const EXISTING_WIDGETS = new Set();
|
|
10
|
+
let interval = null;
|
|
7
11
|
class ImageWidget extends WidgetType {
|
|
8
12
|
text;
|
|
9
13
|
link;
|
|
@@ -36,6 +40,7 @@ class ImageWidget extends WidgetType {
|
|
|
36
40
|
if (!image)
|
|
37
41
|
return false;
|
|
38
42
|
delete IMAGE_NODES[this.key];
|
|
43
|
+
EXISTING_WIDGETS.delete(this.key);
|
|
39
44
|
if (image.src !== widget.src)
|
|
40
45
|
image.src = widget.src;
|
|
41
46
|
if (image.alt !== widget.text)
|
|
@@ -45,13 +50,15 @@ class ImageWidget extends WidgetType {
|
|
|
45
50
|
this.from = widget.from;
|
|
46
51
|
this.to = widget.to;
|
|
47
52
|
this.registerListeners(image);
|
|
48
|
-
IMAGE_NODES[this.key] =
|
|
53
|
+
IMAGE_NODES[this.key] = container;
|
|
54
|
+
EXISTING_WIDGETS.add(this.key);
|
|
49
55
|
return true;
|
|
50
56
|
}
|
|
51
57
|
updateDOM() {
|
|
52
58
|
return true;
|
|
53
59
|
}
|
|
54
60
|
toDOM() {
|
|
61
|
+
EXISTING_WIDGETS.add(this.key);
|
|
55
62
|
let container = IMAGE_NODES[this.key];
|
|
56
63
|
let image = container?.image;
|
|
57
64
|
if (image && container) {
|
|
@@ -76,11 +83,12 @@ class ImageWidget extends WidgetType {
|
|
|
76
83
|
}
|
|
77
84
|
this.registerListeners(container);
|
|
78
85
|
IMAGE_NODES[this.key] = container;
|
|
86
|
+
if (!interval)
|
|
87
|
+
interval = setInterval(garbageCollectorInterval, INTERVAL_DELAY);
|
|
79
88
|
return container;
|
|
80
89
|
}
|
|
81
|
-
destroy(
|
|
82
|
-
delete
|
|
83
|
-
dom.destroy?.();
|
|
90
|
+
destroy() {
|
|
91
|
+
EXISTING_WIDGETS.delete(this.key);
|
|
84
92
|
}
|
|
85
93
|
registerListeners(image) {
|
|
86
94
|
image.clearListeners?.();
|
|
@@ -95,6 +103,19 @@ class ImageWidget extends WidgetType {
|
|
|
95
103
|
};
|
|
96
104
|
}
|
|
97
105
|
}
|
|
106
|
+
/** for disable cache */
|
|
107
|
+
function garbageCollectorInterval() {
|
|
108
|
+
for (const [key, node] of Object.entries(IMAGE_NODES)) {
|
|
109
|
+
if (EXISTING_WIDGETS.has(key) || !node)
|
|
110
|
+
continue;
|
|
111
|
+
delete IMAGE_NODES[key];
|
|
112
|
+
node.destroy?.();
|
|
113
|
+
}
|
|
114
|
+
if (Object.keys(IMAGE_NODES).length === 0 && interval) {
|
|
115
|
+
clearInterval(interval);
|
|
116
|
+
interval = null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
98
119
|
/** recursively find the link text node in line */
|
|
99
120
|
function getTextNode(text, link, key, line) {
|
|
100
121
|
if (!line)
|
|
@@ -137,6 +158,28 @@ function isCorrectNode(text, link, node) {
|
|
|
137
158
|
function selectLink({ link, node, selection, start }) {
|
|
138
159
|
const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);
|
|
139
160
|
const endPosition = startPosition + link.length;
|
|
161
|
+
if (startPosition === 0 && endPosition === 0) {
|
|
162
|
+
const content = node.textContent;
|
|
163
|
+
if (!content)
|
|
164
|
+
return;
|
|
165
|
+
let startPosition = 0;
|
|
166
|
+
let pos = 0;
|
|
167
|
+
while (pos < content.length) {
|
|
168
|
+
if (content.codePointAt(pos) !== CODE_OF_START_IMAGE_URL) {
|
|
169
|
+
pos++;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
startPosition = pos + 1;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const range = document.createRange();
|
|
177
|
+
range.setStart(node, startPosition);
|
|
178
|
+
range.collapse(true);
|
|
179
|
+
selection.removeAllRanges();
|
|
180
|
+
selection.addRange(range);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
140
183
|
const range = document.createRange();
|
|
141
184
|
range.setStart(node, startPosition);
|
|
142
185
|
range.setEnd(node, endPosition);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-widget.js","sources":["../../../../../src/extensions/markdown/image/image-widget.ts"],"sourcesContent":["import { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedImageEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\n\nconst IMAGE_NODES: Record<string, ImageContainerElement | undefined> = {};\n\ninterface ImageContainerElement extends HTMLSpanElement {\n clearListeners?: () => void;\n destroy?: () => void;\n image?: HTMLImageElement;\n}\n\nexport class ImageWidget extends WidgetType {\n constructor(\n private text: string,\n private link: string,\n private from: number,\n private to: number,\n private uniqueId: string,\n private fullLine: boolean,\n private imageSrcGetter: ((src: string) => string) | undefined,\n private view: EditorView,\n ) {\n super();\n }\n\n get key() {\n return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;\n }\n\n get src() {\n return this.imageSrcGetter ? this.imageSrcGetter(this.link) : this.link;\n }\n\n eq(widget: ImageWidget): boolean {\n const container = IMAGE_NODES[this.key];\n const image = container?.image;\n\n if (!image) return false;\n\n delete IMAGE_NODES[this.key];\n\n if (image.src !== widget.src) image.src = widget.src;\n if (image.alt !== widget.text) image.alt = widget.text;\n\n this.link = widget.link;\n this.text = widget.text;\n this.from = widget.from;\n this.to = widget.to;\n\n this.registerListeners(image);\n IMAGE_NODES[this.key] = image;\n\n return true;\n }\n\n updateDOM(): boolean {\n return true;\n }\n\n toDOM(): HTMLElement {\n let container = IMAGE_NODES[this.key];\n let image = container?.image;\n\n if (image && container) {\n if (image.src !== this.src) {\n image.src = this.src;\n }\n if (image.alt !== this.text) image.alt = this.text;\n\n return container;\n }\n\n image = document.createElement(\"img\");\n image.classList.add(styles.image);\n image.alt = this.text;\n image.src = this.src;\n image.style.maxWidth = \"100%\";\n\n container = document.createElement(\"span\") as ImageContainerElement;\n container.appendChild(image);\n container.image = image;\n if (this.fullLine) {\n container.style.width = \"100%\";\n container.style.display = \"inline-block\";\n }\n\n this.registerListeners(container);\n IMAGE_NODES[this.key] = container;\n\n return container;\n }\n\n destroy(dom: ImageContainerElement): void {\n delete IMAGE_NODES[this.key];\n dom.destroy?.();\n }\n\n registerListeners(image: ImageContainerElement) {\n image.clearListeners?.();\n const abortController = new AbortController();\n image.addEventListener(\n \"mousedown\",\n (event) => handleClick(this.view, this.text, this.link, this.key, event),\n { signal: abortController.signal },\n );\n image.clearListeners = () => {\n abortController.abort();\n };\n image.destroy = () => {\n image.clearListeners?.();\n image.remove();\n };\n }\n}\n\n/** recursively find the link text node in line */\nfunction getTextNode(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): ChildNode | null {\n if (!line) return null;\n const textNodeContainer = getTextNodeContainer(text, link, key, line);\n if (!textNodeContainer) return null;\n\n for (const node of Array.from(textNodeContainer.childNodes)) {\n if (isCorrectNode(text, link, node)) {\n return node;\n }\n }\n\n return null;\n}\n\nfunction getTextNodeContainer(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): HTMLElement | null {\n if (!line) return null;\n\n for (const node of Array.from(line.childNodes)) {\n if (node instanceof HTMLElement && node.getAttribute(\"data-id\") === key) {\n return node;\n }\n\n if (node.nodeType !== 3) {\n const inner = getTextNodeContainer(text, link, key, node);\n if (inner) return inner;\n }\n }\n\n return null;\n}\n\nfunction isCorrectNode(\n text: string,\n link: string,\n node: ChildNode | Node | null | undefined,\n): node is ChildNode | Node {\n if (!node) return false;\n\n const textContent = node?.textContent;\n\n return Boolean(\n node &&\n textContent &&\n node.nodeType === 3 &&\n textContent.includes(link) &&\n textContent.includes(text),\n );\n}\n\ntype SelectLinkOptions = {\n node: ChildNode | Node;\n selection: Selection;\n start?: number;\n link: string;\n};\nfunction selectLink({ link, node, selection, start }: SelectLinkOptions) {\n const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);\n const endPosition = startPosition + link.length;\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.setEnd(node, endPosition);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction handleClick(\n view: EditorView | undefined,\n text: string,\n link: string,\n key: string,\n event: MouseEvent,\n) {\n const selection = window.getSelection();\n\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const target = event.target as HTMLImageElement;\n const parent = target.parentNode;\n let line: HTMLElement | null = parent as HTMLElement | null;\n\n /** recursively find line that contains link */\n while (line && !line.classList.contains(\"cm-line\")) {\n line = line.parentNode as HTMLElement | null;\n }\n\n const editor = Array.from(document.querySelectorAll(\".cm-editor\")).find((element) =>\n element.contains(target),\n );\n\n if (!selection || !editor || !parent) return;\n\n const textNode = getTextNode(text, link, key, line);\n\n if (textNode) {\n return void selectLink({ selection, link, node: textNode });\n }\n\n saveDispatch(() => {\n if (!view) return;\n view.dispatch(view.state.update({ effects: openedImageEffect.of(key) }));\n\n const textNode = getTextNode(text, link, key, line);\n if (textNode) {\n selectLink({ selection, link, node: textNode });\n }\n\n requestAnimationFrame(() => {\n saveDispatch(() => {\n if (view) view.dispatch(view.state.update({ effects: openedImageEffect.of(undefined) }));\n });\n });\n });\n\n return false;\n}\n"],"names":[],"mappings":";;;;;AAKA,MAAM,WAAW,GAAsD,EAAE;AAQnE,MAAO,WAAY,SAAQ,UAAU,CAAA;AAE/B,IAAA,IAAA;AACA,IAAA,IAAA;AACA,IAAA,IAAA;AACA,IAAA,EAAA;AACA,IAAA,QAAA;AACA,IAAA,QAAA;AACA,IAAA,cAAA;AACA,IAAA,IAAA;AARV,IAAA,WAAA,CACU,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,EAAU,EACV,QAAgB,EAChB,QAAiB,EACjB,cAAqD,EACrD,IAAgB,EAAA;AAExB,QAAA,KAAK,EAAE;QATC,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAE,CAAA,EAAA,GAAF,EAAE;QACF,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAc,CAAA,cAAA,GAAd,cAAc;QACd,IAAI,CAAA,IAAA,GAAJ,IAAI;;AAKd,IAAA,IAAI,GAAG,GAAA;QACL,OAAO,CAAA,EAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAI,CAAA,EAAA,IAAI,CAAC,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAA,CAAE;;AAG7E,IAAA,IAAI,GAAG,GAAA;QACL,OAAO,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;;AAGzE,IAAA,EAAE,CAAC,MAAmB,EAAA;QACpB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AACvC,QAAA,MAAM,KAAK,GAAG,SAAS,EAAE,KAAK;AAE9B,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,KAAK;AAExB,QAAA,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AAE5B,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG;AAAE,YAAA,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG;AACpD,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI;AAAE,YAAA,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI;AAEtD,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE;AAEnB,QAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC7B,QAAA,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK;AAE7B,QAAA,OAAO,IAAI;;IAGb,SAAS,GAAA;AACP,QAAA,OAAO,IAAI;;IAGb,KAAK,GAAA;QACH,IAAI,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AACrC,QAAA,IAAI,KAAK,GAAG,SAAS,EAAE,KAAK;AAE5B,QAAA,IAAI,KAAK,IAAI,SAAS,EAAE;YACtB,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE;AAC1B,gBAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG;;AAEtB,YAAA,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI;AAAE,gBAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI;AAElD,YAAA,OAAO,SAAS;;AAGlB,QAAA,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACrC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AACjC,QAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI;AACrB,QAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG;AACpB,QAAA,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM;AAE7B,QAAA,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAA0B;AACnE,QAAA,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC;AAC5B,QAAA,SAAS,CAAC,KAAK,GAAG,KAAK;AACvB,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC9B,YAAA,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,cAAc;;AAG1C,QAAA,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC;AACjC,QAAA,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS;AAEjC,QAAA,OAAO,SAAS;;AAGlB,IAAA,OAAO,CAAC,GAA0B,EAAA;AAChC,QAAA,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AAC5B,QAAA,GAAG,CAAC,OAAO,IAAI;;AAGjB,IAAA,iBAAiB,CAAC,KAA4B,EAAA;AAC5C,QAAA,KAAK,CAAC,cAAc,IAAI;AACxB,QAAA,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE;AAC7C,QAAA,KAAK,CAAC,gBAAgB,CACpB,WAAW,EACX,CAAC,KAAK,KAAK,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EACxE,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,CACnC;AACD,QAAA,KAAK,CAAC,cAAc,GAAG,MAAK;YAC1B,eAAe,CAAC,KAAK,EAAE;AACzB,SAAC;AACD,QAAA,KAAK,CAAC,OAAO,GAAG,MAAK;AACnB,YAAA,KAAK,CAAC,cAAc,IAAI;YACxB,KAAK,CAAC,MAAM,EAAE;AAChB,SAAC;;AAEJ;AAED;AACA,SAAS,WAAW,CAClB,IAAY,EACZ,IAAY,EACZ,GAAW,EACX,IAAyC,EAAA;AAEzC,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AACtB,IAAA,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;AACrE,IAAA,IAAI,CAAC,iBAAiB;AAAE,QAAA,OAAO,IAAI;AAEnC,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE;QAC3D,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;AACnC,YAAA,OAAO,IAAI;;;AAIf,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,oBAAoB,CAC3B,IAAY,EACZ,IAAY,EACZ,GAAW,EACX,IAAyC,EAAA;AAEzC,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AAEtB,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AAC9C,QAAA,IAAI,IAAI,YAAY,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE;AACvE,YAAA,OAAO,IAAI;;AAGb,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE;AACvB,YAAA,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;AACzD,YAAA,IAAI,KAAK;AAAE,gBAAA,OAAO,KAAK;;;AAI3B,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,aAAa,CACpB,IAAY,EACZ,IAAY,EACZ,IAAyC,EAAA;AAEzC,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,KAAK;AAEvB,IAAA,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW;IAErC,OAAO,OAAO,CACZ,IAAI;QACF,WAAW;QACX,IAAI,CAAC,QAAQ,KAAK,CAAC;AACnB,QAAA,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1B,QAAA,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC7B;AACH;AAQA,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAqB,EAAA;AACrE,IAAA,MAAM,aAAa,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;AACvE,IAAA,MAAM,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC,MAAM;AAE/C,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE;AACpC,IAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;AACnC,IAAA,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC;IAC/B,SAAS,CAAC,eAAe,EAAE;AAC3B,IAAA,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3B;AAEA,SAAS,WAAW,CAClB,IAA4B,EAC5B,IAAY,EACZ,IAAY,EACZ,GAAW,EACX,KAAiB,EAAA;AAEjB,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE;AAEvC,IAAA,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE;QACpE;;IAGF,KAAK,CAAC,eAAe,EAAE;IACvB,KAAK,CAAC,cAAc,EAAE;AACtB,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAA0B;AAC/C,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU;IAChC,IAAI,IAAI,GAAuB,MAA4B;;AAG3D,IAAA,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AAClD,QAAA,IAAI,GAAG,IAAI,CAAC,UAAgC;;AAG9C,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAC9E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CACzB;AAED,IAAA,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE;AAEtC,IAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;IAEnD,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,KAAK,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;IAG7D,YAAY,CAAC,MAAK;AAChB,QAAA,IAAI,CAAC,IAAI;YAAE;QACX,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAExE,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;QACnD,IAAI,QAAQ,EAAE;YACZ,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;QAGjD,qBAAqB,CAAC,MAAK;YACzB,YAAY,CAAC,MAAK;AAChB,gBAAA,IAAI,IAAI;oBAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAC1F,aAAC,CAAC;AACJ,SAAC,CAAC;AACJ,KAAC,CAAC;AAEF,IAAA,OAAO,KAAK;AACd;;;;"}
|
|
1
|
+
{"version":3,"file":"image-widget.js","sources":["../../../../../src/extensions/markdown/image/image-widget.ts"],"sourcesContent":["import { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedImageEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\nimport { CODE_OF_START_IMAGE_URL } from \"./image-constants\";\n\nconst IMAGE_NODES: Record<string, ImageContainerElement | undefined> = {};\nconst INTERVAL_DELAY = 10000;\nconst EXISTING_WIDGETS: Set<string> = new Set();\nlet interval: NodeJS.Timeout | null = null;\ninterface ImageContainerElement extends HTMLSpanElement {\n clearListeners?: () => void;\n destroy?: () => void;\n image?: HTMLImageElement;\n}\n\nexport class ImageWidget extends WidgetType {\n constructor(\n private text: string,\n private link: string,\n private from: number,\n private to: number,\n private uniqueId: string,\n private fullLine: boolean,\n private imageSrcGetter: ((src: string) => string) | undefined,\n private view: EditorView,\n ) {\n super();\n }\n\n get key() {\n return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;\n }\n\n get src() {\n return this.imageSrcGetter ? this.imageSrcGetter(this.link) : this.link;\n }\n\n eq(widget: ImageWidget): boolean {\n const container = IMAGE_NODES[this.key];\n const image = container?.image;\n\n if (!image) return false;\n\n delete IMAGE_NODES[this.key];\n EXISTING_WIDGETS.delete(this.key);\n\n if (image.src !== widget.src) image.src = widget.src;\n if (image.alt !== widget.text) image.alt = widget.text;\n\n this.link = widget.link;\n this.text = widget.text;\n this.from = widget.from;\n this.to = widget.to;\n\n this.registerListeners(image);\n IMAGE_NODES[this.key] = container;\n EXISTING_WIDGETS.add(this.key);\n\n return true;\n }\n\n updateDOM(): boolean {\n return true;\n }\n\n toDOM(): HTMLElement {\n EXISTING_WIDGETS.add(this.key);\n let container = IMAGE_NODES[this.key];\n let image = container?.image;\n\n if (image && container) {\n if (image.src !== this.src) {\n image.src = this.src;\n }\n if (image.alt !== this.text) image.alt = this.text;\n\n return container;\n }\n\n image = document.createElement(\"img\");\n image.classList.add(styles.image);\n image.alt = this.text;\n image.src = this.src;\n image.style.maxWidth = \"100%\";\n\n container = document.createElement(\"span\") as ImageContainerElement;\n container.appendChild(image);\n container.image = image;\n if (this.fullLine) {\n container.style.width = \"100%\";\n container.style.display = \"inline-block\";\n }\n\n this.registerListeners(container);\n IMAGE_NODES[this.key] = container;\n\n if (!interval) interval = setInterval(garbageCollectorInterval, INTERVAL_DELAY);\n\n return container;\n }\n\n destroy(): void {\n EXISTING_WIDGETS.delete(this.key);\n }\n\n registerListeners(image: ImageContainerElement) {\n image.clearListeners?.();\n const abortController = new AbortController();\n image.addEventListener(\n \"mousedown\",\n (event) => handleClick(this.view, this.text, this.link, this.key, event),\n { signal: abortController.signal },\n );\n image.clearListeners = () => {\n abortController.abort();\n };\n image.destroy = () => {\n image.clearListeners?.();\n image.remove();\n };\n }\n}\n\n/** for disable cache */\nfunction garbageCollectorInterval() {\n for (const [key, node] of Object.entries(IMAGE_NODES)) {\n if (EXISTING_WIDGETS.has(key) || !node) continue;\n delete IMAGE_NODES[key];\n node.destroy?.();\n }\n\n if (Object.keys(IMAGE_NODES).length === 0 && interval) {\n clearInterval(interval);\n interval = null;\n }\n}\n\n/** recursively find the link text node in line */\nfunction getTextNode(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): ChildNode | null {\n if (!line) return null;\n const textNodeContainer = getTextNodeContainer(text, link, key, line);\n if (!textNodeContainer) return null;\n\n for (const node of Array.from(textNodeContainer.childNodes)) {\n if (isCorrectNode(text, link, node)) {\n return node;\n }\n }\n\n return null;\n}\n\nfunction getTextNodeContainer(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): HTMLElement | null {\n if (!line) return null;\n\n for (const node of Array.from(line.childNodes)) {\n if (node instanceof HTMLElement && node.getAttribute(\"data-id\") === key) {\n return node;\n }\n\n if (node.nodeType !== 3) {\n const inner = getTextNodeContainer(text, link, key, node);\n if (inner) return inner;\n }\n }\n\n return null;\n}\n\nfunction isCorrectNode(\n text: string,\n link: string,\n node: ChildNode | Node | null | undefined,\n): node is ChildNode | Node {\n if (!node) return false;\n\n const textContent = node?.textContent;\n\n return Boolean(\n node &&\n textContent &&\n node.nodeType === 3 &&\n textContent.includes(link) &&\n textContent.includes(text),\n );\n}\n\ntype SelectLinkOptions = {\n node: ChildNode | Node;\n selection: Selection;\n start?: number;\n link: string;\n};\nfunction selectLink({ link, node, selection, start }: SelectLinkOptions) {\n const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);\n const endPosition = startPosition + link.length;\n\n if (startPosition === 0 && endPosition === 0) {\n const content = node.textContent;\n if (!content) return;\n let startPosition = 0;\n let pos = 0;\n\n while (pos < content.length) {\n if (content.codePointAt(pos) !== CODE_OF_START_IMAGE_URL) {\n pos++;\n } else {\n startPosition = pos + 1;\n break;\n }\n }\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n\n return;\n }\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.setEnd(node, endPosition);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction handleClick(\n view: EditorView | undefined,\n text: string,\n link: string,\n key: string,\n event: MouseEvent,\n) {\n const selection = window.getSelection();\n\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const target = event.target as HTMLImageElement;\n const parent = target.parentNode;\n let line: HTMLElement | null = parent as HTMLElement | null;\n\n /** recursively find line that contains link */\n while (line && !line.classList.contains(\"cm-line\")) {\n line = line.parentNode as HTMLElement | null;\n }\n\n const editor = Array.from(document.querySelectorAll(\".cm-editor\")).find((element) =>\n element.contains(target),\n );\n\n if (!selection || !editor || !parent) return;\n\n const textNode = getTextNode(text, link, key, line);\n\n if (textNode) {\n return void selectLink({ selection, link, node: textNode });\n }\n\n saveDispatch(() => {\n if (!view) return;\n view.dispatch(view.state.update({ effects: openedImageEffect.of(key) }));\n\n const textNode = getTextNode(text, link, key, line);\n if (textNode) {\n selectLink({ selection, link, node: textNode });\n }\n\n requestAnimationFrame(() => {\n saveDispatch(() => {\n if (view) view.dispatch(view.state.update({ effects: openedImageEffect.of(undefined) }));\n });\n });\n });\n\n return false;\n}\n"],"names":[],"mappings":"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"}
|