@prosekit/extensions 0.5.2 → 0.5.3
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/dist/_tsup-dts-rollup.d.ts +173 -0
- package/dist/{chunk-DZAKXWWF.js → chunk-2JYT2MT7.js} +21 -41
- package/dist/{chunk-LVMTQOWG.js → chunk-PYT3MOTF.js} +14 -31
- package/dist/chunk-ZPEMHYTU.js +140 -0
- package/dist/list/style.css +4 -8
- package/dist/placeholder/style.css +1 -1
- package/dist/prosekit-extensions-autocomplete.js +33 -62
- package/dist/prosekit-extensions-blockquote.js +2 -2
- package/dist/prosekit-extensions-bold.js +3 -7
- package/dist/prosekit-extensions-code-block.js +37 -77
- package/dist/prosekit-extensions-code.js +1 -1
- package/dist/prosekit-extensions-enter-rule.js +1 -1
- package/dist/prosekit-extensions-heading.js +6 -13
- package/dist/prosekit-extensions-image.js +5 -14
- package/dist/prosekit-extensions-input-rule.js +1 -1
- package/dist/prosekit-extensions-italic.js +1 -1
- package/dist/prosekit-extensions-link.js +16 -31
- package/dist/prosekit-extensions-list.js +2 -4
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-mention.js +4 -6
- package/dist/prosekit-extensions-placeholder.js +9 -20
- package/dist/prosekit-extensions-readonly.js +1 -1
- package/dist/prosekit-extensions-search.d.ts +3 -0
- package/dist/prosekit-extensions-search.js +382 -0
- package/dist/prosekit-extensions-strike.js +1 -1
- package/dist/prosekit-extensions-table.js +30 -68
- package/dist/prosekit-extensions-text-align.js +2 -4
- package/dist/prosekit-extensions-virtual-selection.js +6 -12
- package/dist/search/style.css +13 -0
- package/package.json +16 -5
- package/dist/chunk-ZOBSD7ZH.js +0 -189
@@ -8,18 +8,18 @@ import {
|
|
8
8
|
function defineMentionSpec() {
|
9
9
|
return defineNodeSpec({
|
10
10
|
name: "mention",
|
11
|
-
atom:
|
11
|
+
atom: !0,
|
12
12
|
group: "inline",
|
13
13
|
attrs: {
|
14
14
|
id: {},
|
15
15
|
value: {},
|
16
16
|
kind: { default: "" }
|
17
17
|
},
|
18
|
-
inline:
|
18
|
+
inline: !0,
|
19
19
|
leafText: (node) => node.attrs.value.toString(),
|
20
20
|
parseDOM: [
|
21
21
|
{
|
22
|
-
tag:
|
22
|
+
tag: "span[data-mention]",
|
23
23
|
getAttrs: (dom) => ({
|
24
24
|
id: dom.getAttribute("data-id") || "",
|
25
25
|
kind: dom.getAttribute("data-mention") || "",
|
@@ -41,9 +41,7 @@ function defineMentionSpec() {
|
|
41
41
|
}
|
42
42
|
function defineMentionCommands() {
|
43
43
|
return defineCommands({
|
44
|
-
insertMention: (attrs) => {
|
45
|
-
return insertNode({ type: "mention", attrs });
|
46
|
-
}
|
44
|
+
insertMention: (attrs) => insertNode({ type: "mention", attrs })
|
47
45
|
});
|
48
46
|
}
|
49
47
|
function defineMention() {
|
@@ -11,35 +11,24 @@ function createPlaceholderPlugin(options) {
|
|
11
11
|
key: new PluginKey("prosekit-placeholder"),
|
12
12
|
props: {
|
13
13
|
decorations: (state) => {
|
14
|
-
if (options.strategy === "doc" && !isDocEmpty(state.doc))
|
14
|
+
if (options.strategy === "doc" && !isDocEmpty(state.doc) || isInCodeBlock(state.selection))
|
15
15
|
return null;
|
16
|
-
|
17
|
-
|
18
|
-
return null;
|
19
|
-
}
|
20
|
-
const placeholderText = options.placeholder;
|
21
|
-
const deco = createPlaceholderDecoration(state, placeholderText);
|
22
|
-
if (!deco) {
|
23
|
-
return null;
|
24
|
-
}
|
25
|
-
return DecorationSet.create(state.doc, [deco]);
|
16
|
+
let placeholderText = options.placeholder, deco = createPlaceholderDecoration(state, placeholderText);
|
17
|
+
return deco ? DecorationSet.create(state.doc, [deco]) : null;
|
26
18
|
}
|
27
19
|
}
|
28
20
|
});
|
29
21
|
}
|
30
22
|
function isDocEmpty(doc) {
|
31
23
|
var _a;
|
32
|
-
return doc.childCount <= 1 && !((_a = doc.firstChild)
|
24
|
+
return doc.childCount <= 1 && !((_a = doc.firstChild) != null && _a.content.size);
|
33
25
|
}
|
34
26
|
function createPlaceholderDecoration(state, placeholderText) {
|
35
|
-
|
36
|
-
if (!selection.empty)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if (node.content.size > 0)
|
41
|
-
return null;
|
42
|
-
const before = $pos.before();
|
27
|
+
let { selection } = state;
|
28
|
+
if (!selection.empty) return null;
|
29
|
+
let $pos = selection.$anchor, node = $pos.parent;
|
30
|
+
if (node.content.size > 0) return null;
|
31
|
+
let before = $pos.before();
|
43
32
|
return Decoration.node(before, before + node.nodeSize, {
|
44
33
|
class: "prosekit-placeholder",
|
45
34
|
"data-placeholder": placeholderText
|
@@ -0,0 +1,382 @@
|
|
1
|
+
// src/search/index.ts
|
2
|
+
import { defineCommands, definePlugin } from "@prosekit/core";
|
3
|
+
|
4
|
+
// src/search/prosemirror-search/search.ts
|
5
|
+
import {
|
6
|
+
Plugin,
|
7
|
+
PluginKey,
|
8
|
+
TextSelection
|
9
|
+
} from "@prosekit/pm/state";
|
10
|
+
import { DecorationSet, Decoration } from "@prosekit/pm/view";
|
11
|
+
|
12
|
+
// src/search/prosemirror-search/query.ts
|
13
|
+
import { Slice, Fragment } from "@prosekit/pm/model";
|
14
|
+
import "@prosekit/pm/state";
|
15
|
+
var SearchQuery = class {
|
16
|
+
/// Create a query object.
|
17
|
+
constructor(config) {
|
18
|
+
this.search = config.search, this.caseSensitive = !!config.caseSensitive, this.literal = !!config.literal, this.regexp = !!config.regexp, this.replace = config.replace || "", this.valid = !!this.search && !(this.regexp && !validRegExp(this.search)), this.wholeWord = !!config.wholeWord, this.impl = this.valid ? this.regexp ? new RegExpQuery(this) : new StringQuery(this) : nullQuery;
|
19
|
+
}
|
20
|
+
/// Compare this query to another query.
|
21
|
+
eq(other) {
|
22
|
+
return this.search == other.search && this.replace == other.replace && this.caseSensitive == other.caseSensitive && this.regexp == other.regexp && this.wholeWord == other.wholeWord;
|
23
|
+
}
|
24
|
+
/// Find the next occurrence of this query in the given range.
|
25
|
+
findNext(state, from = 0, to = state.doc.content.size) {
|
26
|
+
for (; ; ) {
|
27
|
+
if (from >= to) return null;
|
28
|
+
let result = this.impl.findNext(state, from, to);
|
29
|
+
if (!result || this.checkResult(state, result)) return result;
|
30
|
+
from = result.from + 1;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
/// Find the previous occurrence of this query in the given range.
|
34
|
+
/// Note that, if `to` is given, it should be _less_ than `from`.
|
35
|
+
findPrev(state, from = state.doc.content.size, to = 0) {
|
36
|
+
for (; ; ) {
|
37
|
+
if (from <= to) return null;
|
38
|
+
let result = this.impl.findPrev(state, from, to);
|
39
|
+
if (!result || this.checkResult(state, result)) return result;
|
40
|
+
from = result.to - 1;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
/// @internal
|
44
|
+
checkResult(state, result) {
|
45
|
+
return this.wholeWord ? checkWordBoundary(state, result.from) && checkWordBoundary(state, result.to) : !0;
|
46
|
+
}
|
47
|
+
/// @internal
|
48
|
+
unquote(string) {
|
49
|
+
return this.literal ? string : string.replace(
|
50
|
+
/\\([\\nrt])/g,
|
51
|
+
(_, ch) => ch == "n" ? `
|
52
|
+
` : ch == "r" ? "\r" : ch == "t" ? " " : "\\"
|
53
|
+
);
|
54
|
+
}
|
55
|
+
/// Get a replacement slice for a given search result.
|
56
|
+
getReplacement(state, result) {
|
57
|
+
let marks = state.doc.resolve(result.from).marksAcross(state.doc.resolve(result.to)), text = this.unquote(this.replace), nodes = [], i = 0, { match } = result;
|
58
|
+
if (match) {
|
59
|
+
text = text.replace(
|
60
|
+
/\$([\d$&+])/g,
|
61
|
+
(m, i2) => i2 == "$" ? "$" : i2 == "&" ? match[0] : i2 != "0" && +i2 < match.length ? match[+i2] : m
|
62
|
+
);
|
63
|
+
for (let pos = result.from; ; ) {
|
64
|
+
let obj = text.indexOf("\uFFFC", i);
|
65
|
+
if (obj < 0) break;
|
66
|
+
let found = findLeafBetween(state, pos, result.to);
|
67
|
+
if (!found) break;
|
68
|
+
obj > i && nodes.push(state.schema.text(text.slice(i, obj), marks)), nodes.push(found.node), i = obj + 1, pos = found.pos + 1;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
return i < text.length && nodes.push(state.schema.text(text.slice(i), marks)), new Slice(Fragment.from(nodes), 0, 0);
|
72
|
+
}
|
73
|
+
}, nullQuery = new class {
|
74
|
+
findNext() {
|
75
|
+
return null;
|
76
|
+
}
|
77
|
+
findPrev() {
|
78
|
+
return null;
|
79
|
+
}
|
80
|
+
}(), StringQuery = class {
|
81
|
+
constructor(query) {
|
82
|
+
this.query = query;
|
83
|
+
let string = query.unquote(query.search);
|
84
|
+
query.caseSensitive || (string = string.toLowerCase()), this.string = string;
|
85
|
+
}
|
86
|
+
findNext(state, from, to) {
|
87
|
+
return scanTextblocks(state.doc, from, to, (node, start) => {
|
88
|
+
let off = Math.max(from, start), content = textContent(node).slice(
|
89
|
+
off - start,
|
90
|
+
Math.min(node.content.size, to - start)
|
91
|
+
), index = (this.query.caseSensitive ? content : content.toLowerCase()).indexOf(this.string);
|
92
|
+
return index < 0 ? null : {
|
93
|
+
from: off + index,
|
94
|
+
to: off + index + this.string.length,
|
95
|
+
match: null
|
96
|
+
};
|
97
|
+
});
|
98
|
+
}
|
99
|
+
findPrev(state, from, to) {
|
100
|
+
return scanTextblocks(state.doc, from, to, (node, start) => {
|
101
|
+
let off = Math.max(start, to), content = textContent(node).slice(
|
102
|
+
off - start,
|
103
|
+
Math.min(node.content.size, from - start)
|
104
|
+
);
|
105
|
+
this.query.caseSensitive || (content = content.toLowerCase());
|
106
|
+
let index = content.lastIndexOf(this.string);
|
107
|
+
return index < 0 ? null : {
|
108
|
+
from: off + index,
|
109
|
+
to: off + index + this.string.length,
|
110
|
+
match: null
|
111
|
+
};
|
112
|
+
});
|
113
|
+
}
|
114
|
+
}, baseFlags = "g" + (/x/.unicode == null ? "" : "u"), RegExpQuery = class {
|
115
|
+
constructor(query) {
|
116
|
+
this.query = query;
|
117
|
+
this.regexp = new RegExp(
|
118
|
+
query.search,
|
119
|
+
baseFlags + (query.caseSensitive ? "" : "i")
|
120
|
+
);
|
121
|
+
}
|
122
|
+
findNext(state, from, to) {
|
123
|
+
return scanTextblocks(state.doc, from, to, (node, start) => {
|
124
|
+
let content = textContent(node).slice(
|
125
|
+
0,
|
126
|
+
Math.min(node.content.size, to - start)
|
127
|
+
);
|
128
|
+
this.regexp.lastIndex = from - start;
|
129
|
+
let match = this.regexp.exec(content);
|
130
|
+
return match ? {
|
131
|
+
from: start + match.index,
|
132
|
+
to: start + match.index + match[0].length,
|
133
|
+
match
|
134
|
+
} : null;
|
135
|
+
});
|
136
|
+
}
|
137
|
+
findPrev(state, from, to) {
|
138
|
+
return scanTextblocks(state.doc, from, to, (node, start) => {
|
139
|
+
let content = textContent(node).slice(
|
140
|
+
0,
|
141
|
+
Math.min(node.content.size, from - start)
|
142
|
+
), match;
|
143
|
+
for (let off = 0; ; ) {
|
144
|
+
this.regexp.lastIndex = off;
|
145
|
+
let next = this.regexp.exec(content);
|
146
|
+
if (!next) break;
|
147
|
+
match = next, off = next.index + 1;
|
148
|
+
}
|
149
|
+
return match ? {
|
150
|
+
from: start + match.index,
|
151
|
+
to: start + match.index + match[0].length,
|
152
|
+
match
|
153
|
+
} : null;
|
154
|
+
});
|
155
|
+
}
|
156
|
+
};
|
157
|
+
function validRegExp(source) {
|
158
|
+
try {
|
159
|
+
return new RegExp(source, baseFlags), !0;
|
160
|
+
} catch (e) {
|
161
|
+
return !1;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
var TextContentCache = /* @__PURE__ */ new WeakMap();
|
165
|
+
function textContent(node) {
|
166
|
+
let cached = TextContentCache.get(node);
|
167
|
+
if (cached) return cached;
|
168
|
+
let content = "";
|
169
|
+
for (let i = 0; i < node.childCount; i++) {
|
170
|
+
let child = node.child(i);
|
171
|
+
child.isText ? content += child.text : child.isLeaf ? content += "\uFFFC" : content += " " + textContent(child) + " ";
|
172
|
+
}
|
173
|
+
return TextContentCache.set(node, content), content;
|
174
|
+
}
|
175
|
+
function scanTextblocks(node, from, to, f, nodeStart = 0) {
|
176
|
+
if (node.inlineContent)
|
177
|
+
return f(node, nodeStart);
|
178
|
+
if (!node.isLeaf)
|
179
|
+
if (from > to)
|
180
|
+
for (let i = node.childCount - 1, pos = nodeStart + node.content.size; i >= 0 && pos > to; i--) {
|
181
|
+
let child = node.child(i);
|
182
|
+
if (pos -= child.nodeSize, pos < from) {
|
183
|
+
let result = scanTextblocks(child, from, to, f, pos + 1);
|
184
|
+
if (result != null) return result;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
else
|
188
|
+
for (let i = 0, pos = nodeStart; i < node.childCount && pos < to; i++) {
|
189
|
+
let child = node.child(i), start = pos;
|
190
|
+
if (pos += child.nodeSize, pos > from) {
|
191
|
+
let result = scanTextblocks(child, from, to, f, start + 1);
|
192
|
+
if (result != null) return result;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
return null;
|
196
|
+
}
|
197
|
+
function checkWordBoundary(state, pos) {
|
198
|
+
let $pos = state.doc.resolve(pos), before = $pos.nodeBefore, after = $pos.nodeAfter;
|
199
|
+
return !before || !after || !before.isText || !after.isText ? !0 : !/\p{L}$/u.test(before.text) || !/^\p{L}/u.test(after.text);
|
200
|
+
}
|
201
|
+
function findLeafBetween(state, from, to) {
|
202
|
+
let found = null;
|
203
|
+
return state.doc.nodesBetween(from, to, (node, pos) => {
|
204
|
+
if (found) return !1;
|
205
|
+
node.isLeaf && node.isInline && !node.isText && (found = { node, pos });
|
206
|
+
}), found;
|
207
|
+
}
|
208
|
+
|
209
|
+
// src/search/prosemirror-search/search.ts
|
210
|
+
var SearchState = class {
|
211
|
+
constructor(query, range, deco) {
|
212
|
+
this.query = query;
|
213
|
+
this.range = range;
|
214
|
+
this.deco = deco;
|
215
|
+
}
|
216
|
+
};
|
217
|
+
function buildMatchDeco(state, query, range) {
|
218
|
+
if (!query.valid) return DecorationSet.empty;
|
219
|
+
let deco = [], sel = state.selection;
|
220
|
+
for (let pos = range ? range.from : 0, end = range ? range.to : state.doc.content.size; ; ) {
|
221
|
+
let next = query.findNext(state, pos, end);
|
222
|
+
if (!next) break;
|
223
|
+
let cls = next.from == sel.from && next.to == sel.to ? "ProseMirror-active-search-match" : "ProseMirror-search-match";
|
224
|
+
deco.push(Decoration.inline(next.from, next.to, { class: cls })), pos = next.to;
|
225
|
+
}
|
226
|
+
return DecorationSet.create(state.doc, deco);
|
227
|
+
}
|
228
|
+
var searchKey = new PluginKey("search");
|
229
|
+
function search(options = {}) {
|
230
|
+
return new Plugin({
|
231
|
+
key: searchKey,
|
232
|
+
state: {
|
233
|
+
init(_config, state) {
|
234
|
+
let query = options.initialQuery || new SearchQuery({ search: "" }), range = options.initialRange || null;
|
235
|
+
return new SearchState(
|
236
|
+
query,
|
237
|
+
range,
|
238
|
+
buildMatchDeco(state, query, range)
|
239
|
+
);
|
240
|
+
},
|
241
|
+
apply(tr, search2, _oldState, state) {
|
242
|
+
let set = tr.getMeta(searchKey);
|
243
|
+
if (set)
|
244
|
+
return new SearchState(
|
245
|
+
set.query,
|
246
|
+
set.range,
|
247
|
+
buildMatchDeco(state, set.query, set.range)
|
248
|
+
);
|
249
|
+
if (tr.docChanged || tr.selectionSet) {
|
250
|
+
let range = search2.range;
|
251
|
+
if (range) {
|
252
|
+
let from = tr.mapping.map(range.from, 1), to = tr.mapping.map(range.to, -1);
|
253
|
+
range = from < to ? { from, to } : null;
|
254
|
+
}
|
255
|
+
search2 = new SearchState(
|
256
|
+
search2.query,
|
257
|
+
range,
|
258
|
+
buildMatchDeco(state, search2.query, range)
|
259
|
+
);
|
260
|
+
}
|
261
|
+
return search2;
|
262
|
+
}
|
263
|
+
},
|
264
|
+
props: {
|
265
|
+
decorations: (state) => searchKey.getState(state).deco
|
266
|
+
}
|
267
|
+
});
|
268
|
+
}
|
269
|
+
function nextMatch(search2, state, wrap, curFrom, curTo) {
|
270
|
+
let range = search2.range || { from: 0, to: state.doc.content.size }, next = search2.query.findNext(state, Math.max(curTo, range.from), range.to);
|
271
|
+
return !next && wrap && (next = search2.query.findNext(state, range.from, Math.min(curFrom, range.to))), next;
|
272
|
+
}
|
273
|
+
function prevMatch(search2, state, wrap, curFrom, curTo) {
|
274
|
+
let range = search2.range || { from: 0, to: state.doc.content.size }, prev = search2.query.findPrev(
|
275
|
+
state,
|
276
|
+
Math.min(curFrom, range.to),
|
277
|
+
range.from
|
278
|
+
);
|
279
|
+
return !prev && wrap && (prev = search2.query.findPrev(state, range.to, Math.max(curTo, range.from))), prev;
|
280
|
+
}
|
281
|
+
function findCommand(wrap, dir) {
|
282
|
+
return (state, dispatch) => {
|
283
|
+
let search2 = searchKey.getState(state);
|
284
|
+
if (!search2 || !search2.query.valid) return !1;
|
285
|
+
let { from, to } = state.selection, next = dir > 0 ? nextMatch(search2, state, wrap, from, to) : prevMatch(search2, state, wrap, from, to);
|
286
|
+
if (!next) return !1;
|
287
|
+
let selection = TextSelection.create(state.doc, next.from, next.to);
|
288
|
+
return dispatch && dispatch(state.tr.setSelection(selection).scrollIntoView()), !0;
|
289
|
+
};
|
290
|
+
}
|
291
|
+
var findNext = findCommand(!0, 1), findNextNoWrap = findCommand(!1, 1), findPrev = findCommand(!0, -1), findPrevNoWrap = findCommand(!1, -1);
|
292
|
+
function replaceCommand(wrap, moveForward) {
|
293
|
+
return (state, dispatch) => {
|
294
|
+
let search2 = searchKey.getState(state);
|
295
|
+
if (!search2 || !search2.query.valid) return !1;
|
296
|
+
let { from } = state.selection, next = nextMatch(search2, state, wrap, from, from);
|
297
|
+
if (!next) return !1;
|
298
|
+
if (!dispatch) return !0;
|
299
|
+
if (state.selection.from == next.from && state.selection.to == next.to) {
|
300
|
+
let tr = state.tr.replace(
|
301
|
+
next.from,
|
302
|
+
next.to,
|
303
|
+
search2.query.getReplacement(state, next)
|
304
|
+
), after = moveForward && nextMatch(search2, state, wrap, next.from, next.to);
|
305
|
+
after ? tr.setSelection(
|
306
|
+
TextSelection.create(
|
307
|
+
tr.doc,
|
308
|
+
tr.mapping.map(after.from, 1),
|
309
|
+
tr.mapping.map(after.to, -1)
|
310
|
+
)
|
311
|
+
) : tr.setSelection(
|
312
|
+
TextSelection.create(tr.doc, next.from, tr.mapping.map(next.to, 1))
|
313
|
+
), dispatch(tr.scrollIntoView());
|
314
|
+
} else if (moveForward)
|
315
|
+
dispatch(
|
316
|
+
state.tr.setSelection(TextSelection.create(state.doc, next.from, next.to)).scrollIntoView()
|
317
|
+
);
|
318
|
+
else
|
319
|
+
return !1;
|
320
|
+
return !0;
|
321
|
+
};
|
322
|
+
}
|
323
|
+
var replaceNext = replaceCommand(!0, !0), replaceNextNoWrap = replaceCommand(!1, !0), replaceCurrent = replaceCommand(!1, !1), replaceAll = (state, dispatch) => {
|
324
|
+
let search2 = searchKey.getState(state);
|
325
|
+
if (!search2) return !1;
|
326
|
+
let matches = [], range = search2.range || { from: 0, to: state.doc.content.size };
|
327
|
+
for (let pos = range.from; ; ) {
|
328
|
+
let next = search2.query.findNext(state, pos, range.to);
|
329
|
+
if (!next) break;
|
330
|
+
matches.push(next), pos = next.to;
|
331
|
+
}
|
332
|
+
if (dispatch) {
|
333
|
+
let tr = state.tr;
|
334
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
335
|
+
let match = matches[i];
|
336
|
+
tr.replace(
|
337
|
+
match.from,
|
338
|
+
match.to,
|
339
|
+
search2.query.getReplacement(state, match)
|
340
|
+
);
|
341
|
+
}
|
342
|
+
dispatch(tr);
|
343
|
+
}
|
344
|
+
return !0;
|
345
|
+
};
|
346
|
+
|
347
|
+
// src/search/index.ts
|
348
|
+
function defineSearchQuery(options) {
|
349
|
+
let query = new SearchQuery(options);
|
350
|
+
return definePlugin(search({ initialQuery: query }));
|
351
|
+
}
|
352
|
+
function scrollActiveIntoView(view) {
|
353
|
+
if (view.isDestroyed) return;
|
354
|
+
let active = view.dom.querySelector(".ProseMirror-active-search-match");
|
355
|
+
active == null || active.scrollIntoView({
|
356
|
+
block: "nearest",
|
357
|
+
inline: "nearest",
|
358
|
+
behavior: "smooth"
|
359
|
+
});
|
360
|
+
}
|
361
|
+
function withScrollActiveIntoView(command) {
|
362
|
+
return (state, dispatch, view) => {
|
363
|
+
let result = command(state, dispatch, view);
|
364
|
+
return result && dispatch && view && setTimeout(() => scrollActiveIntoView(view), 50), result;
|
365
|
+
};
|
366
|
+
}
|
367
|
+
function defineSearchCommands() {
|
368
|
+
return defineCommands({
|
369
|
+
findNext: () => withScrollActiveIntoView(findNext),
|
370
|
+
findPrev: () => withScrollActiveIntoView(findPrev),
|
371
|
+
findNextNoWrap: () => withScrollActiveIntoView(findNextNoWrap),
|
372
|
+
findPrevNoWrap: () => withScrollActiveIntoView(findPrevNoWrap),
|
373
|
+
replaceNext: () => withScrollActiveIntoView(replaceNext),
|
374
|
+
replaceNextNoWrap: () => withScrollActiveIntoView(replaceNextNoWrap),
|
375
|
+
replaceCurrent: () => withScrollActiveIntoView(replaceCurrent),
|
376
|
+
replaceAll: () => withScrollActiveIntoView(replaceAll)
|
377
|
+
});
|
378
|
+
}
|
379
|
+
export {
|
380
|
+
defineSearchCommands,
|
381
|
+
defineSearchQuery
|
382
|
+
};
|
@@ -10,23 +10,13 @@ import {
|
|
10
10
|
} from "@prosekit/core";
|
11
11
|
import { TextSelection } from "@prosekit/pm/state";
|
12
12
|
function createEmptyTable(schema, row, col, header) {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
Array.from({ length: col }, () => tableHeaderCell.createAndFill())
|
21
|
-
);
|
22
|
-
};
|
23
|
-
const createBodyRow = () => {
|
24
|
-
return tableRow.createAndFill(
|
25
|
-
null,
|
26
|
-
Array.from({ length: col }, () => tableCell.createAndFill())
|
27
|
-
);
|
28
|
-
};
|
29
|
-
const rows = [
|
13
|
+
let table = getNodeType(schema, "table"), tableRow = getNodeType(schema, "tableRow"), tableCell = getNodeType(schema, "tableCell"), tableHeaderCell = getNodeType(schema, "tableHeaderCell"), createHeaderRow = () => tableRow.createAndFill(
|
14
|
+
null,
|
15
|
+
Array.from({ length: col }, () => tableHeaderCell.createAndFill())
|
16
|
+
), createBodyRow = () => tableRow.createAndFill(
|
17
|
+
null,
|
18
|
+
Array.from({ length: col }, () => tableCell.createAndFill())
|
19
|
+
), rows = [
|
30
20
|
...Array.from({ length: header ? 1 : 0 }, createHeaderRow),
|
31
21
|
...Array.from({ length: header ? row - 1 : row }, createBodyRow)
|
32
22
|
];
|
@@ -38,41 +28,27 @@ function insertTable({
|
|
38
28
|
header
|
39
29
|
}) {
|
40
30
|
return (state, dispatch, view) => {
|
41
|
-
|
31
|
+
let table = createEmptyTable(state.schema, row, col, header);
|
42
32
|
return insertNode({ node: table })(state, dispatch, view);
|
43
33
|
};
|
44
34
|
}
|
45
35
|
var exitTable = (state, dispatch) => {
|
46
|
-
|
47
|
-
if (!$head.sameParent($anchor))
|
48
|
-
return
|
49
|
-
|
50
|
-
let
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
}
|
58
|
-
}
|
59
|
-
if (tableStart < 0 || tableDepth <= 0) {
|
60
|
-
return false;
|
61
|
-
}
|
62
|
-
const above = $head.node(tableDepth - 1);
|
63
|
-
const after = $head.indexAfter(tableDepth - 1);
|
64
|
-
const type = defaultBlockAt(above.contentMatchAt(after));
|
65
|
-
const node = type == null ? void 0 : type.createAndFill();
|
66
|
-
if (!type || !node || !above.canReplaceWith(after, after, type)) {
|
67
|
-
return false;
|
68
|
-
}
|
36
|
+
let { $head, $anchor } = state.selection;
|
37
|
+
if (!$head.sameParent($anchor))
|
38
|
+
return !1;
|
39
|
+
let tableStart = -1, tableDepth = -1;
|
40
|
+
for (let depth = $head.depth; depth >= 0; depth--)
|
41
|
+
$head.node(depth).type.spec.tableRole === "table" && (tableStart = $head.before(depth), tableDepth = depth);
|
42
|
+
if (tableStart < 0 || tableDepth <= 0)
|
43
|
+
return !1;
|
44
|
+
let above = $head.node(tableDepth - 1), after = $head.indexAfter(tableDepth - 1), type = defaultBlockAt(above.contentMatchAt(after)), node = type == null ? void 0 : type.createAndFill();
|
45
|
+
if (!type || !node || !above.canReplaceWith(after, after, type))
|
46
|
+
return !1;
|
69
47
|
if (dispatch) {
|
70
|
-
|
71
|
-
|
72
|
-
tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1));
|
73
|
-
dispatch(tr.scrollIntoView());
|
48
|
+
let pos = $head.after(tableDepth), tr = state.tr.replaceWith(pos, pos, node);
|
49
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1)), dispatch(tr.scrollIntoView());
|
74
50
|
}
|
75
|
-
return
|
51
|
+
return !0;
|
76
52
|
};
|
77
53
|
function defineTableCommands() {
|
78
54
|
return defineCommands({
|
@@ -95,15 +71,11 @@ var cellAttrs = {
|
|
95
71
|
colspan: { default: 1 },
|
96
72
|
rowspan: { default: 1 },
|
97
73
|
colwidth: { default: null }
|
98
|
-
};
|
99
|
-
var cellContent = "block+";
|
74
|
+
}, cellContent = "block+";
|
100
75
|
function getCellAttrs(dom) {
|
101
|
-
if (typeof dom
|
76
|
+
if (typeof dom == "string")
|
102
77
|
return {};
|
103
|
-
|
104
|
-
const widthAttr = dom.getAttribute("data-colwidth");
|
105
|
-
const widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null;
|
106
|
-
const colspan = Number(dom.getAttribute("colspan") || 1);
|
78
|
+
let widthAttr = dom.getAttribute("data-colwidth"), widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null, colspan = Number(dom.getAttribute("colspan") || 1);
|
107
79
|
return {
|
108
80
|
colspan,
|
109
81
|
rowspan: Number(dom.getAttribute("rowspan") || 1),
|
@@ -111,25 +83,15 @@ function getCellAttrs(dom) {
|
|
111
83
|
};
|
112
84
|
}
|
113
85
|
function setCellAttrs(node) {
|
114
|
-
|
115
|
-
|
116
|
-
if (pmAttrs.colspan !== 1) {
|
117
|
-
domAttrs.colspan = pmAttrs.colspan;
|
118
|
-
}
|
119
|
-
if (pmAttrs.rowspan !== 1) {
|
120
|
-
domAttrs.rowspan = pmAttrs.rowspan;
|
121
|
-
}
|
122
|
-
if (pmAttrs.colwidth) {
|
123
|
-
domAttrs["data-colwidth"] = pmAttrs.colwidth.join(",");
|
124
|
-
}
|
125
|
-
return domAttrs;
|
86
|
+
let pmAttrs = node.attrs, domAttrs = {};
|
87
|
+
return pmAttrs.colspan !== 1 && (domAttrs.colspan = pmAttrs.colspan), pmAttrs.rowspan !== 1 && (domAttrs.rowspan = pmAttrs.rowspan), pmAttrs.colwidth && (domAttrs["data-colwidth"] = pmAttrs.colwidth.join(",")), domAttrs;
|
126
88
|
}
|
127
89
|
function defineTableSpec() {
|
128
90
|
return defineNodeSpec({
|
129
91
|
name: "table",
|
130
92
|
tableRole: "table",
|
131
93
|
content: "tableRow+",
|
132
|
-
isolating:
|
94
|
+
isolating: !0,
|
133
95
|
group: "block",
|
134
96
|
parseDOM: [{ tag: "table" }],
|
135
97
|
toDOM() {
|
@@ -154,7 +116,7 @@ function defineTableCellSpec() {
|
|
154
116
|
tableRole: "cell",
|
155
117
|
content: cellContent,
|
156
118
|
attrs: cellAttrs,
|
157
|
-
isolating:
|
119
|
+
isolating: !0,
|
158
120
|
parseDOM: [{ tag: "td", getAttrs: (dom) => getCellAttrs(dom) }],
|
159
121
|
toDOM(node) {
|
160
122
|
return ["td", setCellAttrs(node), 0];
|
@@ -167,7 +129,7 @@ function defineTableHeaderCellSpec() {
|
|
167
129
|
tableRole: "header_cell",
|
168
130
|
content: cellContent,
|
169
131
|
attrs: cellAttrs,
|
170
|
-
isolating:
|
132
|
+
isolating: !0,
|
171
133
|
parseDOM: [{ tag: "th", getAttrs: (dom) => getCellAttrs(dom) }],
|
172
134
|
toDOM(node) {
|
173
135
|
return ["th", setCellAttrs(node), 0];
|
@@ -11,11 +11,9 @@ function defineTextAlignAttr(type, defaultValue) {
|
|
11
11
|
type,
|
12
12
|
attr: "textAlign",
|
13
13
|
default: defaultValue,
|
14
|
-
splittable:
|
14
|
+
splittable: !0,
|
15
15
|
toDOM: (value) => value ? ["style", `text-align:${value};`] : null,
|
16
|
-
parseDOM: (node) =>
|
17
|
-
return node.style.getPropertyValue("text-align") || null;
|
18
|
-
}
|
16
|
+
parseDOM: (node) => node.style.getPropertyValue("text-align") || null
|
19
17
|
});
|
20
18
|
}
|
21
19
|
function defineTextAlignAttrs(types, defaultValue) {
|