@prosekit/extensions 0.4.2 → 0.4.4
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 +63 -2
- package/dist/chunk-MX6UNVWH.js +187 -0
- package/dist/list/style.css +1 -1
- package/dist/prosekit-extensions-code-block.js +3 -3
- package/dist/prosekit-extensions-link.d.ts +1 -0
- package/dist/prosekit-extensions-link.js +25 -10
- package/dist/prosekit-extensions-mark-rule.d.ts +2 -0
- package/dist/prosekit-extensions-mark-rule.js +6 -0
- package/package.json +14 -6
@@ -16,6 +16,7 @@ import { IndentListOptions } from 'prosemirror-flat-list';
|
|
16
16
|
import { InputRule } from '@prosekit/pm/inputrules';
|
17
17
|
import { ListAttributes } from 'prosemirror-flat-list';
|
18
18
|
import { ListDOMSerializer } from 'prosemirror-flat-list';
|
19
|
+
import { MarkType } from '@prosekit/pm/model';
|
19
20
|
import { NodeRange } from 'prosemirror-model';
|
20
21
|
import { NodeType } from '@prosekit/pm/model';
|
21
22
|
import { Options } from 'tsup';
|
@@ -28,6 +29,8 @@ import { ToggleCollapsedOptions } from 'prosemirror-flat-list';
|
|
28
29
|
import { Transaction } from '@prosekit/pm/state';
|
29
30
|
import { UnwrapListOptions } from 'prosemirror-flat-list';
|
30
31
|
|
32
|
+
export declare function applyMarkRules(rules: MarkRule[], transactions: readonly Transaction[], oldState: EditorState, newState: EditorState): Transaction | null;
|
33
|
+
|
31
34
|
declare class AutocompleteRule {
|
32
35
|
readonly regex: RegExp;
|
33
36
|
readonly onMatch: MatchHandler;
|
@@ -412,10 +415,21 @@ expandLink: [];
|
|
412
415
|
};
|
413
416
|
}>;
|
414
417
|
|
418
|
+
/**
|
419
|
+
* Apply link marks after typing Enter.
|
420
|
+
*/
|
415
421
|
export declare function defineLinkEnterRule(): Extension<ExtensionTyping<string, string, CommandArgs>>;
|
416
422
|
|
423
|
+
/**
|
424
|
+
* Apply link marks after pressing Space.
|
425
|
+
*/
|
417
426
|
export declare function defineLinkInputRule(): Extension<ExtensionTyping<string, string, CommandArgs>>;
|
418
427
|
|
428
|
+
/**
|
429
|
+
* Apply and remove link marks to the text during typing.
|
430
|
+
*/
|
431
|
+
export declare function defineLinkMarkRule(): Extension<ExtensionTyping<string, string, CommandArgs>>;
|
432
|
+
|
419
433
|
export declare function defineLinkSpec(): Extension< {
|
420
434
|
MARKS: "link";
|
421
435
|
}>;
|
@@ -467,6 +481,14 @@ export declare function defineListSpec(): Extension<{
|
|
467
481
|
NODES: "list";
|
468
482
|
}>;
|
469
483
|
|
484
|
+
/**
|
485
|
+
* A mark rule is something that can automatically apply marks to text if it
|
486
|
+
* matches a certain pattern, and remove them if it doesn't match anymore.
|
487
|
+
*/
|
488
|
+
declare function defineMarkRule(options: MarkRuleOptions): Extension<ExtensionTyping<string, string, CommandArgs>>;
|
489
|
+
export { defineMarkRule }
|
490
|
+
export { defineMarkRule as defineMarkRule_alias_1 }
|
491
|
+
|
470
492
|
/**
|
471
493
|
* @public
|
472
494
|
*/
|
@@ -758,6 +780,8 @@ export declare type EnterRuleOptions = {
|
|
758
780
|
*/
|
759
781
|
export declare const exitTable: Command;
|
760
782
|
|
783
|
+
export declare function getCheckRanges(transactions: readonly Transaction[], oldState: EditorState, newState: EditorState): Array<[number, number]>;
|
784
|
+
|
761
785
|
export { getHighlighter }
|
762
786
|
|
763
787
|
export declare function getPluginState(state: EditorState): PredictionPluginState | undefined;
|
@@ -799,9 +823,11 @@ export declare function insertTable({ row, col, header, }: {
|
|
799
823
|
header: boolean;
|
800
824
|
}): Command;
|
801
825
|
|
802
|
-
export declare const
|
826
|
+
export declare const LINK_ENTER_RE: RegExp;
|
803
827
|
|
804
|
-
export declare const
|
828
|
+
export declare const LINK_INPUT_RE: RegExp;
|
829
|
+
|
830
|
+
export declare const LINK_MARK_RE: RegExp;
|
805
831
|
|
806
832
|
/**
|
807
833
|
* @public
|
@@ -812,6 +838,41 @@ export declare interface LinkAttrs {
|
|
812
838
|
|
813
839
|
export { ListDOMSerializer }
|
814
840
|
|
841
|
+
/**
|
842
|
+
* @internal
|
843
|
+
*/
|
844
|
+
export declare interface MarkRule {
|
845
|
+
regex: RegExp;
|
846
|
+
type: string | MarkType;
|
847
|
+
getAttrs?: ((match: RegExpMatchArray) => Attrs | null) | null;
|
848
|
+
}
|
849
|
+
|
850
|
+
/**
|
851
|
+
* The options for {@link defineMarkRule}.
|
852
|
+
*
|
853
|
+
* @public
|
854
|
+
*/
|
855
|
+
declare interface MarkRuleOptions {
|
856
|
+
/**
|
857
|
+
* The regular expression to match against. It must has a `g` flag to match
|
858
|
+
* all instances of the mark.
|
859
|
+
*/
|
860
|
+
regex: RegExp;
|
861
|
+
/**
|
862
|
+
* The mark type to apply to the matched text.
|
863
|
+
*/
|
864
|
+
type: string | MarkType;
|
865
|
+
/**
|
866
|
+
* Attributes to set on the mark. If a function is provided, it will be called
|
867
|
+
* with the matched result from the regular expression.
|
868
|
+
*
|
869
|
+
* @default null
|
870
|
+
*/
|
871
|
+
attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null);
|
872
|
+
}
|
873
|
+
export { MarkRuleOptions }
|
874
|
+
export { MarkRuleOptions as MarkRuleOptions_alias_1 }
|
875
|
+
|
815
876
|
declare type MatchHandler = (options: {
|
816
877
|
state: EditorState;
|
817
878
|
match: RegExpExecArray;
|
@@ -0,0 +1,187 @@
|
|
1
|
+
// src/mark-rule/extension.ts
|
2
|
+
import { Facet, pluginFacet } from "@prosekit/core";
|
3
|
+
import { ProseMirrorPlugin } from "@prosekit/pm/state";
|
4
|
+
|
5
|
+
// src/mark-rule/apply.ts
|
6
|
+
import { OBJECT_REPLACEMENT_CHARACTER, getMarkType } from "@prosekit/core";
|
7
|
+
import "@prosekit/pm/model";
|
8
|
+
import "@prosekit/pm/state";
|
9
|
+
|
10
|
+
// src/mark-rule/range.ts
|
11
|
+
import "@prosekit/pm/state";
|
12
|
+
function getSpanTextRanges($from, $to) {
|
13
|
+
const nodeRange = $from.blockRange($to);
|
14
|
+
if (!nodeRange) {
|
15
|
+
return [];
|
16
|
+
}
|
17
|
+
const stack = [];
|
18
|
+
let start = nodeRange.start;
|
19
|
+
for (let i = nodeRange.startIndex; i < nodeRange.endIndex; i++) {
|
20
|
+
const child = nodeRange.parent.child(i);
|
21
|
+
stack.push([start, child]);
|
22
|
+
start += child.nodeSize;
|
23
|
+
}
|
24
|
+
const ranges = [];
|
25
|
+
while (stack.length > 0) {
|
26
|
+
const [start2, node] = stack.pop();
|
27
|
+
if (node.type.spec.code) {
|
28
|
+
continue;
|
29
|
+
}
|
30
|
+
if (node.type.isTextblock) {
|
31
|
+
ranges.push([start2 + 1, start2 + 1 + node.content.size]);
|
32
|
+
continue;
|
33
|
+
}
|
34
|
+
node.forEach((child, offset) => {
|
35
|
+
stack.push([start2 + offset + 1, child]);
|
36
|
+
});
|
37
|
+
}
|
38
|
+
return ranges;
|
39
|
+
}
|
40
|
+
function getInlineTextRange($from, $to) {
|
41
|
+
return [$from.start(), $to.end()];
|
42
|
+
}
|
43
|
+
function getTextRanges(doc, from, to) {
|
44
|
+
const $from = doc.resolve(from);
|
45
|
+
const $to = doc.resolve(to);
|
46
|
+
if ($from.sameParent($to) && $from.parent.isTextblock) {
|
47
|
+
return [getInlineTextRange($from, $to)];
|
48
|
+
} else {
|
49
|
+
const nodeRange = $from.blockRange($to);
|
50
|
+
if (!nodeRange) {
|
51
|
+
return [];
|
52
|
+
}
|
53
|
+
return getSpanTextRanges($from, $to);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
function getMapRange(transactions, oldState, newState) {
|
57
|
+
let lo = oldState.selection.from;
|
58
|
+
let hi = oldState.selection.to;
|
59
|
+
for (const tr of transactions) {
|
60
|
+
for (const map of tr.mapping.maps) {
|
61
|
+
lo = map.map(lo);
|
62
|
+
hi = map.map(hi);
|
63
|
+
map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
|
64
|
+
lo = Math.min(lo, hi, newStart);
|
65
|
+
hi = Math.max(lo, hi, newEnd);
|
66
|
+
});
|
67
|
+
}
|
68
|
+
}
|
69
|
+
lo = Math.min(lo, hi, newState.selection.from);
|
70
|
+
hi = Math.min(lo, hi, newState.selection.to);
|
71
|
+
return [lo, hi];
|
72
|
+
}
|
73
|
+
function getCheckRanges(transactions, oldState, newState) {
|
74
|
+
const [from, to] = getMapRange(transactions, oldState, newState);
|
75
|
+
return getTextRanges(newState.doc, from, to);
|
76
|
+
}
|
77
|
+
|
78
|
+
// src/mark-rule/apply.ts
|
79
|
+
function getExpectedMarkings(rules, doc, from, to) {
|
80
|
+
var _a;
|
81
|
+
const text = doc.textBetween(from, to, OBJECT_REPLACEMENT_CHARACTER);
|
82
|
+
const ranges = [];
|
83
|
+
for (const rule of rules) {
|
84
|
+
rule.regex.lastIndex = 0;
|
85
|
+
const matches = text.matchAll(rule.regex);
|
86
|
+
const markType = getMarkType(doc.type.schema, rule.type);
|
87
|
+
for (const match of matches) {
|
88
|
+
const index = match.index;
|
89
|
+
if (index == null)
|
90
|
+
continue;
|
91
|
+
const attrs = (_a = rule.getAttrs) == null ? void 0 : _a.call(rule, match);
|
92
|
+
const mark = markType.create(attrs);
|
93
|
+
ranges.push([from + index, from + index + match[0].length, mark]);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
ranges.sort((a, b) => a[0] - b[0] || b[1] - a[1]);
|
97
|
+
const result = [];
|
98
|
+
let freeIndex = 0;
|
99
|
+
for (const range of ranges) {
|
100
|
+
if (range[0] >= freeIndex) {
|
101
|
+
result.push(range);
|
102
|
+
freeIndex = range[1];
|
103
|
+
}
|
104
|
+
}
|
105
|
+
return result;
|
106
|
+
}
|
107
|
+
function getReceivedMarkings(rules, doc, from, to) {
|
108
|
+
const result = [];
|
109
|
+
const schema = doc.type.schema;
|
110
|
+
const markTypes = rules.map((rule) => getMarkType(schema, rule.type));
|
111
|
+
doc.nodesBetween(from, to, (node, pos) => {
|
112
|
+
if (!node.isInline) {
|
113
|
+
return;
|
114
|
+
}
|
115
|
+
for (const markType of markTypes) {
|
116
|
+
const mark = node.marks.find((mark2) => mark2.type === markType);
|
117
|
+
if (mark) {
|
118
|
+
result.push([pos, pos + node.nodeSize, mark]);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
});
|
122
|
+
return result;
|
123
|
+
}
|
124
|
+
function markRangeEquals(a, b) {
|
125
|
+
return a[0] === b[0] && a[1] === b[1] && a[2].eq(b[2]);
|
126
|
+
}
|
127
|
+
function markRangeDiffs(a, b) {
|
128
|
+
return a.filter((x) => !b.some((y) => markRangeEquals(x, y)));
|
129
|
+
}
|
130
|
+
function applyMarkRules(rules, transactions, oldState, newState) {
|
131
|
+
if (transactions.length === 0 || transactions.every((tr2) => !tr2.docChanged)) {
|
132
|
+
return null;
|
133
|
+
}
|
134
|
+
const ranges = getCheckRanges(transactions, oldState, newState);
|
135
|
+
const toRemove = [];
|
136
|
+
const toCreate = [];
|
137
|
+
for (const [from, to] of ranges) {
|
138
|
+
const expected = getExpectedMarkings(rules, newState.doc, from, to);
|
139
|
+
const received = getReceivedMarkings(rules, newState.doc, from, to);
|
140
|
+
toRemove.push(...markRangeDiffs(received, expected));
|
141
|
+
toCreate.push(...markRangeDiffs(expected, received));
|
142
|
+
}
|
143
|
+
if (toCreate.length === 0 && toRemove.length === 0) {
|
144
|
+
return null;
|
145
|
+
}
|
146
|
+
const tr = newState.tr;
|
147
|
+
for (const [from, to, mark] of toRemove) {
|
148
|
+
tr.removeMark(from, to, mark);
|
149
|
+
}
|
150
|
+
for (const [from, to, mark] of toCreate) {
|
151
|
+
tr.addMark(from, to, mark);
|
152
|
+
}
|
153
|
+
return tr;
|
154
|
+
}
|
155
|
+
|
156
|
+
// src/mark-rule/extension.ts
|
157
|
+
function defineMarkRule(options) {
|
158
|
+
const { regex, type, attrs } = options;
|
159
|
+
const getAttrs = attrs && typeof attrs === "object" ? () => attrs : attrs;
|
160
|
+
return markRuleFacet.extension([{ regex, type, getAttrs }]);
|
161
|
+
}
|
162
|
+
var markRuleFacet = Facet.define({
|
163
|
+
converter: () => {
|
164
|
+
let rules = [];
|
165
|
+
const plugin = new ProseMirrorPlugin({
|
166
|
+
appendTransaction: (transactions, oldState, newState) => {
|
167
|
+
return applyMarkRules(rules, transactions, oldState, newState);
|
168
|
+
}
|
169
|
+
});
|
170
|
+
const pluginFunc = () => [plugin];
|
171
|
+
return {
|
172
|
+
create: (inputs) => {
|
173
|
+
rules = inputs;
|
174
|
+
return pluginFunc;
|
175
|
+
},
|
176
|
+
update: (inputs) => {
|
177
|
+
rules = inputs;
|
178
|
+
return null;
|
179
|
+
}
|
180
|
+
};
|
181
|
+
},
|
182
|
+
next: pluginFacet
|
183
|
+
});
|
184
|
+
|
185
|
+
export {
|
186
|
+
defineMarkRule
|
187
|
+
};
|
package/dist/list/style.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* ../../node_modules/.pnpm/prosemirror-flat-list@0.
|
1
|
+
/* ../../node_modules/.pnpm/prosemirror-flat-list@0.5.0/node_modules/prosemirror-flat-list/dist/style.css */
|
2
2
|
.prosemirror-flat-list {
|
3
3
|
padding: 0;
|
4
4
|
margin-top: 0;
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import {
|
2
|
-
defineTextBlockInputRule
|
3
|
-
} from "./chunk-DYFRBXUX.js";
|
4
1
|
import {
|
5
2
|
defineTextBlockEnterRule
|
6
3
|
} from "./chunk-ASTUC4KT.js";
|
4
|
+
import {
|
5
|
+
defineTextBlockInputRule
|
6
|
+
} from "./chunk-DYFRBXUX.js";
|
7
7
|
|
8
8
|
// src/code-block/code-block.ts
|
9
9
|
import { union } from "@prosekit/core";
|
@@ -2,5 +2,6 @@ export { defineLinkSpec } from './_tsup-dts-rollup';
|
|
2
2
|
export { defineLinkCommands } from './_tsup-dts-rollup';
|
3
3
|
export { defineLinkInputRule } from './_tsup-dts-rollup';
|
4
4
|
export { defineLinkEnterRule } from './_tsup-dts-rollup';
|
5
|
+
export { defineLinkMarkRule } from './_tsup-dts-rollup';
|
5
6
|
export { defineLink } from './_tsup-dts-rollup';
|
6
7
|
export { LinkAttrs } from './_tsup-dts-rollup';
|
@@ -1,9 +1,12 @@
|
|
1
1
|
import {
|
2
|
-
|
3
|
-
} from "./chunk-
|
2
|
+
defineMarkRule
|
3
|
+
} from "./chunk-MX6UNVWH.js";
|
4
4
|
import {
|
5
5
|
defineEnterRule
|
6
6
|
} from "./chunk-ASTUC4KT.js";
|
7
|
+
import {
|
8
|
+
defineInputRule
|
9
|
+
} from "./chunk-DYFRBXUX.js";
|
7
10
|
|
8
11
|
// src/link/index.ts
|
9
12
|
import {
|
@@ -19,15 +22,19 @@ import { InputRule } from "@prosekit/pm/inputrules";
|
|
19
22
|
|
20
23
|
// src/link/link-regex.ts
|
21
24
|
var TLD_RE_PATTERN = "a(?:a(?:a|rp)|b(?:arth|b(?:ott|vie)?|c|le|ogado|udhabi)|c(?:ademy|c(?:enture|ountants?)|o|tor)?|d(?:s|ult)?|e(?:g|ro|tna)?|f(?:l|rica)?|g(?:akhan|ency)?|i(?:g|r(?:bus|force|tel))?|kdn|l(?:faromeo|i(?:baba|pay)|l(?:finanz|state|y)|s(?:ace|tom))?|m(?:azon|e(?:rican(?:express|family)|x)|fam|ica|sterdam)?|n(?:alytics|droid|quan|z)|ol?|p(?:artments|p(?:le)?)|q(?:uarelle)?|r(?:a(?:b|mco)|chi|my|pa|te?)?|s(?:da|ia|sociates)?|t(?:hleta|torney)?|u(?:ction|di(?:ble|o)?|spost|t(?:hor|os?))?|vianca|ws?|xa?|z(?:ure)?)|b(?:a(?:by|idu|n(?:a(?:mex|narepublic)|d|k)|r(?:c(?:elona|lay(?:card|s))|efoot|gains)?|s(?:eball|ketball)|uhaus|yern)?|b(?:c|t|va)?|c[gn]|d|e(?:a(?:ts|uty)|er|ntley|rlin|st(?:buy)?|t)?|f|g|h(?:arti)?|i(?:ble|d|ke|ngo?|o|z)?|j|l(?:ack(?:friday)?|o(?:ckbuster|g|omberg)|ue)|m[sw]?|n(?:pparibas)?|o(?:ats|ehringer|fa|m|nd|o(?:k(?:ing)?)?|s(?:ch|t(?:ik|on))|t|utique|x)?|r(?:adesco|idgestone|o(?:adway|ker|ther)|ussels)?|s|t|u(?:ild(?:ers)?|siness|y|zz)|v|w|y|zh?)|c(?:a(?:b|fe|l(?:l|vinklein)?|m(?:era|p)?|non|p(?:etown|ital(?:one)?)|r(?:avan|ds|e(?:ers?)?|s)?|s(?:a|e|h|ino)|t(?:ering|holic)?)?|b(?:a|n|re|s)|c|d|e(?:nter|o|rn)|f[ad]?|g|h(?:a(?:n(?:el|nel)|rity|se|t)|eap|intai|r(?:istmas|ome)|urch)?|i(?:priani|rcle|sco|t(?:adel|ic?|y(?:eats)?))?|k|l(?:aims|eaning|i(?:ck|ni(?:c|que))|o(?:thing|ud)|ub(?:med)?)?|m|n|o(?:ach|des|ffee|l(?:lege|ogne)|m(?:cast|m(?:bank|unity)|p(?:a(?:ny|re)|uter)|sec)?|n(?:dos|s(?:truction|ulting)|t(?:act|ractors))|o(?:king(?:channel)?|l|p)|rsica|u(?:ntry|pons?|rses))?|pa|r(?:edit(?:card|union)?|icket|own|s|uises?)?|u(?:isinella)?|v|w|x|y(?:mru|ou)?|z)|d(?:a(?:bur|d|nce|t(?:a|e|ing|sun)|y)|clk|ds|e(?:al(?:er|s)?|gree|l(?:ivery|l|oitte|ta)|mocrat|nt(?:al|ist)|si(?:gn)?|v)?|hl|i(?:amonds|et|gital|rect(?:ory)?|s(?:co(?:unt|ver)|h)|y)|j|k|m|np|o(?:c(?:s|tor)|g|mains|t|wnload)?|rive|tv|u(?:bai|nlop|pont|rban)|v(?:ag|r)|z)|e(?:a(?:rth|t)|co?|d(?:eka|u(?:cation)?)|e|g|m(?:ail|erck)|n(?:ergy|gineer(?:ing)?|terprises)|pson|quipment|r(?:icsson|ni)?|s(?:q|tate)?|t(?:isalat)?|u(?:rovision|s)?|vents|x(?:change|p(?:ert|osed|ress)|traspace))|f(?:a(?:ge|i(?:l|rwinds|th)|mily|ns?|rm(?:ers)?|s(?:hion|t))|e(?:dex|edback|rr(?:ari|ero))|i(?:at|d(?:elity|o)|lm|na(?:l|nc(?:e|ial))|r(?:e(?:stone)?|mdale)|sh(?:ing)?|t(?:ness)?)?|j|k|l(?:i(?:ckr|ghts|r)|o(?:rist|wers)|y)|m|o(?:o(?:d(?:network)?|tball)?|r(?:d|ex|sale|um)|undation|x)?|r(?:e(?:e|senius)|l|o(?:gans|nt(?:door|ier)))?|tr|u(?:jitsu|nd?|rniture|tbol)|yi)|g(?:a(?:l(?:l(?:ery|o|up))?|mes?|p|rden|y)?|b(?:iz)?|dn?|e(?:a|nt(?:ing)?|orge)?|f|g(?:ee)?|h|i(?:fts?|v(?:es|ing))?|l(?:ass|e|ob(?:al|o))?|m(?:ail|bh|o|x)?|n|o(?:daddy|l(?:d(?:point)?|f)|o(?:dyear|g(?:le)?)?|p|t|v)|p|q|r(?:a(?:inger|phics|tis)|een|ipe|o(?:cery|up))?|s|t|u(?:ardian|cci|ge|i(?:de|tars)|ru)?|w|y)|h(?:a(?:ir|mburg|ngout|us)|bo|dfc(?:bank)?|e(?:alth(?:care)?|l(?:p|sinki)|r(?:e|mes))|gtv|i(?:phop|samitsu|tachi|v)|kt?|m|n|o(?:ckey|l(?:dings|iday)|me(?:depot|goods|s(?:ense)?)|nda|rse|s(?:pital|t(?:ing)?)|t(?:el(?:es|s)|mail)?|use|w)|r|sbc|t|u(?:ghes)?|y(?:att|undai))|i(?:bm|c(?:bc|e|u)|d|e(?:ee)?|fm|kano|l|m(?:amat|db|mo(?:bilien)?)?|n(?:c|dustries|f(?:initi|o)|g|k|s(?:titute|ur(?:ance|e))|t(?:ernational|uit)?|vestments)?|o|piranga|q|r(?:ish)?|s(?:maili|t(?:anbul)?)?|t(?:au|v)?)|j(?:a(?:guar|va)|cb|e(?:ep|tzt|welry)?|io|ll|mp?|nj|o(?:b(?:s|urg)|t|y)?|p(?:morgan|rs)?|u(?:egos|niper))|k(?:aufen|ddi|e(?:rry(?:hotels|logistics|properties))?|fh|g|h|i(?:a|ds|m|nd(?:er|le)|tchen|wi)?|m|n|o(?:eln|matsu|sher)|p(?:mg|n)?|r(?:d|ed)?|uokgroup|w|y(?:oto)?|z)|l(?:a(?:caixa|m(?:borghini|er)|n(?:c(?:aster|ia)|d(?:rover)?|xess)|salle|t(?:ino|robe)?|w(?:yer)?)?|b|c|ds|e(?:ase|clerc|frak|g(?:al|o)|xus)|gbt|i(?:dl|fe(?:insurance|style)?|ghting|ke|lly|m(?:ited|o)|n(?:coln|de|k)|psy|v(?:e|ing))?|k|l[cp]|o(?:ans?|c(?:ker|us)|l|ndon|tt[eo]|ve)|pl(?:financial)?|r|s|t(?:da?)?|u(?:ndbeck|x(?:e|ury))?|v|y)|m(?:a(?:cys|drid|i(?:f|son)|keup|n(?:agement|go)?|p|r(?:ket(?:ing|s)?|riott|shalls)|serati|ttel)?|ba|c(?:kinsey)?|d|e(?:d(?:ia)?|et|lbourne|m(?:e|orial)|nu?|rckmsd)?|g|h|i(?:ami|crosoft|l|n[it]|t(?:subishi)?)|k|l[bs]?|ma?|n|o(?:bi(?:le)?|da|e|i|m|n(?:ash|ey|ster)|r(?:mon|tgage)|scow|to(?:rcycles)?|v(?:ie)?)?|p|q|r|sd?|t[nr]?|u(?:s(?:eum|ic)|tual)?|v|w|x|y|z)|n(?:a(?:b|goya|me|tura|vy)?|ba|c|e(?:c|t(?:bank|flix|work)?|ustar|ws?|x(?:t(?:direct)?|us))?|fl?|go?|hk|i(?:co|k(?:e|on)|nja|ssa[ny])?|l|o(?:kia|rt(?:hwesternmutual|on)|w(?:ruz|tv)?)?|p|r[aw]?|tt|u|yc|z)|o(?:b(?:i|server)|ffice|kinawa|l(?:ayan(?:group)?|dnavy|lo)|m(?:ega)?|n(?:e|g|l(?:ine)?)|oo|pen|r(?:a(?:cle|nge)|g(?:anic)?|igins)|saka|t(?:suka|t)|vh)|p(?:a(?:ge|nasonic|r(?:is|s|t(?:ners|s|y))|ssagens|y)?|ccw|et?|f(?:izer)?|g|h(?:armacy|d|ilips|o(?:ne|to(?:graphy|s)?)|ysio)?|i(?:c(?:s|t(?:et|ures))|d|n[gk]?|oneer|zza)|k|l(?:a(?:ce|y(?:station)?)|u(?:mbing|s))?|m|nc?|o(?:hl|ker|litie|rn|st)|r(?:a(?:merica|xi)|ess|ime|o(?:d(?:uctions)?|f|gressive|mo|pert(?:ies|y)|tection)?|u(?:dential)?)?|s|t|ub|wc?|y)|q(?:a|pon|ue(?:bec|st))|r(?:a(?:cing|dio)|e(?:a(?:d|l(?:estate|t(?:or|y)))|cipes|d(?:stone|umbrella)?|hab|i(?:sen?|t)|liance|n(?:t(?:als)?)?|p(?:air|ort|ublican)|st(?:aurant)?|views?|xroth)?|i(?:c(?:h(?:ardli)?|oh)|l|o|p)|o(?:c(?:her|ks)|deo|gers|om)?|s(?:vp)?|u(?:gby|hr|n)?|we?|yukyu)|s(?:a(?:arland|fe(?:ty)?|kura|l(?:e|on)|ms(?:club|ung)|n(?:dvik(?:coromant)?|ofi)|p|rl|s|ve|xo)?|b[is]?|c(?:a|b|h(?:aeffler|midt|o(?:larships|ol)|ule|warz)|ience|ot)?|d|e(?:a(?:rch|t)|cur(?:e|ity)|ek|lect|ner|rvices|ven|w|xy?)?|fr|g|h(?:a(?:ngrila|rp|w)|ell|i(?:a|ksha)|o(?:es|p(?:ping)?|uji|w(?:time)?))?|i(?:lk|n(?:a|gles)|te)?|j|k(?:in?|y(?:pe)?)?|l(?:ing)?|m(?:art|ile)?|n(?:cf)?|o(?:c(?:cer|ial)|ft(?:bank|ware)|hu|l(?:ar|utions)|n[gy]|y)?|p(?:a(?:ce)?|o(?:rt|t))|rl?|s|t(?:a(?:da|ples|r|te(?:bank|farm))|c(?:group)?|o(?:ckholm|r(?:age|e))|ream|ud(?:io|y)|yle)?|u(?:cks|pp(?:l(?:ies|y)|ort)|r(?:f|gery)|zuki)?|v|w(?:atch|iss)|x|y(?:dney|stems)?|z)|t(?:a(?:b|ipei|lk|obao|rget|t(?:a(?:motors|r)|too)|xi?)|ci?|dk?|e(?:am|ch(?:nology)?|l|masek|nnis|va)|f|g|h(?:d|eat(?:er|re))?|i(?:aa|ckets|enda|ffany|ps|r(?:es|ol))|j(?:maxx|x)?|k(?:maxx)?|l|m(?:all)?|n|o(?:day|kyo|ols|p|ray|shiba|tal|urs|wn|y(?:ota|s))?|r(?:a(?:d(?:e|ing)|ining|vel(?:channel|ers(?:insurance)?)?)|ust|v)?|t|u(?:be|i|nes|shu)|vs?|w|z)|u(?:a|b(?:ank|s)|g|k|n(?:i(?:com|versity)|o)|ol|ps|s|y|z)|v(?:a(?:cations|n(?:a|guard))?|c|e(?:gas|ntures|r(?:isign|sicherung)|t)?|g|i(?:ajes|deo|g|king|llas|n|p|rgin|s(?:a|ion)|v[ao])?|laanderen|n|o(?:dka|l(?:kswagen|vo)|t(?:e|ing|o)|yage)|u(?:elos)?)|w(?:a(?:l(?:es|mart|ter)|ng(?:gou)?|tch(?:es)?)|e(?:ather(?:channel)?|b(?:cam|er|site)|d(?:ding)?|i(?:bo|r))|f|hoswho|i(?:en|ki|lliamhill|n(?:dows|e|ners)?)|me|o(?:lterskluwer|odside|r(?:ks?|ld)|w)|s|t[cf])|x(?:box|erox|finity|i(?:huan|n)|xx|yz)|y(?:a(?:chts|hoo|maxun|ndex)|e|o(?:dobashi|ga|kohama|u(?:tube)?)|t|un)|z(?:a(?:ppos|ra)?|ero|ip|m|one|uerich|w)";
|
25
|
+
var PUNCTUATION_CHAR_PATTERN = "\\.\\,\\;\\!\\?";
|
26
|
+
var STOP_CHAR_PATTERN = "[" + PUNCTUATION_CHAR_PATTERN + "]";
|
27
|
+
var END_CHAR_PATTERN = "[^\\s" + PUNCTUATION_CHAR_PATTERN + "]";
|
22
28
|
var LINK_RE_BASE_PATTERN = (
|
23
29
|
// start of the link group
|
24
|
-
"((?:(?:(?:https?:)?\\/\\/)?(?:(?:[a-z0-9\\u00a1-\\uffff][a-z0-9\\u00a1-\\uffff_-]{0,62})?[a-z0-9\\u00a1-\\uffff]\\.)+(?:" + TLD_RE_PATTERN + "))(?::\\d{2,5})?(
|
30
|
+
"((?:(?:(?:https?:)?\\/\\/)?(?:(?:[a-z0-9\\u00a1-\\uffff][a-z0-9\\u00a1-\\uffff_-]{0,62})?[a-z0-9\\u00a1-\\uffff]\\.)+(?:" + TLD_RE_PATTERN + "))(?::\\d{2,5})?(?:/(?:\\S*" + END_CHAR_PATTERN + ")?)?(?:\\?(?:\\S*" + END_CHAR_PATTERN + "))?(?:\\#(?:\\S*" + END_CHAR_PATTERN + ")?)?)"
|
25
31
|
);
|
26
|
-
var
|
27
|
-
var
|
28
|
-
var
|
29
|
-
var
|
30
|
-
var
|
32
|
+
var LINK_ENTER_PATTERN = LINK_RE_BASE_PATTERN + STOP_CHAR_PATTERN + "?$";
|
33
|
+
var LINK_INPUT_PATTERN = LINK_RE_BASE_PATTERN + STOP_CHAR_PATTERN + "?\\s$";
|
34
|
+
var LINK_MARK_PATTERN = LINK_RE_BASE_PATTERN + "(?=" + STOP_CHAR_PATTERN + "|\\s|$)";
|
35
|
+
var LINK_ENTER_RE = new RegExp(LINK_ENTER_PATTERN, "gi");
|
36
|
+
var LINK_INPUT_RE = new RegExp(LINK_INPUT_PATTERN, "gi");
|
37
|
+
var LINK_MARK_RE = new RegExp(LINK_MARK_PATTERN, "gi");
|
31
38
|
|
32
39
|
// src/link/index.ts
|
33
40
|
function defineLinkSpec() {
|
@@ -63,7 +70,7 @@ function defineLinkCommands() {
|
|
63
70
|
}
|
64
71
|
function defineLinkInputRule() {
|
65
72
|
return defineInputRule(
|
66
|
-
new InputRule(
|
73
|
+
new InputRule(LINK_INPUT_RE, (state, match, from) => {
|
67
74
|
const href = match[1];
|
68
75
|
if (!href)
|
69
76
|
return null;
|
@@ -74,7 +81,7 @@ function defineLinkInputRule() {
|
|
74
81
|
}
|
75
82
|
function defineLinkEnterRule() {
|
76
83
|
return defineEnterRule({
|
77
|
-
regex:
|
84
|
+
regex: LINK_ENTER_RE,
|
78
85
|
handler: ({ state, from, match }) => {
|
79
86
|
const href = match[1];
|
80
87
|
if (!href)
|
@@ -85,6 +92,13 @@ function defineLinkEnterRule() {
|
|
85
92
|
}
|
86
93
|
});
|
87
94
|
}
|
95
|
+
function defineLinkMarkRule() {
|
96
|
+
return defineMarkRule({
|
97
|
+
regex: LINK_MARK_RE,
|
98
|
+
type: "link",
|
99
|
+
attrs: (match) => ({ href: match[1] })
|
100
|
+
});
|
101
|
+
}
|
88
102
|
function defineLink() {
|
89
103
|
return union([
|
90
104
|
defineLinkSpec(),
|
@@ -98,5 +112,6 @@ export {
|
|
98
112
|
defineLinkCommands,
|
99
113
|
defineLinkEnterRule,
|
100
114
|
defineLinkInputRule,
|
115
|
+
defineLinkMarkRule,
|
101
116
|
defineLinkSpec
|
102
117
|
};
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@prosekit/extensions",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.4.
|
4
|
+
"version": "0.4.4",
|
5
5
|
"private": false,
|
6
6
|
"author": {
|
7
7
|
"name": "ocavue",
|
@@ -30,6 +30,11 @@
|
|
30
30
|
"import": "./dist/prosekit-extensions.js",
|
31
31
|
"default": "./dist/prosekit-extensions.js"
|
32
32
|
},
|
33
|
+
"./mark-rule": {
|
34
|
+
"types": "./dist/prosekit-extensions-mark-rule.d.ts",
|
35
|
+
"import": "./dist/prosekit-extensions-mark-rule.js",
|
36
|
+
"default": "./dist/prosekit-extensions-mark-rule.js"
|
37
|
+
},
|
33
38
|
"./autocomplete": {
|
34
39
|
"types": "./dist/prosekit-extensions-autocomplete.d.ts",
|
35
40
|
"import": "./dist/prosekit-extensions-autocomplete.js",
|
@@ -147,19 +152,19 @@
|
|
147
152
|
"dist"
|
148
153
|
],
|
149
154
|
"dependencies": {
|
150
|
-
"@prosekit/core": "^0.4.
|
155
|
+
"@prosekit/core": "^0.4.1",
|
151
156
|
"@prosekit/pm": "^0.1.2",
|
152
157
|
"prosemirror-dropcursor": "^1.8.1",
|
153
|
-
"prosemirror-flat-list": "^0.
|
158
|
+
"prosemirror-flat-list": "^0.5.0",
|
154
159
|
"prosemirror-highlight": "^0.5.0",
|
155
160
|
"prosemirror-tables": "^1.3.7",
|
156
|
-
"shiki": "^1.
|
161
|
+
"shiki": "^1.3.0"
|
157
162
|
},
|
158
163
|
"devDependencies": {
|
159
164
|
"@prosekit/dev": "*",
|
160
165
|
"tsup": "^8.0.2",
|
161
|
-
"typescript": "^5.
|
162
|
-
"vitest": "^1.
|
166
|
+
"typescript": "^5.4.5",
|
167
|
+
"vitest": "^1.5.2"
|
163
168
|
},
|
164
169
|
"scripts": {
|
165
170
|
"build:tsup": "tsup",
|
@@ -171,6 +176,9 @@
|
|
171
176
|
".": [
|
172
177
|
"./dist/prosekit-extensions.d.ts"
|
173
178
|
],
|
179
|
+
"mark-rule": [
|
180
|
+
"./dist/prosekit-extensions-mark-rule.d.ts"
|
181
|
+
],
|
174
182
|
"autocomplete": [
|
175
183
|
"./dist/prosekit-extensions-autocomplete.d.ts"
|
176
184
|
],
|