@prosekit/extensions 0.3.0 → 0.3.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.
@@ -246,7 +246,7 @@ export declare function defineDropCursor(options?: DropCursorOptions): Extension
246
246
  *
247
247
  * @public
248
248
  */
249
- export declare function defineEnterRule({ regex, handler, }: EnterRuleOptions): Extension;
249
+ export declare function defineEnterRule({ regex, handler, stop, }: EnterRuleOptions): Extension;
250
250
 
251
251
  /**
252
252
  * @public
@@ -355,6 +355,10 @@ expandLink: [];
355
355
  };
356
356
  }>;
357
357
 
358
+ export declare function defineLinkEnterRule(): Extension<ExtensionTyping<string, string, CommandArgs>>;
359
+
360
+ export declare function defineLinkInputRule(): Extension<ExtensionTyping<string, string, CommandArgs>>;
361
+
358
362
  export declare function defineLinkSpec(): Extension< {
359
363
  MARKS: "link";
360
364
  }>;
@@ -469,7 +473,7 @@ MARKS: "strike";
469
473
  *
470
474
  * @public
471
475
  */
472
- export declare function defineTextBlockEnterRule({ regex, type, attrs, }: TextBlockEnterRuleOptions): Extension;
476
+ export declare function defineTextBlockEnterRule({ regex, type, attrs, stop, }: TextBlockEnterRuleOptions): Extension;
473
477
 
474
478
  /**
475
479
  * Defines an input rule that changes the type of a textblock when the matched
@@ -605,6 +609,12 @@ export declare type EnterRuleOptions = {
605
609
  * A handler function to be called when an enter rule is triggered.
606
610
  */
607
611
  handler: EnterRuleHandler;
612
+ /**
613
+ * Whether to stop further handlers from being called if this rule is triggered.
614
+ *
615
+ * @default false
616
+ */
617
+ stop?: boolean;
608
618
  };
609
619
 
610
620
  export declare function getPluginState(state: EditorState): PredictionPluginState | undefined;
@@ -628,6 +638,10 @@ export declare interface ImageAttrs {
628
638
  src?: string | null;
629
639
  }
630
640
 
641
+ export declare const LINK_RE: RegExp;
642
+
643
+ export declare const LINK_SPACE_RE: RegExp;
644
+
631
645
  /**
632
646
  * @public
633
647
  */
@@ -642,7 +656,7 @@ declare type MatchHandler = (options: {
642
656
  to: number;
643
657
  ignoreMatch: () => void;
644
658
  deleteMatch: () => void;
645
- }) => Transaction | null | void;
659
+ }) => void;
646
660
  export { MatchHandler }
647
661
  export { MatchHandler as MatchHandler_alias_1 }
648
662
 
@@ -700,6 +714,12 @@ export declare type TextBlockEnterRuleOptions = {
700
714
  * Attributes to set on the node.
701
715
  */
702
716
  attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null);
717
+ /**
718
+ * Whether to stop further handlers from being called if this rule is triggered.
719
+ *
720
+ * @default true
721
+ */
722
+ stop?: boolean;
703
723
  };
704
724
 
705
725
  export { }
@@ -0,0 +1,111 @@
1
+ // src/enter-rule/index.ts
2
+ import {
3
+ Facet,
4
+ OBJECT_REPLACEMENT_CHARACTER,
5
+ getNodeType,
6
+ isTextSelection,
7
+ pluginFacet
8
+ } from "@prosekit/core";
9
+ import { keydownHandler } from "@prosekit/pm/keymap";
10
+ import {
11
+ ProseMirrorPlugin
12
+ } from "@prosekit/pm/state";
13
+ function defineEnterRule({
14
+ regex,
15
+ handler,
16
+ stop = false
17
+ }) {
18
+ const rule = new EnterRule(regex, handler, stop);
19
+ return enterRule.extension([rule]);
20
+ }
21
+ function defineTextBlockEnterRule({
22
+ regex,
23
+ type,
24
+ attrs,
25
+ stop = true
26
+ }) {
27
+ return defineEnterRule({
28
+ regex,
29
+ handler: ({ state, from, to, match }) => {
30
+ const nodeType = getNodeType(state.schema, type);
31
+ const $start = state.doc.resolve(from);
32
+ if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) {
33
+ return null;
34
+ }
35
+ const nodeAttrs = attrs && typeof attrs === "function" ? attrs(match) : attrs;
36
+ return state.tr.delete(from, to).setBlockType(from, from, nodeType, nodeAttrs);
37
+ },
38
+ stop
39
+ });
40
+ }
41
+ var EnterRule = class {
42
+ constructor(regex, handler, stop) {
43
+ this.regex = regex;
44
+ this.handler = handler;
45
+ this.stop = stop;
46
+ }
47
+ };
48
+ var enterRule = Facet.define({
49
+ converter: () => {
50
+ let rules = [];
51
+ const command = (state, dispatch, view) => {
52
+ if (!view)
53
+ return false;
54
+ return execRules(view, rules, dispatch);
55
+ };
56
+ const handler = keydownHandler({ Enter: command });
57
+ const plugin = new ProseMirrorPlugin({ props: { handleKeyDown: handler } });
58
+ const pluginFunc = () => [plugin];
59
+ return {
60
+ create: (inputs) => {
61
+ rules = inputs;
62
+ return pluginFunc;
63
+ },
64
+ update: (inputs) => {
65
+ rules = inputs;
66
+ return null;
67
+ }
68
+ };
69
+ },
70
+ next: pluginFacet
71
+ });
72
+ function execRules(view, rules, dispatch) {
73
+ if (view.composing)
74
+ return false;
75
+ const state = view.state;
76
+ const selection = state.selection;
77
+ if (!isTextSelection(selection))
78
+ return false;
79
+ const $cursor = selection.$cursor;
80
+ if (!$cursor || $cursor.parent.type.spec.code)
81
+ return false;
82
+ const textBefore = $cursor.parent.textBetween(
83
+ Math.max(0, $cursor.parentOffset - MAX_MATCH),
84
+ $cursor.parentOffset,
85
+ null,
86
+ OBJECT_REPLACEMENT_CHARACTER
87
+ );
88
+ for (const rule of rules) {
89
+ rule.regex.lastIndex = 0;
90
+ const match = rule.regex.exec(textBefore);
91
+ const tr = match && rule.handler({
92
+ state,
93
+ from: $cursor.pos - match[0].length,
94
+ to: $cursor.pos,
95
+ match
96
+ });
97
+ if (!tr)
98
+ continue;
99
+ dispatch == null ? void 0 : dispatch(tr);
100
+ if (rule.stop) {
101
+ return true;
102
+ }
103
+ }
104
+ return false;
105
+ }
106
+ var MAX_MATCH = 200;
107
+
108
+ export {
109
+ defineEnterRule,
110
+ defineTextBlockEnterRule
111
+ };
@@ -1,3 +1,6 @@
1
+ import {
2
+ defineTextBlockEnterRule
3
+ } from "./chunk-6DQPSMHC.js";
1
4
  import {
2
5
  defineTextBlockInputRule
3
6
  } from "./chunk-DYFRBXUX.js";
@@ -41,91 +44,6 @@ function defineCodeBlockHighlight({
41
44
  );
42
45
  }
43
46
 
44
- // src/enter-rule/index.ts
45
- import {
46
- Facet,
47
- getNodeType,
48
- isTextSelection,
49
- keymapFacet,
50
- OBJECT_REPLACEMENT_CHARACTER
51
- } from "@prosekit/core";
52
- function defineEnterRule({
53
- regex,
54
- handler
55
- }) {
56
- const rule = new EnterRule(regex, handler);
57
- return inputRuleFacet.extension([rule]);
58
- }
59
- function defineTextBlockEnterRule({
60
- regex,
61
- type,
62
- attrs
63
- }) {
64
- return defineEnterRule({
65
- regex,
66
- handler: ({ state, from, to, match }) => {
67
- const nodeType = getNodeType(state.schema, type);
68
- const $start = state.doc.resolve(from);
69
- if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) {
70
- return null;
71
- }
72
- const nodeAttrs = attrs && typeof attrs === "function" ? attrs(match) : attrs;
73
- return state.tr.delete(from, to).setBlockType(from, from, nodeType, nodeAttrs);
74
- }
75
- });
76
- }
77
- var EnterRule = class {
78
- constructor(regex, handler) {
79
- this.regex = regex;
80
- this.handler = handler;
81
- }
82
- };
83
- var inputRuleFacet = Facet.define({
84
- convert: (inputs) => {
85
- return {
86
- Enter: (state, dispatch, view) => {
87
- if (!view)
88
- return false;
89
- return execRules(view, inputs, dispatch);
90
- }
91
- };
92
- },
93
- next: keymapFacet
94
- });
95
- function execRules(view, rules, dispatch) {
96
- if (view.composing)
97
- return false;
98
- const state = view.state;
99
- const selection = state.selection;
100
- if (!isTextSelection(selection))
101
- return false;
102
- const $cursor = selection.$cursor;
103
- if (!$cursor || $cursor.parent.type.spec.code)
104
- return false;
105
- const textBefore = $cursor.parent.textBetween(
106
- Math.max(0, $cursor.parentOffset - MAX_MATCH),
107
- $cursor.parentOffset,
108
- null,
109
- OBJECT_REPLACEMENT_CHARACTER
110
- );
111
- for (const rule of rules) {
112
- rule.regex.lastIndex = 0;
113
- const match = rule.regex.exec(textBefore);
114
- const tr = match && rule.handler({
115
- state,
116
- from: $cursor.pos - match[0].length,
117
- to: $cursor.pos,
118
- match
119
- });
120
- if (!tr)
121
- continue;
122
- dispatch == null ? void 0 : dispatch(tr);
123
- return true;
124
- }
125
- return false;
126
- }
127
- var MAX_MATCH = 200;
128
-
129
47
  // src/code-block/code-block-input-rule.ts
130
48
  function defineCodeBlockInputRule() {
131
49
  return defineTextBlockInputRule({
@@ -1,4 +1,6 @@
1
1
  export { defineLinkSpec } from './_tsup-dts-rollup';
2
2
  export { defineLinkCommands } from './_tsup-dts-rollup';
3
+ export { defineLinkInputRule } from './_tsup-dts-rollup';
4
+ export { defineLinkEnterRule } from './_tsup-dts-rollup';
3
5
  export { defineLink } from './_tsup-dts-rollup';
4
6
  export { LinkAttrs } from './_tsup-dts-rollup';
@@ -1,16 +1,39 @@
1
+ import {
2
+ defineEnterRule
3
+ } from "./chunk-6DQPSMHC.js";
4
+ import {
5
+ defineInputRule
6
+ } from "./chunk-DYFRBXUX.js";
7
+
1
8
  // src/link/index.ts
2
9
  import {
3
- defineCommands,
4
10
  addMark,
11
+ defineCommands,
5
12
  defineMarkSpec,
6
- union,
13
+ expandMark,
7
14
  removeMark,
8
15
  toggleMark,
9
- expandMark
16
+ union
10
17
  } from "@prosekit/core";
18
+ import { InputRule } from "@prosekit/pm/inputrules";
19
+
20
+ // src/link/link-regex.ts
21
+ 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)";
22
+ var LINK_RE_BASE_PATTERN = (
23
+ // 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})?(?:[/?#]\\S*)?)"
25
+ );
26
+ var LINK_STOP_PATTERN = "(?:\\.|\\,|\\;\\!)?";
27
+ var LINK_RE_PATTERN = LINK_RE_BASE_PATTERN + LINK_STOP_PATTERN + "$";
28
+ var LINK_SPACE_RE_PATTERN = LINK_RE_BASE_PATTERN + LINK_STOP_PATTERN + "\\s$";
29
+ var LINK_RE = new RegExp(LINK_RE_PATTERN, "gi");
30
+ var LINK_SPACE_RE = new RegExp(LINK_SPACE_RE_PATTERN, "gi");
31
+
32
+ // src/link/index.ts
11
33
  function defineLinkSpec() {
12
34
  return defineMarkSpec({
13
35
  name: "link",
36
+ inclusive: false,
14
37
  parseDOM: [
15
38
  {
16
39
  tag: "a[href]",
@@ -38,11 +61,42 @@ function defineLinkCommands() {
38
61
  expandLink: () => expandMark({ type: "link" })
39
62
  });
40
63
  }
64
+ function defineLinkInputRule() {
65
+ return defineInputRule(
66
+ new InputRule(LINK_SPACE_RE, (state, match, from) => {
67
+ const href = match[1];
68
+ if (!href)
69
+ return null;
70
+ const mark = state.schema.marks.link.create({ href });
71
+ return state.tr.addMark(from, from + href.length, mark).insertText(" ");
72
+ })
73
+ );
74
+ }
75
+ function defineLinkEnterRule() {
76
+ return defineEnterRule({
77
+ regex: LINK_RE,
78
+ handler: ({ state, from, match }) => {
79
+ const href = match[1];
80
+ if (!href)
81
+ return null;
82
+ const mark = state.schema.marks.link.create({ href });
83
+ const tr = state.tr.addMark(from, from + href.length, mark);
84
+ return tr.docChanged ? tr : null;
85
+ }
86
+ });
87
+ }
41
88
  function defineLink() {
42
- return union([defineLinkSpec(), defineLinkCommands()]);
89
+ return union([
90
+ defineLinkSpec(),
91
+ defineLinkCommands(),
92
+ defineLinkInputRule(),
93
+ defineLinkEnterRule()
94
+ ]);
43
95
  }
44
96
  export {
45
97
  defineLink,
46
98
  defineLinkCommands,
99
+ defineLinkEnterRule,
100
+ defineLinkInputRule,
47
101
  defineLinkSpec
48
102
  };
@@ -33,9 +33,8 @@ var virtualSelectionPlugin = new ProseMirrorPlugin({
33
33
  view.dispatch(setFocusMeta(view.state.tr, false));
34
34
  },
35
35
  blur: (view) => {
36
- var _a;
37
- const dom = view.dom;
38
- const activeElement = (_a = dom == null ? void 0 : dom.ownerDocument) == null ? void 0 : _a.activeElement;
36
+ const { dom, root } = view;
37
+ const activeElement = root.activeElement;
39
38
  if (activeElement === dom)
40
39
  return;
41
40
  view.dispatch(setFocusMeta(view.state.tr, true));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.3.1",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",