mossmd 0.8.1
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/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +336 -0
- package/dist/collab/index.d.ts +14 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +6 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/core/code-languages.d.ts +3 -0
- package/dist/core/code-languages.d.ts.map +1 -0
- package/dist/core/code-languages.js +130 -0
- package/dist/core/code-languages.js.map +1 -0
- package/dist/core/decoration-utils.d.ts +4 -0
- package/dist/core/decoration-utils.d.ts.map +1 -0
- package/dist/core/decoration-utils.js +25 -0
- package/dist/core/decoration-utils.js.map +1 -0
- package/dist/core/edit-helpers.d.ts +13 -0
- package/dist/core/edit-helpers.d.ts.map +1 -0
- package/dist/core/edit-helpers.js +318 -0
- package/dist/core/edit-helpers.js.map +1 -0
- package/dist/core/icons.d.ts +16 -0
- package/dist/core/icons.d.ts.map +1 -0
- package/dist/core/icons.js +86 -0
- package/dist/core/icons.js.map +1 -0
- package/dist/core/inline-preview.d.ts +32 -0
- package/dist/core/inline-preview.d.ts.map +1 -0
- package/dist/core/inline-preview.js +925 -0
- package/dist/core/inline-preview.js.map +1 -0
- package/dist/core/list-editing.d.ts +10 -0
- package/dist/core/list-editing.d.ts.map +1 -0
- package/dist/core/list-editing.js +244 -0
- package/dist/core/list-editing.js.map +1 -0
- package/dist/core/list-model.d.ts +40 -0
- package/dist/core/list-model.d.ts.map +1 -0
- package/dist/core/list-model.js +114 -0
- package/dist/core/list-model.js.map +1 -0
- package/dist/core/list-navigation.d.ts +3 -0
- package/dist/core/list-navigation.d.ts.map +1 -0
- package/dist/core/list-navigation.js +234 -0
- package/dist/core/list-navigation.js.map +1 -0
- package/dist/core/markdown-context.d.ts +3 -0
- package/dist/core/markdown-context.d.ts.map +1 -0
- package/dist/core/markdown-context.js +10 -0
- package/dist/core/markdown-context.js.map +1 -0
- package/dist/core/preview-activity.d.ts +18 -0
- package/dist/core/preview-activity.d.ts.map +1 -0
- package/dist/core/preview-activity.js +199 -0
- package/dist/core/preview-activity.js.map +1 -0
- package/dist/core/preview-widgets.d.ts +65 -0
- package/dist/core/preview-widgets.d.ts.map +1 -0
- package/dist/core/preview-widgets.js +359 -0
- package/dist/core/preview-widgets.js.map +1 -0
- package/dist/core/read-only.d.ts +26 -0
- package/dist/core/read-only.d.ts.map +1 -0
- package/dist/core/read-only.js +49 -0
- package/dist/core/read-only.js.map +1 -0
- package/dist/core/tree-progress.d.ts +29 -0
- package/dist/core/tree-progress.d.ts.map +1 -0
- package/dist/core/tree-progress.js +143 -0
- package/dist/core/tree-progress.js.map +1 -0
- package/dist/editor.d.ts +219 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +551 -0
- package/dist/editor.js.map +1 -0
- package/dist/features/callout/index.d.ts +9 -0
- package/dist/features/callout/index.d.ts.map +1 -0
- package/dist/features/callout/index.js +223 -0
- package/dist/features/callout/index.js.map +1 -0
- package/dist/features/file-blocks/index.d.ts +12 -0
- package/dist/features/file-blocks/index.d.ts.map +1 -0
- package/dist/features/file-blocks/index.js +397 -0
- package/dist/features/file-blocks/index.js.map +1 -0
- package/dist/features/image/index.d.ts +28 -0
- package/dist/features/image/index.d.ts.map +1 -0
- package/dist/features/image/index.js +699 -0
- package/dist/features/image/index.js.map +1 -0
- package/dist/features/index.d.ts +17 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +9 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/search/index.d.ts +4 -0
- package/dist/features/search/index.d.ts.map +1 -0
- package/dist/features/search/index.js +131 -0
- package/dist/features/search/index.js.map +1 -0
- package/dist/features/slash-commands/index.d.ts +52 -0
- package/dist/features/slash-commands/index.d.ts.map +1 -0
- package/dist/features/slash-commands/index.js +422 -0
- package/dist/features/slash-commands/index.js.map +1 -0
- package/dist/features/table/index.d.ts +44 -0
- package/dist/features/table/index.d.ts.map +1 -0
- package/dist/features/table/index.js +1262 -0
- package/dist/features/table/index.js.map +1 -0
- package/dist/features/upload/index.d.ts +80 -0
- package/dist/features/upload/index.d.ts.map +1 -0
- package/dist/features/upload/index.js +790 -0
- package/dist/features/upload/index.js.map +1 -0
- package/dist/features/wiki-links/index.d.ts +27 -0
- package/dist/features/wiki-links/index.d.ts.map +1 -0
- package/dist/features/wiki-links/index.js +577 -0
- package/dist/features/wiki-links/index.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/content.css +247 -0
- package/dist/styles/inline-preview.css +2116 -0
- package/dist/styles/tokens.css +234 -0
- package/dist/syntax/highlight.d.ts +10 -0
- package/dist/syntax/highlight.d.ts.map +1 -0
- package/dist/syntax/highlight.js +75 -0
- package/dist/syntax/highlight.js.map +1 -0
- package/dist/syntax/index.d.ts +16 -0
- package/dist/syntax/index.d.ts.map +1 -0
- package/dist/syntax/index.js +29 -0
- package/dist/syntax/index.js.map +1 -0
- package/dist/theme/index.d.ts +6 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +204 -0
- package/dist/theme/index.js.map +1 -0
- package/package.json +237 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// Slash commands.
|
|
2
|
+
//
|
|
3
|
+
// Two trigger paths share one completion source:
|
|
4
|
+
//
|
|
5
|
+
// * Type `/` at the start of an (otherwise empty) line → popup opens,
|
|
6
|
+
// filters as you type. URL mid-text `/` doesn't fire because the
|
|
7
|
+
// trigger requires line-start with only whitespace before.
|
|
8
|
+
// * Click the `+` button rendered at the start of the cursor's line
|
|
9
|
+
// when that line is empty → popup opens via `startCompletion`.
|
|
10
|
+
//
|
|
11
|
+
// Both paths land in the same source, which calls `config.suggest` (or
|
|
12
|
+
// filters `config.commands` locally) and applies the chosen command's
|
|
13
|
+
// `apply` callback. `apply` may be async — that's how upload-image /
|
|
14
|
+
// upload-file pick from disk and then dispatch the resulting markdown.
|
|
15
|
+
//
|
|
16
|
+
// The `/` trigger character is temporary scaffolding: when a command
|
|
17
|
+
// is selected, `apply` replaces the `/query` range with the command's
|
|
18
|
+
// snippet, so the slash doesn't survive in the doc. Raw markdown
|
|
19
|
+
// remains the only source of truth (project invariant).
|
|
20
|
+
//
|
|
21
|
+
// Default commands ship an upload-image / upload-file skeleton that
|
|
22
|
+
// uses the browser file picker and creates a local object URL — fine
|
|
23
|
+
// for a demo, but consumers are expected to either override these or
|
|
24
|
+
// supply their own commands that talk to a real upload service.
|
|
25
|
+
import { autocompletion, startCompletion, } from '@codemirror/autocomplete';
|
|
26
|
+
import { EditorState } from '@codemirror/state';
|
|
27
|
+
import { Decoration, ViewPlugin, WidgetType, } from '@codemirror/view';
|
|
28
|
+
import { Code2, File, FileImage, FileText, List, MessageSquare, Minus, Plus, Table2, } from 'lucide-react';
|
|
29
|
+
import { appendMossIcon, mossLucideIcon, } from '../../core/icons';
|
|
30
|
+
import { readOnlyFacet } from '../../core/read-only';
|
|
31
|
+
import { mossUploadBlocks } from '../upload';
|
|
32
|
+
const SIDE_PLUS_ICON = mossLucideIcon(Plus, { size: 18, strokeWidth: 2 });
|
|
33
|
+
const SLASH_COMMAND_ICONS = {
|
|
34
|
+
image: mossLucideIcon(FileImage),
|
|
35
|
+
file: mossLucideIcon(File),
|
|
36
|
+
snippet: mossLucideIcon(FileText),
|
|
37
|
+
list: mossLucideIcon(List),
|
|
38
|
+
code: mossLucideIcon(Code2),
|
|
39
|
+
table: mossLucideIcon(Table2),
|
|
40
|
+
rule: mossLucideIcon(Minus),
|
|
41
|
+
callout: mossLucideIcon(MessageSquare),
|
|
42
|
+
};
|
|
43
|
+
function isSlashCommandCompletion(completion) {
|
|
44
|
+
return 'command' in completion;
|
|
45
|
+
}
|
|
46
|
+
function renderSlashCommandIcon(completion) {
|
|
47
|
+
if (!isSlashCommandCompletion(completion))
|
|
48
|
+
return null;
|
|
49
|
+
const configuredIcon = completion.command.icon;
|
|
50
|
+
const iconKey = typeof configuredIcon === 'string' && /^[\w-]+$/.test(configuredIcon)
|
|
51
|
+
? configuredIcon
|
|
52
|
+
: typeof configuredIcon === 'string'
|
|
53
|
+
? 'snippet'
|
|
54
|
+
: 'custom';
|
|
55
|
+
const iconSource = typeof configuredIcon === 'string'
|
|
56
|
+
? SLASH_COMMAND_ICONS[iconKey] ?? SLASH_COMMAND_ICONS.snippet
|
|
57
|
+
: configuredIcon ?? SLASH_COMMAND_ICONS.snippet;
|
|
58
|
+
const icon = document.createElement('span');
|
|
59
|
+
icon.className = `cm-completionIcon cm-completionIcon-moss-${iconKey}`;
|
|
60
|
+
icon.setAttribute('aria-hidden', 'true');
|
|
61
|
+
appendMossIcon(icon, iconSource, {
|
|
62
|
+
size: 16,
|
|
63
|
+
strokeWidth: 1.8,
|
|
64
|
+
ariaHidden: true,
|
|
65
|
+
});
|
|
66
|
+
return icon;
|
|
67
|
+
}
|
|
68
|
+
// `matchBefore` searches within the current line. Do not anchor this
|
|
69
|
+
// expression at the start, otherwise an indented line such as ` /` can
|
|
70
|
+
// never match; the line-start policy is checked separately below.
|
|
71
|
+
const SLASH_QUERY_RE = /\/[\w-]*$/;
|
|
72
|
+
export function mossSlashCommands(config, options = {}) {
|
|
73
|
+
// Register the source via `EditorState.languageData` (additive,
|
|
74
|
+
// mergeable) rather than `autocompletion({ override: [...] })`
|
|
75
|
+
// (single-valued, conflicts on merge). Multiple features can each
|
|
76
|
+
// contribute their own completion sources this way without
|
|
77
|
+
// colliding — wiki-links and slash-commands coexist cleanly.
|
|
78
|
+
//
|
|
79
|
+
// CRITICAL: the `autocomplete` value MUST be a stable function
|
|
80
|
+
// reference. `CompletionState.update` looks up the existing
|
|
81
|
+
// ActiveSource via `this.active.find(s => s.source == source)` —
|
|
82
|
+
// identity comparison. If the provider returns a fresh arrow each
|
|
83
|
+
// call, the lookup never matches, every update creates a new
|
|
84
|
+
// ActiveSource (starting Inactive), and the Activate transition
|
|
85
|
+
// gets thrown away by the `active == this.active` short-circuit
|
|
86
|
+
// check downstream. The result: provider fires, but the source is
|
|
87
|
+
// never queried.
|
|
88
|
+
const autocompleteHandler = (context) => source(context, config);
|
|
89
|
+
const extensions = [
|
|
90
|
+
EditorState.languageData.of(() => [{ autocomplete: autocompleteHandler }]),
|
|
91
|
+
// Global autocomplete config (without override). Equal-valued
|
|
92
|
+
// scalar fields merge without conflict, so multiple features can
|
|
93
|
+
// each call `autocompletion(...)` to set defaults; the values
|
|
94
|
+
// must agree or CM6 throws "Config merge conflict".
|
|
95
|
+
autocompletion({
|
|
96
|
+
activateOnTyping: true,
|
|
97
|
+
// Wiki-link completion may disable CodeMirror's shared icon
|
|
98
|
+
// renderer. Slash commands render their own Lucide icon below,
|
|
99
|
+
// so they remain visible when both completion features are enabled.
|
|
100
|
+
icons: false,
|
|
101
|
+
addToOptions: [
|
|
102
|
+
{
|
|
103
|
+
position: 20,
|
|
104
|
+
render: renderSlashCommandIcon,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
closeOnBlur: true,
|
|
108
|
+
}),
|
|
109
|
+
];
|
|
110
|
+
if (config.sideButton) {
|
|
111
|
+
extensions.push(sidePlusButtonPlugin);
|
|
112
|
+
}
|
|
113
|
+
// Upload progress widgets are included by default for backwards
|
|
114
|
+
// compatibility. A dedicated file-upload extension can own the field
|
|
115
|
+
// instead, avoiding duplicate StateField registration.
|
|
116
|
+
if (options.includeUploadBlocks !== false) {
|
|
117
|
+
extensions.push(mossUploadBlocks(options.uploadBlocksConfig));
|
|
118
|
+
}
|
|
119
|
+
return extensions;
|
|
120
|
+
}
|
|
121
|
+
async function source(context, config) {
|
|
122
|
+
if (context.state.facet(readOnlyFacet))
|
|
123
|
+
return null;
|
|
124
|
+
// Path A: user typed /query.
|
|
125
|
+
const slashMatch = context.matchBefore(SLASH_QUERY_RE);
|
|
126
|
+
if (slashMatch) {
|
|
127
|
+
// Trigger gate: when triggerAtLineStart (default true), the slash
|
|
128
|
+
// must be the first non-whitespace character on its line. Without
|
|
129
|
+
// this gate, `https://...` mid-text would pop the menu.
|
|
130
|
+
if (config.triggerAtLineStart !== false) {
|
|
131
|
+
const line = context.state.doc.lineAt(slashMatch.from);
|
|
132
|
+
const before = line.text.slice(0, slashMatch.from - line.from);
|
|
133
|
+
if (before.trim() !== '')
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const line = context.state.doc.lineAt(slashMatch.from);
|
|
138
|
+
const before = line.text.slice(0, slashMatch.from - line.from);
|
|
139
|
+
if (before !== '' && !/\s$/.test(before))
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const query = slashMatch.text.slice(1);
|
|
143
|
+
const commands = await resolveCommands(config, query);
|
|
144
|
+
if (context.aborted)
|
|
145
|
+
return null;
|
|
146
|
+
return {
|
|
147
|
+
// Let CodeMirror filter the command query without treating `/` as
|
|
148
|
+
// part of the completion text. `toOption` expands the apply range
|
|
149
|
+
// back over the trigger when a command is accepted.
|
|
150
|
+
from: slashMatch.from + 1,
|
|
151
|
+
to: context.pos,
|
|
152
|
+
options: commands.map((cmd) => toOption(cmd)),
|
|
153
|
+
validFor: config.suggest ? () => false : /^[\w-]*$/,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// Path B: explicit invocation via the side `+` button. CM6 sets
|
|
157
|
+
// `context.explicit = true` when `startCompletion` is called. Only
|
|
158
|
+
// fire when the cursor is on an empty (whitespace-only) line, so
|
|
159
|
+
// programmatically opening the menu doesn't surprise users mid-prose.
|
|
160
|
+
if (context.explicit && isCursorOnEmptyLine(context.state, context.pos)) {
|
|
161
|
+
const commands = await resolveCommands(config, '');
|
|
162
|
+
if (context.aborted)
|
|
163
|
+
return null;
|
|
164
|
+
return {
|
|
165
|
+
from: context.pos,
|
|
166
|
+
options: commands.map((cmd) => toOption(cmd)),
|
|
167
|
+
validFor: /^[\w-]*$/,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
async function resolveCommands(config, query) {
|
|
173
|
+
const list = config.suggest ? await config.suggest(query) : config.commands;
|
|
174
|
+
const filtered = config.suggest ? list : defaultFilter(list, query);
|
|
175
|
+
return filtered.slice(0, config.maxResults ?? 12);
|
|
176
|
+
}
|
|
177
|
+
function defaultFilter(commands, query) {
|
|
178
|
+
const q = query.toLowerCase();
|
|
179
|
+
if (!q)
|
|
180
|
+
return [...commands];
|
|
181
|
+
const scored = [];
|
|
182
|
+
for (const cmd of commands) {
|
|
183
|
+
const label = cmd.label.toLowerCase();
|
|
184
|
+
const id = cmd.id.toLowerCase();
|
|
185
|
+
const keywords = cmd.keywords?.map((k) => k.toLowerCase()) ?? [];
|
|
186
|
+
let score = 0;
|
|
187
|
+
if (label === q || id === q)
|
|
188
|
+
score = 100;
|
|
189
|
+
else if (label.startsWith(q) || id.startsWith(q))
|
|
190
|
+
score = 80;
|
|
191
|
+
else if (label.includes(q) || id.includes(q))
|
|
192
|
+
score = 60;
|
|
193
|
+
else if (keywords.some((k) => k.includes(q)))
|
|
194
|
+
score = 40;
|
|
195
|
+
if (score > 0)
|
|
196
|
+
scored.push({ cmd, score });
|
|
197
|
+
}
|
|
198
|
+
scored.sort((a, b) => b.score - a.score);
|
|
199
|
+
return scored.map((s) => s.cmd);
|
|
200
|
+
}
|
|
201
|
+
function toOption(cmd) {
|
|
202
|
+
const typeIcon = typeof cmd.icon === 'string' && /^[\w-]+$/.test(cmd.icon)
|
|
203
|
+
? cmd.icon
|
|
204
|
+
: 'snippet';
|
|
205
|
+
return {
|
|
206
|
+
label: cmd.label,
|
|
207
|
+
detail: cmd.detail,
|
|
208
|
+
type: `moss-${typeIcon}`,
|
|
209
|
+
apply: (view, _completion, from, to) => {
|
|
210
|
+
// Forward to the command's apply. We don't await — CM6 doesn't
|
|
211
|
+
// expect apply to return a promise, but async side effects (file
|
|
212
|
+
// upload, network) are fine since they dispatch their own
|
|
213
|
+
// transactions when ready.
|
|
214
|
+
const triggerFrom = from > 0 && view.state.sliceDoc(from - 1, from) === '/'
|
|
215
|
+
? from - 1
|
|
216
|
+
: from;
|
|
217
|
+
void cmd.apply(view, triggerFrom, to);
|
|
218
|
+
},
|
|
219
|
+
command: cmd,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function isCursorOnEmptyLine(state, pos) {
|
|
223
|
+
const line = state.doc.lineAt(pos);
|
|
224
|
+
return line.text.trim() === '';
|
|
225
|
+
}
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
// Side `+` button
|
|
228
|
+
//
|
|
229
|
+
// A non-block widget rendered at the start of the cursor's line when
|
|
230
|
+
// that line is empty. Clicking focuses the editor and calls
|
|
231
|
+
// `startCompletion`, which lands in path B of the source above. Only
|
|
232
|
+
// the cursor's line gets a button — keeps the DOM cheap on long docs
|
|
233
|
+
// and matches Notion's "discoverable on the active empty line" UX
|
|
234
|
+
// rather than rendering buttons for every empty line in the viewport.
|
|
235
|
+
//
|
|
236
|
+
// The button is a non-block decoration at the start of the active line.
|
|
237
|
+
// CSS moves it visually into the left gutter without changing the row's
|
|
238
|
+
// document layout.
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
class SidePlusWidget extends WidgetType {
|
|
241
|
+
constructor(lineFrom) {
|
|
242
|
+
super();
|
|
243
|
+
Object.defineProperty(this, "lineFrom", {
|
|
244
|
+
enumerable: true,
|
|
245
|
+
configurable: true,
|
|
246
|
+
writable: true,
|
|
247
|
+
value: lineFrom
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
eq(other) {
|
|
251
|
+
return other.lineFrom === this.lineFrom;
|
|
252
|
+
}
|
|
253
|
+
toDOM(view) {
|
|
254
|
+
const btn = document.createElement('button');
|
|
255
|
+
btn.type = 'button';
|
|
256
|
+
btn.className = 'cm-moss-side-plus';
|
|
257
|
+
appendMossIcon(btn, SIDE_PLUS_ICON);
|
|
258
|
+
btn.title = 'Add a block (or type /)';
|
|
259
|
+
btn.setAttribute('aria-label', 'Add a block');
|
|
260
|
+
btn.addEventListener('mousedown', (event) => {
|
|
261
|
+
// Prevent the editor from stealing focus / moving the caret
|
|
262
|
+
// before we dispatch our own selection.
|
|
263
|
+
event.preventDefault();
|
|
264
|
+
event.stopPropagation();
|
|
265
|
+
view.focus();
|
|
266
|
+
view.dispatch({
|
|
267
|
+
selection: { anchor: this.lineFrom },
|
|
268
|
+
scrollIntoView: false,
|
|
269
|
+
});
|
|
270
|
+
startCompletion(view);
|
|
271
|
+
});
|
|
272
|
+
btn.addEventListener('click', (event) => {
|
|
273
|
+
// Keep the follow-up click from being handled by the editor after
|
|
274
|
+
// the mousedown handler has placed the caret on this line.
|
|
275
|
+
event.preventDefault();
|
|
276
|
+
event.stopPropagation();
|
|
277
|
+
});
|
|
278
|
+
return btn;
|
|
279
|
+
}
|
|
280
|
+
ignoreEvent() {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function buildSidePlusDecorations(view) {
|
|
285
|
+
const { state } = view;
|
|
286
|
+
if (state.facet(readOnlyFacet))
|
|
287
|
+
return Decoration.none;
|
|
288
|
+
if (!view.hasFocus)
|
|
289
|
+
return Decoration.none;
|
|
290
|
+
const sel = state.selection.main;
|
|
291
|
+
if (!sel.empty)
|
|
292
|
+
return Decoration.none;
|
|
293
|
+
const line = state.doc.lineAt(sel.head);
|
|
294
|
+
if (line.text.trim() !== '')
|
|
295
|
+
return Decoration.none;
|
|
296
|
+
// Only render when the cursor is at the start of the empty line —
|
|
297
|
+
// if the user moved into the middle of whitespace, don't show the
|
|
298
|
+
// button (they're navigating, not adding a block).
|
|
299
|
+
if (sel.head !== line.from)
|
|
300
|
+
return Decoration.none;
|
|
301
|
+
return Decoration.set([
|
|
302
|
+
Decoration.widget({
|
|
303
|
+
widget: new SidePlusWidget(line.from),
|
|
304
|
+
// Non-block: renders inline at line.from. CSS shifts it
|
|
305
|
+
// absolutely into the left gutter without taking a row.
|
|
306
|
+
side: -1,
|
|
307
|
+
}).range(line.from),
|
|
308
|
+
], true);
|
|
309
|
+
}
|
|
310
|
+
const sidePlusButtonPlugin = ViewPlugin.fromClass(class {
|
|
311
|
+
constructor(view) {
|
|
312
|
+
Object.defineProperty(this, "decorations", {
|
|
313
|
+
enumerable: true,
|
|
314
|
+
configurable: true,
|
|
315
|
+
writable: true,
|
|
316
|
+
value: void 0
|
|
317
|
+
});
|
|
318
|
+
this.decorations = buildSidePlusDecorations(view);
|
|
319
|
+
}
|
|
320
|
+
update(update) {
|
|
321
|
+
const readOnlyChanged = update.startState.facet(readOnlyFacet) !==
|
|
322
|
+
update.state.facet(readOnlyFacet);
|
|
323
|
+
if (update.docChanged ||
|
|
324
|
+
update.selectionSet ||
|
|
325
|
+
update.focusChanged ||
|
|
326
|
+
readOnlyChanged) {
|
|
327
|
+
this.decorations = buildSidePlusDecorations(update.view);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}, { decorations: (p) => p.decorations });
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
// Default commands
|
|
333
|
+
//
|
|
334
|
+
// Only the upload-image / upload-file skeletons ship in the package.
|
|
335
|
+
// They use the browser file picker and create a local object URL —
|
|
336
|
+
// fine for a demo, but production consumers should override these with
|
|
337
|
+
// commands that POST to their upload service.
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
export const mossDefaultSlashCommands = [
|
|
340
|
+
{
|
|
341
|
+
id: 'upload-image',
|
|
342
|
+
label: 'Upload image',
|
|
343
|
+
detail: 'Pick from disk and insert ',
|
|
344
|
+
keywords: ['picture', 'photo', 'image', 'img'],
|
|
345
|
+
icon: 'image',
|
|
346
|
+
apply: async (view, from, to) => {
|
|
347
|
+
const files = await pickFiles('image/*');
|
|
348
|
+
if (files.length === 0)
|
|
349
|
+
return;
|
|
350
|
+
const insert = files
|
|
351
|
+
.map((file) => `})`)
|
|
352
|
+
.join('\n\n');
|
|
353
|
+
view.dispatch({
|
|
354
|
+
changes: { from, to, insert },
|
|
355
|
+
// Drop the caret right after `![name` so the user can type
|
|
356
|
+
// `|caption` to split alt and caption, or leave as-is (the
|
|
357
|
+
// name doubles as caption by default).
|
|
358
|
+
selection: { anchor: from + 2 + files[0].name.length },
|
|
359
|
+
});
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
id: 'upload-file',
|
|
364
|
+
label: 'Upload file',
|
|
365
|
+
detail: 'Pick from disk and link [name](url)',
|
|
366
|
+
keywords: ['attachment', 'file', 'link'],
|
|
367
|
+
icon: 'file',
|
|
368
|
+
apply: async (view, from, to) => {
|
|
369
|
+
const files = await pickFiles();
|
|
370
|
+
if (files.length === 0)
|
|
371
|
+
return;
|
|
372
|
+
view.dispatch({
|
|
373
|
+
changes: {
|
|
374
|
+
from,
|
|
375
|
+
to,
|
|
376
|
+
insert: files
|
|
377
|
+
.map((file) => `[${file.name}](${URL.createObjectURL(file)})`)
|
|
378
|
+
.join('\n\n'),
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
];
|
|
384
|
+
function pickFiles(accept) {
|
|
385
|
+
return new Promise((resolve) => {
|
|
386
|
+
const input = document.createElement('input');
|
|
387
|
+
input.type = 'file';
|
|
388
|
+
input.multiple = true;
|
|
389
|
+
if (accept)
|
|
390
|
+
input.accept = accept;
|
|
391
|
+
input.style.position = 'fixed';
|
|
392
|
+
input.style.top = '-9999px';
|
|
393
|
+
input.style.opacity = '0';
|
|
394
|
+
let settled = false;
|
|
395
|
+
const cleanup = () => {
|
|
396
|
+
if (settled)
|
|
397
|
+
return;
|
|
398
|
+
settled = true;
|
|
399
|
+
input.remove();
|
|
400
|
+
window.removeEventListener('focus', onFocus, true);
|
|
401
|
+
};
|
|
402
|
+
const onFocus = () => {
|
|
403
|
+
// Give the change event a chance to fire first; if it didn't,
|
|
404
|
+
// the user cancelled the picker.
|
|
405
|
+
window.setTimeout(() => {
|
|
406
|
+
if (!settled && !input.files?.length) {
|
|
407
|
+
cleanup();
|
|
408
|
+
resolve([]);
|
|
409
|
+
}
|
|
410
|
+
}, 300);
|
|
411
|
+
};
|
|
412
|
+
input.addEventListener('change', () => {
|
|
413
|
+
const files = Array.from(input.files ?? []);
|
|
414
|
+
cleanup();
|
|
415
|
+
resolve(files);
|
|
416
|
+
});
|
|
417
|
+
window.addEventListener('focus', onFocus, true);
|
|
418
|
+
document.body.appendChild(input);
|
|
419
|
+
input.click();
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/features/slash-commands/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Facet, type Extension } from '@codemirror/state';
|
|
2
|
+
interface TableModel {
|
|
3
|
+
header: string[];
|
|
4
|
+
rows: string[][];
|
|
5
|
+
}
|
|
6
|
+
export declare function splitRowCells(line: string): string[];
|
|
7
|
+
export declare function escapeCell(text: string): string;
|
|
8
|
+
export declare function serializeTable(model: TableModel): string;
|
|
9
|
+
type CellToken = {
|
|
10
|
+
type: 'text';
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'strong';
|
|
14
|
+
delim: '**' | '__';
|
|
15
|
+
children: CellToken[];
|
|
16
|
+
} | {
|
|
17
|
+
type: 'em';
|
|
18
|
+
delim: '*' | '_';
|
|
19
|
+
children: CellToken[];
|
|
20
|
+
} | {
|
|
21
|
+
type: 'strike';
|
|
22
|
+
children: CellToken[];
|
|
23
|
+
} | {
|
|
24
|
+
type: 'highlight';
|
|
25
|
+
children: CellToken[];
|
|
26
|
+
} | {
|
|
27
|
+
type: 'link';
|
|
28
|
+
textChildren: CellToken[];
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function parseCellInline(raw: string): CellToken[];
|
|
32
|
+
export interface TablesConfig {
|
|
33
|
+
/**
|
|
34
|
+
* Called when the user clicks the external-link icon on a link
|
|
35
|
+
* rendered inside a table cell. Defaults to `window.open(url,
|
|
36
|
+
* '_blank', 'noopener,noreferrer')`.
|
|
37
|
+
*/
|
|
38
|
+
onLinkClick?: (url: string) => void;
|
|
39
|
+
}
|
|
40
|
+
export type MossTablesConfig = TablesConfig;
|
|
41
|
+
export declare const tableLinkClickFacet: Facet<(url: string) => void, (url: string) => void>;
|
|
42
|
+
export declare function mossTables(config?: TablesConfig): Extension;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/table/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,EAKL,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAC;AAwE3B,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;CAClB;AAYD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BpD;AA2BD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAWxD;AA2CD,KAAK,SAAS,GACV;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,SAAS,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAmCxD;AAunCD,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAa5C,eAAO,MAAM,mBAAmB,cACxB,MAAM,KAAK,IAAI,QACf,MAAM,KAAK,IAAI,CAGrB,CAAC;AAEH,wBAAgB,UAAU,CAAC,MAAM,GAAE,YAAiB,GAAG,SAAS,CAQ/D"}
|