@gravity-ui/markdown-editor 15.35.1 → 15.36.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/build/cjs/core/Editor.js +2 -0
- package/build/cjs/core/Editor.js.map +1 -1
- package/build/cjs/core/index.d.ts +1 -0
- package/build/cjs/core/index.js +3 -1
- package/build/cjs/core/index.js.map +1 -1
- package/build/cjs/core/markdown/MarkdownParser.d.ts +1 -0
- package/build/cjs/core/markdown/MarkdownParser.js +3 -0
- package/build/cjs/core/markdown/MarkdownParser.js.map +1 -1
- package/build/cjs/core/types/parser.d.ts +1 -0
- package/build/cjs/core/types/parser.js.map +1 -1
- package/build/cjs/core/utils/parser.d.ts +3 -0
- package/build/cjs/core/utils/parser.js +12 -0
- package/build/cjs/core/utils/parser.js.map +1 -0
- package/build/cjs/extensions/behavior/SelectionContext/tooltip.js +3 -0
- package/build/cjs/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
- package/build/cjs/extensions/markdown/Bold/index.js +1 -1
- package/build/cjs/extensions/markdown/Bold/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Code/index.js +1 -1
- package/build/cjs/extensions/markdown/Code/index.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +75 -66
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js +42 -22
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js +20 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js.map +1 -1
- package/build/cjs/extensions/markdown/Italic/index.js +1 -1
- package/build/cjs/extensions/markdown/Italic/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Mark/index.js +1 -1
- package/build/cjs/extensions/markdown/Mark/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Strike/index.js +1 -1
- package/build/cjs/extensions/markdown/Strike/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Underline/index.js +1 -1
- package/build/cjs/extensions/markdown/Underline/index.js.map +1 -1
- package/build/cjs/extensions/yfm/Monospace/index.js +1 -1
- package/build/cjs/extensions/yfm/Monospace/index.js.map +1 -1
- package/build/cjs/utils/actions.d.ts +6 -0
- package/build/cjs/utils/actions.js +24 -0
- package/build/cjs/utils/actions.js.map +1 -1
- package/build/cjs/utils/marks.d.ts +6 -0
- package/build/cjs/utils/marks.js +31 -0
- package/build/cjs/utils/marks.js.map +1 -1
- package/build/cjs/utils/transaction.d.ts +1 -0
- package/build/cjs/utils/transaction.js +40 -0
- package/build/cjs/utils/transaction.js.map +1 -0
- package/build/cjs/version.js +1 -1
- package/build/cjs/version.js.map +1 -1
- package/build/esm/core/Editor.js +2 -0
- package/build/esm/core/Editor.js.map +1 -1
- package/build/esm/core/index.d.ts +1 -0
- package/build/esm/core/index.js +1 -0
- package/build/esm/core/index.js.map +1 -1
- package/build/esm/core/markdown/MarkdownParser.d.ts +1 -0
- package/build/esm/core/markdown/MarkdownParser.js +3 -0
- package/build/esm/core/markdown/MarkdownParser.js.map +1 -1
- package/build/esm/core/types/parser.d.ts +1 -0
- package/build/esm/core/types/parser.js.map +1 -1
- package/build/esm/core/utils/parser.d.ts +3 -0
- package/build/esm/core/utils/parser.js +8 -0
- package/build/esm/core/utils/parser.js.map +1 -0
- package/build/esm/extensions/behavior/SelectionContext/tooltip.js +3 -0
- package/build/esm/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
- package/build/esm/extensions/markdown/Bold/index.js +2 -2
- package/build/esm/extensions/markdown/Bold/index.js.map +1 -1
- package/build/esm/extensions/markdown/Code/index.js +2 -2
- package/build/esm/extensions/markdown/Code/index.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +75 -66
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js +43 -23
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js +20 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js.map +1 -1
- package/build/esm/extensions/markdown/Italic/index.js +2 -2
- package/build/esm/extensions/markdown/Italic/index.js.map +1 -1
- package/build/esm/extensions/markdown/Mark/index.js +2 -2
- package/build/esm/extensions/markdown/Mark/index.js.map +1 -1
- package/build/esm/extensions/markdown/Strike/index.js +2 -2
- package/build/esm/extensions/markdown/Strike/index.js.map +1 -1
- package/build/esm/extensions/markdown/Underline/index.js +2 -2
- package/build/esm/extensions/markdown/Underline/index.js.map +1 -1
- package/build/esm/extensions/yfm/Monospace/index.js +2 -2
- package/build/esm/extensions/yfm/Monospace/index.js.map +1 -1
- package/build/esm/utils/actions.d.ts +6 -0
- package/build/esm/utils/actions.js +24 -1
- package/build/esm/utils/actions.js.map +1 -1
- package/build/esm/utils/marks.d.ts +6 -0
- package/build/esm/utils/marks.js +30 -0
- package/build/esm/utils/marks.js.map +1 -1
- package/build/esm/utils/transaction.d.ts +1 -0
- package/build/esm/utils/transaction.js +36 -0
- package/build/esm/utils/transaction.js.map +1 -0
- package/build/esm/version.js +1 -1
- package/build/esm/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,8 +10,9 @@ import { codeLangSelectTooltipViewCreator } from "./TooltipPlugin/index.js";
|
|
|
10
10
|
import { PlainTextLang } from "./const.js";
|
|
11
11
|
import { codeBlockLineNumbersPlugin } from "./plugins/codeBlockLineNumbersPlugin.js";
|
|
12
12
|
import { codeBlockLineWrappingPlugin } from "./plugins/codeBlockLineWrappingPlugin.js";
|
|
13
|
+
import { processChangedCodeBlocks } from "./utils.js";
|
|
13
14
|
import "./CodeBlockHighlight.css";
|
|
14
|
-
const
|
|
15
|
+
const pluginKey = new PluginKey('code_block_highlight');
|
|
15
16
|
export const CodeBlockHighlight = (builder, opts) => {
|
|
16
17
|
let langs;
|
|
17
18
|
let lowlight;
|
|
@@ -45,7 +46,7 @@ export const CodeBlockHighlight = (builder, opts) => {
|
|
|
45
46
|
// TODO: add TAB key handler
|
|
46
47
|
// TODO: Remove constant selection of block
|
|
47
48
|
return new Plugin({
|
|
48
|
-
key,
|
|
49
|
+
key: pluginKey,
|
|
49
50
|
state: {
|
|
50
51
|
init: (_, state) => {
|
|
51
52
|
loadModules().then((loaded) => {
|
|
@@ -65,47 +66,47 @@ export const CodeBlockHighlight = (builder, opts) => {
|
|
|
65
66
|
}
|
|
66
67
|
selectItems.sort(sortLangs);
|
|
67
68
|
if (view && !view.isDestroyed) {
|
|
68
|
-
view.dispatch(view.state.tr.setMeta(
|
|
69
|
+
view.dispatch(view.state.tr.setMeta(pluginKey, { modulesLoaded }));
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
});
|
|
72
|
-
|
|
73
|
+
const cache = new WeakMap();
|
|
74
|
+
return {
|
|
75
|
+
cache,
|
|
76
|
+
decoSet: modulesLoaded
|
|
77
|
+
? DecorationSet.empty
|
|
78
|
+
: getDecorations(state.doc, cache),
|
|
79
|
+
};
|
|
73
80
|
},
|
|
74
|
-
apply: (tr,
|
|
81
|
+
apply: (tr, { cache, decoSet }) => {
|
|
75
82
|
if (!modulesLoaded) {
|
|
76
|
-
return DecorationSet.empty;
|
|
83
|
+
return { cache, decoSet: DecorationSet.empty };
|
|
77
84
|
}
|
|
78
|
-
if (tr.getMeta(
|
|
79
|
-
return getDecorations(tr.doc);
|
|
85
|
+
if (tr.getMeta(pluginKey)?.modulesLoaded) {
|
|
86
|
+
return { cache, decoSet: getDecorations(tr.doc, cache) };
|
|
80
87
|
}
|
|
81
|
-
if (tr.docChanged)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
// selection includes codeblock node,
|
|
88
|
-
return getDecorations(tr.doc);
|
|
88
|
+
if (!tr.docChanged)
|
|
89
|
+
return { cache, decoSet };
|
|
90
|
+
decoSet = processChangedCodeBlocks(tr, decoSet, (node, pos, decoSet) => {
|
|
91
|
+
const lang = node.attrs[CodeBlockNodeAttr.Lang];
|
|
92
|
+
if (!lang || !lowlight.registered(lang)) {
|
|
93
|
+
return decoSet.remove(decoSet.find(pos, pos + node.nodeSize));
|
|
89
94
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
newNodes.length !== oldNodes.length ||
|
|
96
|
-
// OR transaction has changes that completely encapsulate a node
|
|
97
|
-
// (for example, a transaction that affects the entire document).
|
|
98
|
-
// Such transactions can happen during collab syncing via y-prosemirror, for example.
|
|
99
|
-
tr.steps.some((step) => {
|
|
100
|
-
return (stepHasFromTo(step) &&
|
|
101
|
-
oldNodes.some((node) => node.pos >= step.from &&
|
|
102
|
-
node.pos + node.node.nodeSize <= step.to));
|
|
103
|
-
})) {
|
|
104
|
-
return getDecorations(tr.doc);
|
|
95
|
+
const cached = cache.get(node);
|
|
96
|
+
if (cached) {
|
|
97
|
+
// node is in cache, but decorations may be missing (for example, after undo)
|
|
98
|
+
if (!decoSet.find(pos, pos + node.nodeSize).length) {
|
|
99
|
+
return decoSet.add(tr.doc, renderTree(cached, pos + 1));
|
|
105
100
|
}
|
|
101
|
+
return decoSet;
|
|
106
102
|
}
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
decoSet = decoSet.remove(decoSet.find(pos, pos + node.nodeSize));
|
|
104
|
+
const ast = lowlight.highlight(lang, node.textContent);
|
|
105
|
+
const parsed = parseNodes(ast.children);
|
|
106
|
+
cache.set(node, parsed);
|
|
107
|
+
return decoSet.add(tr.doc, renderTree(parsed, pos + 1));
|
|
108
|
+
});
|
|
109
|
+
return { cache, decoSet };
|
|
109
110
|
},
|
|
110
111
|
},
|
|
111
112
|
view: (v) => {
|
|
@@ -116,8 +117,8 @@ export const CodeBlockHighlight = (builder, opts) => {
|
|
|
116
117
|
});
|
|
117
118
|
},
|
|
118
119
|
props: {
|
|
119
|
-
decorations
|
|
120
|
-
return
|
|
120
|
+
decorations(state) {
|
|
121
|
+
return pluginKey.getState(state)?.decoSet;
|
|
121
122
|
},
|
|
122
123
|
nodeViews: {
|
|
123
124
|
[codeBlockNodeName]: CodeBlockNodeView.withOpts(opts),
|
|
@@ -125,52 +126,60 @@ export const CodeBlockHighlight = (builder, opts) => {
|
|
|
125
126
|
},
|
|
126
127
|
});
|
|
127
128
|
});
|
|
128
|
-
function getDecorations(doc) {
|
|
129
|
-
const decos = [];
|
|
129
|
+
function getDecorations(doc, cache) {
|
|
130
130
|
if (!lowlight) {
|
|
131
131
|
return DecorationSet.empty;
|
|
132
132
|
}
|
|
133
|
+
const decos = [];
|
|
133
134
|
for (const { node, pos } of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {
|
|
134
|
-
let from = pos + 1;
|
|
135
|
-
let nodes;
|
|
136
135
|
const lang = node.attrs[CodeBlockNodeAttr.Lang];
|
|
137
|
-
if (lang
|
|
138
|
-
nodes = lowlight.highlight(lang, node.textContent).children;
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
136
|
+
if (!lang || !lowlight.registered(lang)) {
|
|
141
137
|
continue;
|
|
142
138
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
from = to;
|
|
139
|
+
// Try to get parsed result from cache using node as key
|
|
140
|
+
let parsedNodes = cache.get(node);
|
|
141
|
+
if (!parsedNodes) {
|
|
142
|
+
// Compute, parse and cache using the node itself as key
|
|
143
|
+
const nodes = lowlight.highlight(lang, node.textContent).children;
|
|
144
|
+
parsedNodes = parseNodes(nodes);
|
|
145
|
+
cache.set(node, parsedNodes);
|
|
151
146
|
}
|
|
147
|
+
decos.push(...renderTree(parsedNodes, pos + 1));
|
|
152
148
|
}
|
|
153
149
|
return DecorationSet.create(doc, decos);
|
|
154
150
|
}
|
|
155
151
|
};
|
|
152
|
+
function renderTree(parsedNodes, from) {
|
|
153
|
+
const decos = [];
|
|
154
|
+
for (const { text, classes } of parsedNodes) {
|
|
155
|
+
const to = from + text.length;
|
|
156
|
+
if (classes.length) {
|
|
157
|
+
decos.push(Decoration.inline(from, to, {
|
|
158
|
+
class: classes.join(' '),
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
from = to;
|
|
162
|
+
}
|
|
163
|
+
return decos;
|
|
164
|
+
}
|
|
156
165
|
function parseNodes(nodes, className = []) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
166
|
+
const result = [];
|
|
167
|
+
collectNodes(nodes, className, result);
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
function collectNodes(nodes, className, result) {
|
|
171
|
+
for (const node of nodes) {
|
|
160
172
|
if (node.type === 'element') {
|
|
161
|
-
classes =
|
|
162
|
-
|
|
173
|
+
const classes = className.concat(node.properties.className ?? []);
|
|
174
|
+
collectNodes(node.children, classes, result);
|
|
163
175
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
function stepHasFromTo(step) {
|
|
172
|
-
// @ts-expect-error
|
|
173
|
-
return typeof step.from === 'number' && typeof step.to === 'number';
|
|
176
|
+
else {
|
|
177
|
+
result.push({
|
|
178
|
+
text: node.type === 'comment' || node.type === 'text' ? node.value : '',
|
|
179
|
+
classes: className,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
174
183
|
}
|
|
175
184
|
function sortLangs(a, b) {
|
|
176
185
|
// plaintext always goes first
|
package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockHighlight.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Options} from '@diplodoc/transform';\n// importing only type, because lowlight and highlight.js is optional deps\nimport type HLJS from 'highlight.js/lib/core';\nimport type {createLowlight} from 'lowlight' with {'resolution-mode': 'import'};\nimport type {Node} from 'prosemirror-model';\nimport {Plugin, PluginKey} from 'prosemirror-state';\nimport type {Step} from 'prosemirror-transform';\n// @ts-ignore // TODO: fix cjs build\nimport {findChildrenByType} from 'prosemirror-utils';\nimport {Decoration, DecorationSet, type EditorView} from 'prosemirror-view';\n\nimport type {ExtensionAuto} from '../../../../core';\nimport {capitalize} from '../../../../lodash';\nimport {globalLogger} from '../../../../logger';\nimport {\n CodeBlockNodeAttr,\n type LineNumbersOptions,\n codeBlockNodeName,\n codeBlockType,\n} from '../CodeBlockSpecs';\n\nimport {CodeBlockNodeView} from './CodeBlockNodeView';\nimport {codeLangSelectTooltipViewCreator} from './TooltipPlugin';\nimport {PlainTextLang} from './const';\nimport {codeBlockLineNumbersPlugin} from './plugins/codeBlockLineNumbersPlugin';\nimport {codeBlockLineWrappingPlugin} from './plugins/codeBlockLineWrappingPlugin';\n\nimport './CodeBlockHighlight.scss';\n\nexport type HighlightLangMap = Options['highlightLangs'];\n\ntype Lowlight = ReturnType<typeof createLowlight>;\ntype Root = ReturnType<Lowlight['highlight']>;\n\ntype LangSelectItem = {\n value: string;\n content: string;\n};\n\nconst key = new PluginKey<DecorationSet>('code_block_highlight');\n\nexport type CodeBlockHighlightOptions = {\n lineWrapping?: {\n enabled?: boolean;\n };\n lineNumbers?: LineNumbersOptions;\n langs?: HighlightLangMap;\n};\n\nexport const CodeBlockHighlight: ExtensionAuto<CodeBlockHighlightOptions> = (builder, opts) => {\n let langs: NonNullable<HighlightLangMap>;\n let lowlight: Lowlight;\n let hljs: typeof HLJS;\n\n const loadModules = async () => {\n try {\n hljs = (await import('highlight.js/lib/core')).default;\n const low = await import('lowlight');\n\n const all: HighlightLangMap = low.all;\n const create: typeof createLowlight = low.createLowlight;\n langs = {...all, ...opts.langs};\n lowlight = create(langs);\n return true;\n } catch (e) {\n globalLogger.info('Skip code_block highlighting');\n builder.logger.log('Skip code_block highlighting');\n return false;\n }\n };\n\n if (opts.lineWrapping?.enabled) builder.addPlugin(codeBlockLineWrappingPlugin);\n if (opts.lineNumbers?.enabled) builder.addPlugin(codeBlockLineNumbersPlugin);\n\n builder.addPlugin(() => {\n let modulesLoaded = false;\n let view: EditorView | null = null;\n\n // empty array by default, but is filled after loading modules\n const selectItems: LangSelectItem[] = [];\n const mapping: Record<string, string> = {};\n\n // TODO: add TAB key handler\n // TODO: Remove constant selection of block\n return new Plugin<DecorationSet>({\n key,\n state: {\n init: (_, state) => {\n loadModules().then((loaded) => {\n modulesLoaded = loaded;\n\n if (modulesLoaded) {\n for (const lang of Object.keys(langs)) {\n const defs = langs[lang](hljs);\n selectItems.push({\n value: lang,\n content: defs.name || capitalize(lang),\n });\n if (defs.aliases) {\n for (const alias of defs.aliases) {\n mapping[alias] = lang;\n }\n }\n }\n\n selectItems.sort(sortLangs);\n\n if (view && !view.isDestroyed) {\n view.dispatch(view.state.tr.setMeta(key, {modulesLoaded}));\n }\n }\n });\n return getDecorations(state.doc);\n },\n apply: (tr, decos, oldState, newState) => {\n if (!modulesLoaded) {\n return DecorationSet.empty;\n }\n\n if (tr.getMeta(key)?.modulesLoaded) {\n return getDecorations(tr.doc);\n }\n\n if (tr.docChanged) {\n const oldNodeName = oldState.selection.$head.parent.type.name;\n const newNodeName = newState.selection.$head.parent.type.name;\n\n // Apply decorations if:\n if (\n oldNodeName === codeBlockNodeName ||\n newNodeName === codeBlockNodeName\n ) {\n // selection includes codeblock node,\n return getDecorations(tr.doc);\n } else {\n const oldNodes = findChildrenByType(\n oldState.doc,\n codeBlockType(oldState.schema),\n );\n const newNodes = findChildrenByType(\n newState.doc,\n codeBlockType(newState.schema),\n );\n if (\n // OR transaction adds/removes codeblock nodes,\n newNodes.length !== oldNodes.length ||\n // OR transaction has changes that completely encapsulate a node\n // (for example, a transaction that affects the entire document).\n // Such transactions can happen during collab syncing via y-prosemirror, for example.\n tr.steps.some((step) => {\n return (\n stepHasFromTo(step) &&\n oldNodes.some(\n (node: {node: Node; pos: number}) =>\n node.pos >= step.from &&\n node.pos + node.node.nodeSize <= step.to,\n )\n );\n })\n ) {\n return getDecorations(tr.doc);\n }\n }\n }\n return decos.map(tr.mapping, tr.doc);\n },\n },\n view: (v) => {\n view = v;\n return codeLangSelectTooltipViewCreator(view, selectItems, mapping, {\n showCodeWrapping: Boolean(opts.lineWrapping?.enabled),\n showLineNumbers: Boolean(opts.lineNumbers?.enabled),\n });\n },\n props: {\n decorations: (state) => {\n return key.getState(state);\n },\n nodeViews: {\n [codeBlockNodeName]: CodeBlockNodeView.withOpts(opts),\n },\n },\n });\n });\n\n function getDecorations(doc: Node) {\n const decos: Decoration[] = [];\n\n if (!lowlight) {\n return DecorationSet.empty;\n }\n\n for (const {node, pos} of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {\n let from = pos + 1;\n let nodes: Root['children'];\n\n const lang: string | undefined = node.attrs[CodeBlockNodeAttr.Lang];\n if (lang && lowlight.registered(lang)) {\n nodes = lowlight.highlight(lang, node.textContent).children;\n } else {\n continue;\n }\n\n for (const {text, classes} of parseNodes(nodes)) {\n const to = from + text.length;\n if (classes.length) {\n decos.push(\n Decoration.inline(from, to, {\n class: classes.join(' '),\n }),\n );\n }\n from = to;\n }\n }\n\n return DecorationSet.create(doc, decos);\n }\n};\n\nfunction parseNodes(\n nodes: Root['children'],\n className: readonly string[] = [],\n): {text: string; classes: readonly string[]}[] {\n return nodes\n .map((node) => {\n let classes = className;\n if (node.type === 'element') {\n classes = classes.concat((node.properties.className as string[]) ?? []);\n return parseNodes(node.children, classes);\n }\n\n return {\n text: node.type === 'comment' || node.type === 'text' ? node.value : '',\n classes,\n };\n })\n .flat();\n}\n\nfunction stepHasFromTo(step: Step): step is Step & {from: number; to: number} {\n // @ts-expect-error\n return typeof step.from === 'number' && typeof step.to === 'number';\n}\n\nfunction sortLangs(a: LangSelectItem, b: LangSelectItem): number {\n // plaintext always goes first\n if (a.value === PlainTextLang) return -1;\n if (b.value === PlainTextLang) return 1;\n return 0;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"CodeBlockHighlight.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Options} from '@diplodoc/transform';\n// importing only type, because lowlight and highlight.js is optional deps\nimport type HLJS from 'highlight.js/lib/core';\nimport type {createLowlight} from 'lowlight' with {'resolution-mode': 'import'};\nimport type {Node} from 'prosemirror-model';\nimport {Plugin, PluginKey} from 'prosemirror-state';\n// @ts-ignore // TODO: fix cjs build\nimport {findChildrenByType} from 'prosemirror-utils';\nimport {Decoration, DecorationSet, type EditorView} from 'prosemirror-view';\n\nimport type {ExtensionAuto} from '../../../../core';\nimport {capitalize} from '../../../../lodash';\nimport {globalLogger} from '../../../../logger';\nimport {\n CodeBlockNodeAttr,\n type LineNumbersOptions,\n codeBlockNodeName,\n codeBlockType,\n} from '../CodeBlockSpecs';\n\nimport {CodeBlockNodeView} from './CodeBlockNodeView';\nimport {codeLangSelectTooltipViewCreator} from './TooltipPlugin';\nimport {PlainTextLang} from './const';\nimport {codeBlockLineNumbersPlugin} from './plugins/codeBlockLineNumbersPlugin';\nimport {codeBlockLineWrappingPlugin} from './plugins/codeBlockLineWrappingPlugin';\nimport {processChangedCodeBlocks} from './utils';\n\nimport './CodeBlockHighlight.scss';\n\nexport type HighlightLangMap = Options['highlightLangs'];\n\ntype Lowlight = ReturnType<typeof createLowlight>;\ntype Root = ReturnType<Lowlight['highlight']>;\n\ntype LangSelectItem = {\n value: string;\n content: string;\n};\n\nconst pluginKey = new PluginKey<PluginState>('code_block_highlight');\n\n// Cache for parsed highlight results, using ProseMirror nodes as keys\ntype HighlightCache = WeakMap<Node, HighlightParsedTree>;\n\ntype HighlightParsedTree = {text: string; classes: readonly string[]}[];\n\ntype PluginState = {\n cache: HighlightCache;\n decoSet: DecorationSet;\n};\n\nexport type CodeBlockHighlightOptions = {\n lineWrapping?: {\n enabled?: boolean;\n };\n lineNumbers?: LineNumbersOptions;\n langs?: HighlightLangMap;\n};\n\nexport const CodeBlockHighlight: ExtensionAuto<CodeBlockHighlightOptions> = (builder, opts) => {\n let langs: NonNullable<HighlightLangMap>;\n let lowlight: Lowlight;\n let hljs: typeof HLJS;\n\n const loadModules = async () => {\n try {\n hljs = (await import('highlight.js/lib/core')).default;\n const low = await import('lowlight');\n\n const all: HighlightLangMap = low.all;\n const create: typeof createLowlight = low.createLowlight;\n langs = {...all, ...opts.langs};\n lowlight = create(langs);\n return true;\n } catch (e) {\n globalLogger.info('Skip code_block highlighting');\n builder.logger.log('Skip code_block highlighting');\n return false;\n }\n };\n\n if (opts.lineWrapping?.enabled) builder.addPlugin(codeBlockLineWrappingPlugin);\n if (opts.lineNumbers?.enabled) builder.addPlugin(codeBlockLineNumbersPlugin);\n\n builder.addPlugin(() => {\n let modulesLoaded = false;\n let view: EditorView | null = null;\n\n // empty array by default, but is filled after loading modules\n const selectItems: LangSelectItem[] = [];\n const mapping: Record<string, string> = {};\n\n // TODO: add TAB key handler\n // TODO: Remove constant selection of block\n return new Plugin<PluginState>({\n key: pluginKey,\n state: {\n init: (_, state) => {\n loadModules().then((loaded) => {\n modulesLoaded = loaded;\n\n if (modulesLoaded) {\n for (const lang of Object.keys(langs)) {\n const defs = langs[lang](hljs);\n selectItems.push({\n value: lang,\n content: defs.name || capitalize(lang),\n });\n if (defs.aliases) {\n for (const alias of defs.aliases) {\n mapping[alias] = lang;\n }\n }\n }\n\n selectItems.sort(sortLangs);\n\n if (view && !view.isDestroyed) {\n view.dispatch(view.state.tr.setMeta(pluginKey, {modulesLoaded}));\n }\n }\n });\n\n const cache: HighlightCache = new WeakMap();\n\n return {\n cache,\n decoSet: modulesLoaded\n ? DecorationSet.empty\n : getDecorations(state.doc, cache),\n };\n },\n apply: (tr, {cache, decoSet}) => {\n if (!modulesLoaded) {\n return {cache, decoSet: DecorationSet.empty};\n }\n\n if (tr.getMeta(pluginKey)?.modulesLoaded) {\n return {cache, decoSet: getDecorations(tr.doc, cache)};\n }\n\n if (!tr.docChanged) return {cache, decoSet};\n\n decoSet = processChangedCodeBlocks(tr, decoSet, (node, pos, decoSet) => {\n const lang: string | undefined = node.attrs[CodeBlockNodeAttr.Lang];\n\n if (!lang || !lowlight.registered(lang)) {\n return decoSet.remove(decoSet.find(pos, pos + node.nodeSize));\n }\n\n const cached = cache.get(node);\n if (cached) {\n // node is in cache, but decorations may be missing (for example, after undo)\n if (!decoSet.find(pos, pos + node.nodeSize).length) {\n return decoSet.add(tr.doc, renderTree(cached, pos + 1));\n }\n return decoSet;\n }\n\n decoSet = decoSet.remove(decoSet.find(pos, pos + node.nodeSize));\n const ast = lowlight.highlight(lang, node.textContent);\n const parsed = parseNodes(ast.children);\n cache.set(node, parsed);\n return decoSet.add(tr.doc, renderTree(parsed, pos + 1));\n });\n\n return {cache, decoSet};\n },\n },\n view: (v) => {\n view = v;\n return codeLangSelectTooltipViewCreator(view, selectItems, mapping, {\n showCodeWrapping: Boolean(opts.lineWrapping?.enabled),\n showLineNumbers: Boolean(opts.lineNumbers?.enabled),\n });\n },\n props: {\n decorations(state) {\n return pluginKey.getState(state)?.decoSet;\n },\n nodeViews: {\n [codeBlockNodeName]: CodeBlockNodeView.withOpts(opts),\n },\n },\n });\n });\n\n function getDecorations(doc: Node, cache: HighlightCache) {\n if (!lowlight) {\n return DecorationSet.empty;\n }\n\n const decos: Decoration[] = [];\n\n for (const {node, pos} of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {\n const lang: string | undefined = node.attrs[CodeBlockNodeAttr.Lang];\n if (!lang || !lowlight.registered(lang)) {\n continue;\n }\n\n // Try to get parsed result from cache using node as key\n let parsedNodes = cache.get(node);\n if (!parsedNodes) {\n // Compute, parse and cache using the node itself as key\n const nodes = lowlight.highlight(lang, node.textContent).children;\n parsedNodes = parseNodes(nodes);\n cache.set(node, parsedNodes);\n }\n\n decos.push(...renderTree(parsedNodes, pos + 1));\n }\n\n return DecorationSet.create(doc, decos);\n }\n};\n\nfunction renderTree(parsedNodes: HighlightParsedTree, from: number): Decoration[] {\n const decos: Decoration[] = [];\n\n for (const {text, classes} of parsedNodes) {\n const to = from + text.length;\n if (classes.length) {\n decos.push(\n Decoration.inline(from, to, {\n class: classes.join(' '),\n }),\n );\n }\n from = to;\n }\n\n return decos;\n}\n\nfunction parseNodes(\n nodes: Root['children'],\n className: readonly string[] = [],\n): HighlightParsedTree {\n const result: HighlightParsedTree = [];\n collectNodes(nodes, className, result);\n return result;\n}\n\nfunction collectNodes(\n nodes: Root['children'],\n className: readonly string[],\n result: HighlightParsedTree,\n): void {\n for (const node of nodes) {\n if (node.type === 'element') {\n const classes = className.concat((node.properties.className as string[]) ?? []);\n collectNodes(node.children, classes, result);\n } else {\n result.push({\n text: node.type === 'comment' || node.type === 'text' ? node.value : '',\n classes: className,\n });\n }\n }\n}\n\nfunction sortLangs(a: LangSelectItem, b: LangSelectItem): number {\n // plaintext always goes first\n if (a.value === PlainTextLang) return -1;\n if (b.value === PlainTextLang) return 1;\n return 0;\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { Plugin, PluginKey } from "../../../../../pm/state.js";
|
|
|
2
2
|
import { findChildrenByType } from "../../../../../pm/utils.js";
|
|
3
3
|
import { Decoration, DecorationSet } from "../../../../../pm/view.js";
|
|
4
4
|
import { codeBlockType } from "../../CodeBlockSpecs/index.js";
|
|
5
|
-
import { isLineNumbersVisible } from "../utils.js";
|
|
5
|
+
import { isLineNumbersVisible, processChangedCodeBlocks } from "../utils.js";
|
|
6
6
|
const pluginKey = new PluginKey('code_block_line_numbers_decorations');
|
|
7
7
|
/** @internal */
|
|
8
8
|
export const codeBlockLineNumbersPlugin = () => {
|
|
@@ -10,42 +10,62 @@ export const codeBlockLineNumbersPlugin = () => {
|
|
|
10
10
|
key: pluginKey,
|
|
11
11
|
state: {
|
|
12
12
|
init(_config, state) {
|
|
13
|
-
|
|
13
|
+
const cache = new WeakSet();
|
|
14
|
+
return { cache, decoSet: buildAllDecorations(state.doc, cache) };
|
|
14
15
|
},
|
|
15
|
-
apply(tr,
|
|
16
|
-
if (tr.docChanged)
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
apply(tr, { cache, decoSet }) {
|
|
17
|
+
if (!tr.docChanged)
|
|
18
|
+
return { cache, decoSet };
|
|
19
|
+
decoSet = processChangedCodeBlocks(tr, decoSet, (node, pos, decoSet) => {
|
|
20
|
+
if (!isLineNumbersVisible(node)) {
|
|
21
|
+
return decoSet.remove(decoSet.find(pos, pos + node.nodeSize));
|
|
22
|
+
}
|
|
23
|
+
if (cache.has(node)) {
|
|
24
|
+
// node has not changed, but decorations may be missing (after undo/redo)
|
|
25
|
+
if (!decoSet.find(pos, pos + node.nodeSize).length) {
|
|
26
|
+
return decoSet.add(tr.doc, buildNodeDecorations(node, pos));
|
|
27
|
+
}
|
|
28
|
+
return decoSet;
|
|
29
|
+
}
|
|
30
|
+
decoSet = decoSet.remove(decoSet.find(pos, pos + node.nodeSize));
|
|
31
|
+
cache.add(node);
|
|
32
|
+
return decoSet.add(tr.doc, buildNodeDecorations(node, pos));
|
|
33
|
+
});
|
|
34
|
+
return { cache, decoSet };
|
|
20
35
|
},
|
|
21
36
|
},
|
|
22
37
|
props: {
|
|
23
38
|
decorations(state) {
|
|
24
|
-
return pluginKey.getState(state);
|
|
39
|
+
return pluginKey.getState(state)?.decoSet;
|
|
25
40
|
},
|
|
26
41
|
},
|
|
27
42
|
});
|
|
28
43
|
};
|
|
29
|
-
function
|
|
44
|
+
function buildAllDecorations(doc, cache) {
|
|
30
45
|
const decos = [];
|
|
31
46
|
for (const { node, pos } of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {
|
|
32
47
|
if (!isLineNumbersVisible(node))
|
|
33
48
|
continue;
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let shift = 0;
|
|
38
|
-
for (let i = 0; i < contentByLines.length; i++) {
|
|
39
|
-
const line = contentByLines[i];
|
|
40
|
-
{
|
|
41
|
-
const elem = document.createElement('span');
|
|
42
|
-
elem.classList.add('yfm-line-number');
|
|
43
|
-
elem.textContent = String(i + 1).padStart(maxDigits, ' ');
|
|
44
|
-
decos.push(Decoration.widget(pos + shift + 1, elem, { side: 1, ignoreSelection: true }));
|
|
45
|
-
}
|
|
46
|
-
shift += line.length + 1;
|
|
47
|
-
}
|
|
49
|
+
const nodeDecos = buildNodeDecorations(node, pos);
|
|
50
|
+
cache.add(node);
|
|
51
|
+
decos.push(...nodeDecos);
|
|
48
52
|
}
|
|
49
53
|
return DecorationSet.create(doc, decos);
|
|
50
54
|
}
|
|
55
|
+
function buildNodeDecorations(node, pos) {
|
|
56
|
+
const decos = [];
|
|
57
|
+
const codeContent = node.textContent;
|
|
58
|
+
const contentByLines = codeContent.split('\n');
|
|
59
|
+
const maxDigits = String(contentByLines.length).length;
|
|
60
|
+
let shift = 0;
|
|
61
|
+
for (let i = 0; i < contentByLines.length; i++) {
|
|
62
|
+
const line = contentByLines[i];
|
|
63
|
+
const elem = document.createElement('span');
|
|
64
|
+
elem.classList.add('yfm-line-number');
|
|
65
|
+
elem.textContent = String(i + 1).padStart(maxDigits, ' ');
|
|
66
|
+
decos.push(Decoration.widget(pos + shift + 1, elem, { side: 1, ignoreSelection: true }));
|
|
67
|
+
shift += line.length + 1;
|
|
68
|
+
}
|
|
69
|
+
return decos;
|
|
70
|
+
}
|
|
51
71
|
//# sourceMappingURL=codeBlockLineNumbersPlugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeBlockLineNumbersPlugin.js","sourceRoot":"../../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAE,SAAS,EAAC,mCAAkB;AAC5C,OAAO,EAAC,kBAAkB,EAAC,mCAAkB;AAC7C,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,kCAAiB;AAEnD,OAAO,EAAC,aAAa,EAAC,sCAA6B;AACnD,OAAO,EAAC,oBAAoB,EAAC,oBAAiB;
|
|
1
|
+
{"version":3,"file":"codeBlockLineNumbersPlugin.js","sourceRoot":"../../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Node} from '#pm/model';\nimport {Plugin, PluginKey} from '#pm/state';\nimport {findChildrenByType} from '#pm/utils';\nimport {Decoration, DecorationSet} from '#pm/view';\n\nimport {codeBlockType} from '../../CodeBlockSpecs';\nimport {isLineNumbersVisible, processChangedCodeBlocks} from '../utils';\n\ntype LineNumberCache = WeakSet<Node>;\n\ntype PluginState = {\n cache: LineNumberCache;\n decoSet: DecorationSet;\n};\n\nconst pluginKey = new PluginKey<PluginState>('code_block_line_numbers_decorations');\n\n/** @internal */\nexport const codeBlockLineNumbersPlugin = () => {\n return new Plugin<PluginState>({\n key: pluginKey,\n state: {\n init(_config, state) {\n const cache: LineNumberCache = new WeakSet();\n return {cache, decoSet: buildAllDecorations(state.doc, cache)};\n },\n apply(tr, {cache, decoSet}) {\n if (!tr.docChanged) return {cache, decoSet};\n\n decoSet = processChangedCodeBlocks(tr, decoSet, (node, pos, decoSet) => {\n if (!isLineNumbersVisible(node)) {\n return decoSet.remove(decoSet.find(pos, pos + node.nodeSize));\n }\n\n if (cache.has(node)) {\n // node has not changed, but decorations may be missing (after undo/redo)\n if (!decoSet.find(pos, pos + node.nodeSize).length) {\n return decoSet.add(tr.doc, buildNodeDecorations(node, pos));\n }\n return decoSet;\n }\n\n decoSet = decoSet.remove(decoSet.find(pos, pos + node.nodeSize));\n cache.add(node);\n return decoSet.add(tr.doc, buildNodeDecorations(node, pos));\n });\n\n return {cache, decoSet};\n },\n },\n props: {\n decorations(state) {\n return pluginKey.getState(state)?.decoSet;\n },\n },\n });\n};\n\nfunction buildAllDecorations(doc: Node, cache: LineNumberCache) {\n const decos: Decoration[] = [];\n\n for (const {node, pos} of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {\n if (!isLineNumbersVisible(node)) continue;\n\n const nodeDecos = buildNodeDecorations(node, pos);\n cache.add(node);\n decos.push(...nodeDecos);\n }\n\n return DecorationSet.create(doc, decos);\n}\n\nfunction buildNodeDecorations(node: Node, pos: number): Decoration[] {\n const decos: Decoration[] = [];\n const codeContent = node.textContent;\n const contentByLines = codeContent.split('\\n');\n const maxDigits = String(contentByLines.length).length;\n\n let shift = 0;\n for (let i = 0; i < contentByLines.length; i++) {\n const line = contentByLines[i];\n\n const elem = document.createElement('span');\n elem.classList.add('yfm-line-number');\n elem.textContent = String(i + 1).padStart(maxDigits, ' ');\n\n decos.push(Decoration.widget(pos + shift + 1, elem, {side: 1, ignoreSelection: true}));\n\n shift += line.length + 1;\n }\n\n return decos;\n}\n"]}
|
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { forEachChangedNode } from "../../../../utils/transaction.js";
|
|
2
|
+
import { CodeBlockNodeAttr, codeBlockNodeName } from "../CodeBlockSpecs/index.js";
|
|
2
3
|
/** @internal */
|
|
3
4
|
export function isLineNumbersVisible(node) {
|
|
4
5
|
return node.attrs[CodeBlockNodeAttr.ShowLineNumbers] === 'true';
|
|
5
6
|
}
|
|
7
|
+
/** @internal */
|
|
8
|
+
export function processChangedCodeBlocks(tr, decoSet, onCodeBlock) {
|
|
9
|
+
decoSet = decoSet.map(tr.mapping, tr.doc);
|
|
10
|
+
forEachChangedNode(tr, (node, pos) => {
|
|
11
|
+
if (node.type.name !== codeBlockNodeName) {
|
|
12
|
+
if (node.isTextblock) {
|
|
13
|
+
// Remove stale decorations from non-code_block textblocks
|
|
14
|
+
// (e.g. when a code_block is converted to a paragraph)
|
|
15
|
+
decoSet = decoSet.remove(decoSet.find(pos, pos + node.nodeSize));
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
decoSet = onCodeBlock(node, pos, decoSet);
|
|
21
|
+
return false;
|
|
22
|
+
});
|
|
23
|
+
return decoSet;
|
|
24
|
+
}
|
|
6
25
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,kBAAkB,EAAC,yCAA8B;AAEzD,OAAO,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,mCAA0B;AAEvE,gBAAgB;AAChB,MAAM,UAAU,oBAAoB,CAAC,IAAU;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC;AACpE,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,wBAAwB,CACpC,EAAe,EACf,OAAsB,EACtB,WAA+E;IAE/E,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAE1C,kBAAkB,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACjC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,0DAA0D;gBAC1D,uDAAuD;gBACvD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACjE,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import type {Node} from '#pm/model';\nimport type {Transaction} from '#pm/state';\nimport type {DecorationSet} from '#pm/view';\nimport {forEachChangedNode} from 'src/utils/transaction';\n\nimport {CodeBlockNodeAttr, codeBlockNodeName} from '../CodeBlockSpecs';\n\n/** @internal */\nexport function isLineNumbersVisible(node: Node): boolean {\n return node.attrs[CodeBlockNodeAttr.ShowLineNumbers] === 'true';\n}\n\n/** @internal */\nexport function processChangedCodeBlocks(\n tr: Transaction,\n decoSet: DecorationSet,\n onCodeBlock: (node: Node, pos: number, decoSet: DecorationSet) => DecorationSet,\n): DecorationSet {\n decoSet = decoSet.map(tr.mapping, tr.doc);\n\n forEachChangedNode(tr, (node, pos) => {\n if (node.type.name !== codeBlockNodeName) {\n if (node.isTextblock) {\n // Remove stale decorations from non-code_block textblocks\n // (e.g. when a code_block is converted to a paragraph)\n decoSet = decoSet.remove(decoSet.find(pos, pos + node.nodeSize));\n return false;\n }\n return true;\n }\n decoSet = onCodeBlock(node, pos, decoSet);\n return false;\n });\n\n return decoSet;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toggleMark } from 'prosemirror-commands';
|
|
2
|
-
import {
|
|
2
|
+
import { createMarkdownInlineMarkAction } from "../../../utils/actions.js";
|
|
3
3
|
import { markInputRule } from "../../../utils/inputrules.js";
|
|
4
4
|
import { withLogAction } from "../../../utils/keymap.js";
|
|
5
5
|
import { ItalicSpecs, italicType } from "./ItalicSpecs/index.js";
|
|
@@ -7,7 +7,7 @@ export { italicMarkName, italicType } from "./ItalicSpecs/index.js";
|
|
|
7
7
|
const iAction = 'italic';
|
|
8
8
|
export const Italic = (builder, opts) => {
|
|
9
9
|
builder.use(ItalicSpecs);
|
|
10
|
-
builder.addAction(iAction, ({ schema }) =>
|
|
10
|
+
builder.addAction(iAction, ({ schema }) => createMarkdownInlineMarkAction(italicType(schema)));
|
|
11
11
|
builder.addInputRules(({ schema }) => ({
|
|
12
12
|
rules: [
|
|
13
13
|
markInputRule({ open: '*', close: '*', ignoreBetween: '*' }, italicType(schema)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Italic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Italic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAC,8BAA8B,EAAC,kCAA+B;AACtE,OAAO,EAAC,aAAa,EAAC,qCAAkC;AACxD,OAAO,EAAC,aAAa,EAAC,iCAA8B;AAEpD,OAAO,EAAC,WAAW,EAAE,UAAU,EAAC,+BAAsB;AAEtD,OAAO,EAAC,cAAc,EAAE,UAAU,EAAC,+BAAsB;AACzD,MAAM,OAAO,GAAG,QAAQ,CAAC;AAMzB,MAAM,CAAC,MAAM,MAAM,GAAiC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAClE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEzB,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,8BAA8B,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAE7F,OAAO,CAAC,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QACjC,KAAK,EAAE;YACH,aAAa,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC9E,aAAa,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;SACjF;KACJ,CAAC,CAAC,CAAC;IAEJ,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;QAClB,MAAM,EAAC,SAAS,EAAC,GAAG,IAAI,CAAC;QACzB,OAAO,CAAC,SAAS,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;SACvE,CAAC,CAAC,CAAC;IACR,CAAC;AACL,CAAC,CAAC","sourcesContent":["import {toggleMark} from 'prosemirror-commands';\n\nimport type {Action, ExtensionAuto} from '../../../core';\nimport {createMarkdownInlineMarkAction} from '../../../utils/actions';\nimport {markInputRule} from '../../../utils/inputrules';\nimport {withLogAction} from '../../../utils/keymap';\n\nimport {ItalicSpecs, italicType} from './ItalicSpecs';\n\nexport {italicMarkName, italicType} from './ItalicSpecs';\nconst iAction = 'italic';\n\nexport type ItalicOptions = {\n italicKey?: string | null;\n};\n\nexport const Italic: ExtensionAuto<ItalicOptions> = (builder, opts) => {\n builder.use(ItalicSpecs);\n\n builder.addAction(iAction, ({schema}) => createMarkdownInlineMarkAction(italicType(schema)));\n\n builder.addInputRules(({schema}) => ({\n rules: [\n markInputRule({open: '*', close: '*', ignoreBetween: '*'}, italicType(schema)),\n markInputRule({open: '_', close: '_', ignoreBetween: '_'}, italicType(schema)),\n ],\n }));\n\n if (opts?.italicKey) {\n const {italicKey} = opts;\n builder.addKeymap(({schema}) => ({\n [italicKey]: withLogAction('italic', toggleMark(italicType(schema))),\n }));\n }\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [iAction]: Action;\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createMarkdownInlineMarkAction } from "../../../utils/actions.js";
|
|
2
2
|
import { markInputRule } from "../../../utils/inputrules.js";
|
|
3
3
|
import { MarkSpecs, markMarkType } from "./MarkSpecs/index.js";
|
|
4
4
|
export { markMarkName, markMarkType } from "./MarkSpecs/index.js";
|
|
@@ -6,7 +6,7 @@ const mAction = 'mark';
|
|
|
6
6
|
export const Mark = (builder) => {
|
|
7
7
|
builder.use(MarkSpecs);
|
|
8
8
|
builder
|
|
9
|
-
.addAction(mAction, ({ schema }) =>
|
|
9
|
+
.addAction(mAction, ({ schema }) => createMarkdownInlineMarkAction(markMarkType(schema)))
|
|
10
10
|
.addInputRules(({ schema }) => ({
|
|
11
11
|
rules: [
|
|
12
12
|
markInputRule({ open: '==', close: '==', ignoreBetween: '=' }, markMarkType(schema)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Mark/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Mark/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,8BAA8B,EAAC,kCAA+B;AACtE,OAAO,EAAC,aAAa,EAAC,qCAAkC;AAExD,OAAO,EAAC,SAAS,EAAE,YAAY,EAAC,6BAAoB;AAEpD,OAAO,EAAC,YAAY,EAAE,YAAY,EAAC,6BAAoB;AACvD,MAAM,OAAO,GAAG,MAAM,CAAC;AAEvB,MAAM,CAAC,MAAM,IAAI,GAAkB,CAAC,OAAO,EAAE,EAAE;IAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEvB,OAAO;SACF,SAAS,CAAC,OAAO,EAAE,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,8BAA8B,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;SACtF,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,aAAa,CAAC,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;SACrF;KACJ,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC","sourcesContent":["import type {Action, ExtensionAuto} from '../../../core';\nimport {createMarkdownInlineMarkAction} from '../../../utils/actions';\nimport {markInputRule} from '../../../utils/inputrules';\n\nimport {MarkSpecs, markMarkType} from './MarkSpecs';\n\nexport {markMarkName, markMarkType} from './MarkSpecs';\nconst mAction = 'mark';\n\nexport const Mark: ExtensionAuto = (builder) => {\n builder.use(MarkSpecs);\n\n builder\n .addAction(mAction, ({schema}) => createMarkdownInlineMarkAction(markMarkType(schema)))\n .addInputRules(({schema}) => ({\n rules: [\n markInputRule({open: '==', close: '==', ignoreBetween: '='}, markMarkType(schema)),\n ],\n }));\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [mAction]: Action;\n }\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toggleMark } from 'prosemirror-commands';
|
|
2
|
-
import {
|
|
2
|
+
import { createMarkdownInlineMarkAction } from "../../../utils/actions.js";
|
|
3
3
|
import { markInputRule } from "../../../utils/inputrules.js";
|
|
4
4
|
import { withLogAction } from "../../../utils/keymap.js";
|
|
5
5
|
import { StrikeSpecs, strikeType } from "./StrikeSpecs/index.js";
|
|
@@ -8,7 +8,7 @@ const sAction = 'strike';
|
|
|
8
8
|
export const Strike = (builder, opts) => {
|
|
9
9
|
builder.use(StrikeSpecs);
|
|
10
10
|
builder
|
|
11
|
-
.addAction(sAction, ({ schema }) =>
|
|
11
|
+
.addAction(sAction, ({ schema }) => createMarkdownInlineMarkAction(strikeType(schema)))
|
|
12
12
|
.addInputRules(({ schema }) => ({
|
|
13
13
|
rules: [
|
|
14
14
|
markInputRule({ open: '~~', close: '~~', ignoreBetween: '~' }, strikeType(schema)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Strike/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Strike/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAC,8BAA8B,EAAC,kCAA+B;AACtE,OAAO,EAAC,aAAa,EAAC,qCAAkC;AACxD,OAAO,EAAC,aAAa,EAAC,iCAA8B;AAEpD,OAAO,EAAC,WAAW,EAAE,UAAU,EAAC,+BAAsB;AAEtD,OAAO,EAAC,cAAc,EAAE,UAAU,EAAC,+BAAsB;AACzD,MAAM,OAAO,GAAG,QAAQ,CAAC;AAMzB,MAAM,CAAC,MAAM,MAAM,GAAiC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAClE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEzB,OAAO;SACF,SAAS,CAAC,OAAO,EAAE,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,8BAA8B,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;SACpF,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,aAAa,CAAC,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;SACnF;KACJ,CAAC,CAAC,CAAC;IAER,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;QAClB,MAAM,EAAC,SAAS,EAAC,GAAG,IAAI,CAAC;QACzB,OAAO,CAAC,SAAS,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;SACvE,CAAC,CAAC,CAAC;IACR,CAAC;AACL,CAAC,CAAC","sourcesContent":["import {toggleMark} from 'prosemirror-commands';\n\nimport type {Action, ExtensionAuto} from '../../../core';\nimport {createMarkdownInlineMarkAction} from '../../../utils/actions';\nimport {markInputRule} from '../../../utils/inputrules';\nimport {withLogAction} from '../../../utils/keymap';\n\nimport {StrikeSpecs, strikeType} from './StrikeSpecs';\n\nexport {strikeMarkName, strikeType} from './StrikeSpecs';\nconst sAction = 'strike';\n\nexport type StrikeOptions = {\n strikeKey?: string | null;\n};\n\nexport const Strike: ExtensionAuto<StrikeOptions> = (builder, opts) => {\n builder.use(StrikeSpecs);\n\n builder\n .addAction(sAction, ({schema}) => createMarkdownInlineMarkAction(strikeType(schema)))\n .addInputRules(({schema}) => ({\n rules: [\n markInputRule({open: '~~', close: '~~', ignoreBetween: '~'}, strikeType(schema)),\n ],\n }));\n\n if (opts?.strikeKey) {\n const {strikeKey} = opts;\n builder.addKeymap(({schema}) => ({\n [strikeKey]: withLogAction('strike', toggleMark(strikeType(schema))),\n }));\n }\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [sAction]: Action;\n }\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toggleMark } from 'prosemirror-commands';
|
|
2
|
-
import {
|
|
2
|
+
import { createMarkdownInlineMarkAction } from "../../../utils/actions.js";
|
|
3
3
|
import { markInputRule } from "../../../utils/inputrules.js";
|
|
4
4
|
import { withLogAction } from "../../../utils/keymap.js";
|
|
5
5
|
import { UnderlineSpecs, underlineType } from "./UnderlineSpecs/index.js";
|
|
@@ -8,7 +8,7 @@ const undAction = 'underline';
|
|
|
8
8
|
export const Underline = (builder, opts) => {
|
|
9
9
|
builder.use(UnderlineSpecs);
|
|
10
10
|
builder
|
|
11
|
-
.addAction(undAction, ({ schema }) =>
|
|
11
|
+
.addAction(undAction, ({ schema }) => createMarkdownInlineMarkAction(underlineType(schema)))
|
|
12
12
|
.addInputRules(({ schema }) => ({
|
|
13
13
|
rules: [
|
|
14
14
|
markInputRule({ open: '++', close: '++', ignoreBetween: '+' }, underlineType(schema)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Underline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Underline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAC,8BAA8B,EAAC,kCAA+B;AACtE,OAAO,EAAC,aAAa,EAAC,qCAAkC;AACxD,OAAO,EAAC,aAAa,EAAC,iCAA8B;AAEpD,OAAO,EAAC,cAAc,EAAE,aAAa,EAAC,kCAAyB;AAE/D,OAAO,EAAC,iBAAiB,EAAE,aAAa,EAAC,kCAAyB;AAClE,MAAM,SAAS,GAAG,WAAW,CAAC;AAM9B,MAAM,CAAC,MAAM,SAAS,GAAoC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACxE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5B,OAAO;SACF,SAAS,CAAC,SAAS,EAAE,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,8BAA8B,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;SACzF,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,aAAa,CAAC,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;SACtF;KACJ,CAAC,CAAC,CAAC;IAER,IAAI,IAAI,EAAE,YAAY,EAAE,CAAC;QACrB,MAAM,EAAC,YAAY,EAAC,GAAG,IAAI,CAAC;QAC5B,OAAO,CAAC,SAAS,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;SAChF,CAAC,CAAC,CAAC;IACR,CAAC;AACL,CAAC,CAAC","sourcesContent":["import {toggleMark} from 'prosemirror-commands';\n\nimport type {Action, ExtensionAuto} from '../../../core';\nimport {createMarkdownInlineMarkAction} from '../../../utils/actions';\nimport {markInputRule} from '../../../utils/inputrules';\nimport {withLogAction} from '../../../utils/keymap';\n\nimport {UnderlineSpecs, underlineType} from './UnderlineSpecs';\n\nexport {underlineMarkName, underlineType} from './UnderlineSpecs';\nconst undAction = 'underline';\n\nexport type UnderlineOptions = {\n underlineKey?: string | null;\n};\n\nexport const Underline: ExtensionAuto<UnderlineOptions> = (builder, opts) => {\n builder.use(UnderlineSpecs);\n\n builder\n .addAction(undAction, ({schema}) => createMarkdownInlineMarkAction(underlineType(schema)))\n .addInputRules(({schema}) => ({\n rules: [\n markInputRule({open: '++', close: '++', ignoreBetween: '+'}, underlineType(schema)),\n ],\n }));\n\n if (opts?.underlineKey) {\n const {underlineKey} = opts;\n builder.addKeymap(({schema}) => ({\n [underlineKey]: withLogAction('underline', toggleMark(underlineType(schema))),\n }));\n }\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [undAction]: Action;\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createMarkdownInlineMarkAction } from "../../../utils/actions.js";
|
|
2
2
|
import { markInputRule } from "../../../utils/inputrules.js";
|
|
3
3
|
import { MonospaceSpecs, monospaceType } from "./MonospaceSpecs/index.js";
|
|
4
4
|
export { monospaceMarkName, monospaceType } from "./MonospaceSpecs/index.js";
|
|
@@ -6,7 +6,7 @@ const monoAction = 'mono';
|
|
|
6
6
|
export const Monospace = (builder) => {
|
|
7
7
|
builder.use(MonospaceSpecs);
|
|
8
8
|
builder
|
|
9
|
-
.addAction(monoAction, ({ schema }) =>
|
|
9
|
+
.addAction(monoAction, ({ schema }) => createMarkdownInlineMarkAction(monospaceType(schema)))
|
|
10
10
|
.addInputRules(({ schema }) => ({
|
|
11
11
|
rules: [
|
|
12
12
|
markInputRule({ open: '##', close: '##', ignoreBetween: '#' }, monospaceType(schema)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Monospace/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Monospace/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,8BAA8B,EAAC,kCAA+B;AACtE,OAAO,EAAC,aAAa,EAAC,qCAAkC;AAExD,OAAO,EAAC,cAAc,EAAE,aAAa,EAAC,kCAAyB;AAE/D,OAAO,EAAC,iBAAiB,EAAE,aAAa,EAAC,kCAAyB;AAClE,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,MAAM,CAAC,MAAM,SAAS,GAAkB,CAAC,OAAO,EAAE,EAAE;IAChD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5B,OAAO;SACF,SAAS,CAAC,UAAU,EAAE,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,8BAA8B,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;SAC1F,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,aAAa,CAAC,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;SACtF;KACJ,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC","sourcesContent":["import type {Action, ExtensionAuto} from '../../../core';\nimport {createMarkdownInlineMarkAction} from '../../../utils/actions';\nimport {markInputRule} from '../../../utils/inputrules';\n\nimport {MonospaceSpecs, monospaceType} from './MonospaceSpecs';\n\nexport {monospaceMarkName, monospaceType} from './MonospaceSpecs';\nconst monoAction = 'mono';\n\nexport const Monospace: ExtensionAuto = (builder) => {\n builder.use(MonospaceSpecs);\n\n builder\n .addAction(monoAction, ({schema}) => createMarkdownInlineMarkAction(monospaceType(schema)))\n .addInputRules(({schema}) => ({\n rules: [\n markInputRule({open: '##', close: '##', ignoreBetween: '#'}, monospaceType(schema)),\n ],\n }));\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [monoAction]: Action;\n }\n }\n}\n"]}
|
|
@@ -2,3 +2,9 @@ import type { MarkType } from 'prosemirror-model';
|
|
|
2
2
|
import type { ActionSpec } from "../core/index.js";
|
|
3
3
|
export declare function defineActions<Keys extends string>(actions: Record<Keys, ActionSpec>): Record<Keys, ActionSpec>;
|
|
4
4
|
export declare function createToggleMarkAction(markType: MarkType): ActionSpec;
|
|
5
|
+
/**
|
|
6
|
+
* Like createToggleMarkAction, but blocks applying the mark when the selection
|
|
7
|
+
* boundaries would produce markdown that cannot round-trip (e.g. `word**,**`).
|
|
8
|
+
* Removing the mark (toggling off) is always allowed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createMarkdownInlineMarkAction(markType: MarkType): ActionSpec;
|