@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.
Files changed (93) hide show
  1. package/build/cjs/core/Editor.js +2 -0
  2. package/build/cjs/core/Editor.js.map +1 -1
  3. package/build/cjs/core/index.d.ts +1 -0
  4. package/build/cjs/core/index.js +3 -1
  5. package/build/cjs/core/index.js.map +1 -1
  6. package/build/cjs/core/markdown/MarkdownParser.d.ts +1 -0
  7. package/build/cjs/core/markdown/MarkdownParser.js +3 -0
  8. package/build/cjs/core/markdown/MarkdownParser.js.map +1 -1
  9. package/build/cjs/core/types/parser.d.ts +1 -0
  10. package/build/cjs/core/types/parser.js.map +1 -1
  11. package/build/cjs/core/utils/parser.d.ts +3 -0
  12. package/build/cjs/core/utils/parser.js +12 -0
  13. package/build/cjs/core/utils/parser.js.map +1 -0
  14. package/build/cjs/extensions/behavior/SelectionContext/tooltip.js +3 -0
  15. package/build/cjs/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
  16. package/build/cjs/extensions/markdown/Bold/index.js +1 -1
  17. package/build/cjs/extensions/markdown/Bold/index.js.map +1 -1
  18. package/build/cjs/extensions/markdown/Code/index.js +1 -1
  19. package/build/cjs/extensions/markdown/Code/index.js.map +1 -1
  20. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +75 -66
  21. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
  22. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js +42 -22
  23. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js.map +1 -1
  24. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js +20 -0
  25. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js.map +1 -1
  26. package/build/cjs/extensions/markdown/Italic/index.js +1 -1
  27. package/build/cjs/extensions/markdown/Italic/index.js.map +1 -1
  28. package/build/cjs/extensions/markdown/Mark/index.js +1 -1
  29. package/build/cjs/extensions/markdown/Mark/index.js.map +1 -1
  30. package/build/cjs/extensions/markdown/Strike/index.js +1 -1
  31. package/build/cjs/extensions/markdown/Strike/index.js.map +1 -1
  32. package/build/cjs/extensions/markdown/Underline/index.js +1 -1
  33. package/build/cjs/extensions/markdown/Underline/index.js.map +1 -1
  34. package/build/cjs/extensions/yfm/Monospace/index.js +1 -1
  35. package/build/cjs/extensions/yfm/Monospace/index.js.map +1 -1
  36. package/build/cjs/utils/actions.d.ts +6 -0
  37. package/build/cjs/utils/actions.js +24 -0
  38. package/build/cjs/utils/actions.js.map +1 -1
  39. package/build/cjs/utils/marks.d.ts +6 -0
  40. package/build/cjs/utils/marks.js +31 -0
  41. package/build/cjs/utils/marks.js.map +1 -1
  42. package/build/cjs/utils/transaction.d.ts +1 -0
  43. package/build/cjs/utils/transaction.js +40 -0
  44. package/build/cjs/utils/transaction.js.map +1 -0
  45. package/build/cjs/version.js +1 -1
  46. package/build/cjs/version.js.map +1 -1
  47. package/build/esm/core/Editor.js +2 -0
  48. package/build/esm/core/Editor.js.map +1 -1
  49. package/build/esm/core/index.d.ts +1 -0
  50. package/build/esm/core/index.js +1 -0
  51. package/build/esm/core/index.js.map +1 -1
  52. package/build/esm/core/markdown/MarkdownParser.d.ts +1 -0
  53. package/build/esm/core/markdown/MarkdownParser.js +3 -0
  54. package/build/esm/core/markdown/MarkdownParser.js.map +1 -1
  55. package/build/esm/core/types/parser.d.ts +1 -0
  56. package/build/esm/core/types/parser.js.map +1 -1
  57. package/build/esm/core/utils/parser.d.ts +3 -0
  58. package/build/esm/core/utils/parser.js +8 -0
  59. package/build/esm/core/utils/parser.js.map +1 -0
  60. package/build/esm/extensions/behavior/SelectionContext/tooltip.js +3 -0
  61. package/build/esm/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
  62. package/build/esm/extensions/markdown/Bold/index.js +2 -2
  63. package/build/esm/extensions/markdown/Bold/index.js.map +1 -1
  64. package/build/esm/extensions/markdown/Code/index.js +2 -2
  65. package/build/esm/extensions/markdown/Code/index.js.map +1 -1
  66. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +75 -66
  67. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
  68. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js +43 -23
  69. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLineNumbersPlugin.js.map +1 -1
  70. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js +20 -1
  71. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/utils.js.map +1 -1
  72. package/build/esm/extensions/markdown/Italic/index.js +2 -2
  73. package/build/esm/extensions/markdown/Italic/index.js.map +1 -1
  74. package/build/esm/extensions/markdown/Mark/index.js +2 -2
  75. package/build/esm/extensions/markdown/Mark/index.js.map +1 -1
  76. package/build/esm/extensions/markdown/Strike/index.js +2 -2
  77. package/build/esm/extensions/markdown/Strike/index.js.map +1 -1
  78. package/build/esm/extensions/markdown/Underline/index.js +2 -2
  79. package/build/esm/extensions/markdown/Underline/index.js.map +1 -1
  80. package/build/esm/extensions/yfm/Monospace/index.js +2 -2
  81. package/build/esm/extensions/yfm/Monospace/index.js.map +1 -1
  82. package/build/esm/utils/actions.d.ts +6 -0
  83. package/build/esm/utils/actions.js +24 -1
  84. package/build/esm/utils/actions.js.map +1 -1
  85. package/build/esm/utils/marks.d.ts +6 -0
  86. package/build/esm/utils/marks.js +30 -0
  87. package/build/esm/utils/marks.js.map +1 -1
  88. package/build/esm/utils/transaction.d.ts +1 -0
  89. package/build/esm/utils/transaction.js +36 -0
  90. package/build/esm/utils/transaction.js.map +1 -0
  91. package/build/esm/version.js +1 -1
  92. package/build/esm/version.js.map +1 -1
  93. 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 key = new PluginKey('code_block_highlight');
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(key, { modulesLoaded }));
69
+ view.dispatch(view.state.tr.setMeta(pluginKey, { modulesLoaded }));
69
70
  }
70
71
  }
71
72
  });
72
- return getDecorations(state.doc);
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, decos, oldState, newState) => {
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(key)?.modulesLoaded) {
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
- const oldNodeName = oldState.selection.$head.parent.type.name;
83
- const newNodeName = newState.selection.$head.parent.type.name;
84
- // Apply decorations if:
85
- if (oldNodeName === codeBlockNodeName ||
86
- newNodeName === codeBlockNodeName) {
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
- else {
91
- const oldNodes = findChildrenByType(oldState.doc, codeBlockType(oldState.schema));
92
- const newNodes = findChildrenByType(newState.doc, codeBlockType(newState.schema));
93
- if (
94
- // OR transaction adds/removes codeblock nodes,
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
- return decos.map(tr.mapping, tr.doc);
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: (state) => {
120
- return key.getState(state);
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 && lowlight.registered(lang)) {
138
- nodes = lowlight.highlight(lang, node.textContent).children;
139
- }
140
- else {
136
+ if (!lang || !lowlight.registered(lang)) {
141
137
  continue;
142
138
  }
143
- for (const { text, classes } of parseNodes(nodes)) {
144
- const to = from + text.length;
145
- if (classes.length) {
146
- decos.push(Decoration.inline(from, to, {
147
- class: classes.join(' '),
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
- return nodes
158
- .map((node) => {
159
- let classes = className;
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 = classes.concat(node.properties.className ?? []);
162
- return parseNodes(node.children, classes);
173
+ const classes = className.concat(node.properties.className ?? []);
174
+ collectNodes(node.children, classes, result);
163
175
  }
164
- return {
165
- text: node.type === 'comment' || node.type === 'text' ? node.value : '',
166
- classes,
167
- };
168
- })
169
- .flat();
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
@@ -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
- return getDecorations(state.doc);
13
+ const cache = new WeakSet();
14
+ return { cache, decoSet: buildAllDecorations(state.doc, cache) };
14
15
  },
15
- apply(tr, decos) {
16
- if (tr.docChanged) {
17
- return getDecorations(tr.doc);
18
- }
19
- return decos.map(tr.mapping, tr.doc);
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 getDecorations(doc) {
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 codeContent = node.textContent;
35
- const contentByLines = codeContent.split('\n');
36
- const maxDigits = String(contentByLines.length).length;
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;AAE9C,MAAM,SAAS,GAAG,IAAI,SAAS,CAAgB,qCAAqC,CAAC,CAAC;AAEtF,gBAAgB;AAChB,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,EAAE;IAC3C,OAAO,IAAI,MAAM,CAAgB;QAC7B,GAAG,EAAE,SAAS;QACd,KAAK,EAAE;YACH,IAAI,CAAC,OAAO,EAAE,KAAK;gBACf,OAAO,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACrC,CAAC;YACD,KAAK,CAAC,EAAE,EAAE,KAAK;gBACX,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;oBAChB,OAAO,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBAClC,CAAC;gBAED,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACzC,CAAC;SACJ;QACD,KAAK,EAAE;YACH,WAAW,CAAC,KAAK;gBACb,OAAO,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;SACJ;KACJ,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,SAAS,cAAc,CAAC,GAAS;IAC7B,MAAM,KAAK,GAAiB,EAAE,CAAC;IAE/B,KAAK,MAAM,EAAC,IAAI,EAAE,GAAG,EAAC,IAAI,kBAAkB,CAAC,GAAG,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;QACtF,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;YAAE,SAAS;QAE1C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACrC,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QAEvD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;YAE/B,CAAC;gBACG,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBACtC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBAE1D,KAAK,CAAC,IAAI,CACN,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,IAAI,EAAC,CAAC,CAC7E,CAAC;YACN,CAAC;YAED,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC","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} from '../utils';\n\nconst pluginKey = new PluginKey<DecorationSet>('code_block_line_numbers_decorations');\n\n/** @internal */\nexport const codeBlockLineNumbersPlugin = () => {\n return new Plugin<DecorationSet>({\n key: pluginKey,\n state: {\n init(_config, state) {\n return getDecorations(state.doc);\n },\n apply(tr, decos) {\n if (tr.docChanged) {\n return getDecorations(tr.doc);\n }\n\n return decos.map(tr.mapping, tr.doc);\n },\n },\n props: {\n decorations(state) {\n return pluginKey.getState(state);\n },\n },\n });\n};\n\nfunction getDecorations(doc: Node) {\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 codeContent = node.textContent;\n const contentByLines = codeContent.split('\\n');\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 {\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(\n Decoration.widget(pos + shift + 1, elem, {side: 1, ignoreSelection: true}),\n );\n }\n\n shift += line.length + 1;\n }\n }\n\n return DecorationSet.create(doc, decos);\n}\n"]}
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 { CodeBlockNodeAttr } from "../CodeBlockSpecs/index.js";
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":"AAEA,OAAO,EAAC,iBAAiB,EAAC,mCAA0B;AAEpD,gBAAgB;AAChB,MAAM,UAAU,oBAAoB,CAAC,IAAU;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC;AACpE,CAAC","sourcesContent":["import type {Node} from '#pm/model';\n\nimport {CodeBlockNodeAttr} from '../CodeBlockSpecs';\n\n/** @internal */\nexport function isLineNumbersVisible(node: Node): boolean {\n return node.attrs[CodeBlockNodeAttr.ShowLineNumbers] === 'true';\n}\n"]}
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 { createToggleMarkAction } from "../../../utils/actions.js";
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 }) => createToggleMarkAction(italicType(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,sBAAsB,EAAC,kCAA+B;AAC9D,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,sBAAsB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAErF,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 {createToggleMarkAction} 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}) => createToggleMarkAction(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
+ {"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 { createToggleMarkAction } from "../../../utils/actions.js";
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 }) => createToggleMarkAction(markMarkType(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,sBAAsB,EAAC,kCAA+B;AAC9D,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,sBAAsB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;SAC9E,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 {createToggleMarkAction} 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}) => createToggleMarkAction(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
+ {"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 { createToggleMarkAction } from "../../../utils/actions.js";
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 }) => createToggleMarkAction(strikeType(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,sBAAsB,EAAC,kCAA+B;AAC9D,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,sBAAsB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;SAC5E,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 {createToggleMarkAction} 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}) => createToggleMarkAction(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
+ {"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 { createToggleMarkAction } from "../../../utils/actions.js";
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 }) => createToggleMarkAction(underlineType(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,sBAAsB,EAAC,kCAA+B;AAC9D,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,sBAAsB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;SACjF,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 {createToggleMarkAction} 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}) => createToggleMarkAction(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
+ {"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 { createToggleMarkAction } from "../../../utils/actions.js";
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 }) => createToggleMarkAction(monospaceType(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,sBAAsB,EAAC,kCAA+B;AAC9D,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,sBAAsB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;SAClF,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 {createToggleMarkAction} 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}) => createToggleMarkAction(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"]}
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;