@atlaskit/prosemirror-input-rules 2.1.7 → 2.1.9

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # @atlaskit/prosemirror-input-rules
2
2
 
3
+ ## 2.1.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0606572f9b8`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0606572f9b8) - [ux] ED-15348 docs(changeset): ED-15348 Fix a bug preventing typeahead actions to be fired from a gap cursor. Typing a typeahead trigger key (/, : or @) should pop-up a typeahead menu. However, if the current selection is inside a gap cursor, the trigger character is inserted and the pop-up menu doesn't open. This changeset fixes that.
8
+ - Updated dependencies
9
+
10
+ ## 2.1.8
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+
3
16
  ## 2.1.7
4
17
 
5
18
  ### Patch Changes
@@ -9,6 +9,8 @@ exports.createInputEventHandler = void 0;
9
9
 
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
 
12
+ var _selection = require("@atlaskit/editor-common/selection");
13
+
12
14
  var _constants = require("./constants");
13
15
 
14
16
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -87,8 +89,16 @@ function findMatchOnRules(_ref3) {
87
89
  state = _ref3.state;
88
90
 
89
91
  for (var i = 0; i < rules.length; i++) {
90
- var rule = rules[i];
91
- var match = rule.match.exec(textBefore);
92
+ var _textBefore$at;
93
+
94
+ var rule = rules[i]; // Some plugins like Typeahead require a whitespace before a trigger character.
95
+ // We want them to fire inside a gap cursor. Yet, a gap cursor is not considered a whitespace,
96
+ // and `textBefore` contains the text in the previous block before the gap cursor.
97
+ // Here is a workaround: if we inside a gap cursor, match the input rule only against the last typed character
98
+ // (which may be a typeahead trigger) and ignore the rest.
99
+
100
+ var matchString = state.selection instanceof _selection.GapCursorSelection ? (_textBefore$at = textBefore.at(-1)) !== null && _textBefore$at !== void 0 ? _textBefore$at : '' : textBefore;
101
+ var match = rule.match.exec(matchString);
92
102
 
93
103
  if (!match) {
94
104
  continue;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/prosemirror-input-rules",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "sideEffects": false
5
5
  }
@@ -1,3 +1,4 @@
1
+ import { GapCursorSelection } from '@atlaskit/editor-common/selection';
1
2
  import { leafNodeReplacementCharacter, MAX_REGEX_MATCH, TEXT_INPUT_RULE_TRANSACTION_KEY } from './constants';
2
3
  export const createInputEventHandler = ({
3
4
  rules,
@@ -68,8 +69,16 @@ function findMatchOnRules({
68
69
  state
69
70
  }) {
70
71
  for (let i = 0; i < rules.length; i++) {
71
- const rule = rules[i];
72
- const match = rule.match.exec(textBefore);
72
+ var _textBefore$at;
73
+
74
+ const rule = rules[i]; // Some plugins like Typeahead require a whitespace before a trigger character.
75
+ // We want them to fire inside a gap cursor. Yet, a gap cursor is not considered a whitespace,
76
+ // and `textBefore` contains the text in the previous block before the gap cursor.
77
+ // Here is a workaround: if we inside a gap cursor, match the input rule only against the last typed character
78
+ // (which may be a typeahead trigger) and ignore the rest.
79
+
80
+ const matchString = state.selection instanceof GapCursorSelection ? (_textBefore$at = textBefore.at(-1)) !== null && _textBefore$at !== void 0 ? _textBefore$at : '' : textBefore;
81
+ const match = rule.match.exec(matchString);
73
82
 
74
83
  if (!match) {
75
84
  continue;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/prosemirror-input-rules",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "sideEffects": false
5
5
  }
@@ -4,6 +4,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
4
4
 
5
5
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
6
 
7
+ import { GapCursorSelection } from '@atlaskit/editor-common/selection';
7
8
  import { leafNodeReplacementCharacter, MAX_REGEX_MATCH, TEXT_INPUT_RULE_TRANSACTION_KEY } from './constants';
8
9
  export var createInputEventHandler = function createInputEventHandler(_ref) {
9
10
  var rules = _ref.rules,
@@ -75,8 +76,16 @@ function findMatchOnRules(_ref3) {
75
76
  state = _ref3.state;
76
77
 
77
78
  for (var i = 0; i < rules.length; i++) {
78
- var rule = rules[i];
79
- var match = rule.match.exec(textBefore);
79
+ var _textBefore$at;
80
+
81
+ var rule = rules[i]; // Some plugins like Typeahead require a whitespace before a trigger character.
82
+ // We want them to fire inside a gap cursor. Yet, a gap cursor is not considered a whitespace,
83
+ // and `textBefore` contains the text in the previous block before the gap cursor.
84
+ // Here is a workaround: if we inside a gap cursor, match the input rule only against the last typed character
85
+ // (which may be a typeahead trigger) and ignore the rest.
86
+
87
+ var matchString = state.selection instanceof GapCursorSelection ? (_textBefore$at = textBefore.at(-1)) !== null && _textBefore$at !== void 0 ? _textBefore$at : '' : textBefore;
88
+ var match = rule.match.exec(matchString);
80
89
 
81
90
  if (!match) {
82
91
  continue;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/prosemirror-input-rules",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "sideEffects": false
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/prosemirror-input-rules",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "description": "A package that contains helpers to create autoformatting rules for ProseMirror",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -19,13 +19,13 @@
19
19
  "releaseModel": "scheduled"
20
20
  },
21
21
  "dependencies": {
22
- "@atlaskit/editor-common": "^69.0.0",
22
+ "@atlaskit/editor-common": "^71.0.0",
23
23
  "@babel/runtime": "^7.0.0",
24
24
  "prosemirror-state": "1.3.4"
25
25
  },
26
26
  "devDependencies": {
27
- "@atlaskit/adf-schema": "^23.2.0",
28
- "@atlaskit/editor-test-helpers": "^17.1.0",
27
+ "@atlaskit/adf-schema": "^24.0.0",
28
+ "@atlaskit/editor-test-helpers": "^17.2.0",
29
29
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
30
30
  "@types/prosemirror-history": "^1.0.1",
31
31
  "@types/prosemirror-model": "^1.11.0",
@@ -41,7 +41,10 @@
41
41
  "import-structure": "atlassian-conventions"
42
42
  },
43
43
  "@repo/internal": {
44
- "deprecation": "no-deprecated-imports"
44
+ "deprecation": "no-deprecated-imports",
45
+ "styling": [
46
+ "emotion"
47
+ ]
45
48
  }
46
49
  },
47
50
  "af:exports": {
package/report.api.md CHANGED
@@ -1,57 +1,82 @@
1
+ <!-- API Report Version: 2.2 -->
2
+
1
3
  ## API Report File for "@atlaskit/prosemirror-input-rules"
2
4
 
3
- > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
5
+ > Do not edit this file. This report is auto-generated using [API Extractor](https://api-extractor.com/).
6
+ > [Learn more about API reports](https://hello.atlassian.net/wiki/spaces/UR/pages/1825484529/Package+API+Reports)
7
+
8
+ ### Table of contents
9
+
10
+ - [Main Entry Types](#main-entry-types)
11
+
12
+ ### Main Entry Types
13
+
14
+ <!--SECTION START: Main Entry Types-->
4
15
 
5
16
  ```ts
6
17
  import type { EditorState } from 'prosemirror-state';
7
18
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
8
19
  import type { Transaction } from 'prosemirror-state';
9
20
 
10
- export declare function createInputRulePlugin(
21
+ // @public (undocumented)
22
+ export function createInputRulePlugin(
11
23
  pluginName: string,
12
24
  rules: InputRuleWrapper[],
13
25
  options?: Options,
14
26
  ): SafePlugin;
15
27
 
16
- export declare type InputRuleHandler = (
28
+ // @public (undocumented)
29
+ export type InputRuleHandler = (
17
30
  state: EditorState,
18
31
  matchResult: RegExpExecArray,
19
32
  start: number,
20
33
  end: number,
21
34
  ) => Transaction | null;
22
35
 
23
- export declare interface InputRuleWrapper {
24
- match: RegExp;
36
+ // @public (undocumented)
37
+ export interface InputRuleWrapper {
38
+ // (undocumented)
25
39
  handler: InputRuleHandler;
40
+ // (undocumented)
41
+ match: RegExp;
42
+ // (undocumented)
26
43
  onHandlerApply?: OnHandlerApply;
27
44
  }
28
45
 
29
- export declare const leafNodeReplacementCharacter = '\uFFFC';
46
+ // @public (undocumented)
47
+ export const leafNodeReplacementCharacter = '\uFFFC';
30
48
 
31
- export declare const MAX_REGEX_MATCH = 500;
49
+ // @public (undocumented)
50
+ export const MAX_REGEX_MATCH = 500;
32
51
 
33
- declare type OnBeforeRegexMatch = (tr: Transaction) => void;
52
+ // @public (undocumented)
53
+ type OnBeforeRegexMatch = (tr: Transaction) => void;
34
54
 
35
- export declare type OnHandlerApply = (
55
+ // @public (undocumented)
56
+ export type OnHandlerApply = (
36
57
  state: EditorState,
37
58
  tr: Transaction,
38
59
  matchResult: RegExpExecArray,
39
60
  ) => void;
40
61
 
41
- export declare type OnInputEvent = (props: {
62
+ // @public (undocumented)
63
+ export type OnInputEvent = (props: {
42
64
  state: EditorState;
43
65
  from: number;
44
66
  to: number;
45
67
  }) => boolean;
46
68
 
47
- declare type Options = {
69
+ // @public (undocumented)
70
+ type Options = {
48
71
  allowInsertTextOnDocument?: boolean;
49
72
  onInputEvent?: OnInputEvent;
50
73
  onBeforeRegexMatch?: OnBeforeRegexMatch;
51
74
  };
52
75
 
53
- export declare const TEXT_INPUT_RULE_TRANSACTION_KEY =
54
- 'input_rule_plugin_transaction';
76
+ // @public (undocumented)
77
+ export const TEXT_INPUT_RULE_TRANSACTION_KEY = 'input_rule_plugin_transaction';
55
78
 
56
- export {};
79
+ // (No @packageDocumentation comment for this package)
57
80
  ```
81
+
82
+ <!--SECTION END: Main Entry Types-->
package/src/handler.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type { EditorState, PluginKey, Transaction } from 'prosemirror-state';
2
2
 
3
+ import { GapCursorSelection } from '@atlaskit/editor-common/selection';
4
+
3
5
  import {
4
6
  leafNodeReplacementCharacter,
5
7
  MAX_REGEX_MATCH,
@@ -22,65 +24,67 @@ type Options = {
22
24
  onBeforeRegexMatch?: OnBeforeRegexMatch;
23
25
  };
24
26
 
25
- export const createInputEventHandler = ({
26
- rules,
27
- pluginKey,
28
- allowInsertTextOnDocument,
29
- onInputEvent,
30
- onBeforeRegexMatch,
31
- }: Options): HandleInputEvent => ({ view, from, to, text }) => {
32
- if (view.composing) {
33
- return false;
34
- }
27
+ export const createInputEventHandler =
28
+ ({
29
+ rules,
30
+ pluginKey,
31
+ allowInsertTextOnDocument,
32
+ onInputEvent,
33
+ onBeforeRegexMatch,
34
+ }: Options): HandleInputEvent =>
35
+ ({ view, from, to, text }) => {
36
+ if (view.composing) {
37
+ return false;
38
+ }
35
39
 
36
- const state = view.state;
37
- const $from = state.doc.resolve(from);
40
+ const state = view.state;
41
+ const $from = state.doc.resolve(from);
38
42
 
39
- if ($from.parent.type.spec.code) {
40
- return false;
41
- }
42
- if (onInputEvent && !onInputEvent({ state, from, to })) {
43
- return false;
44
- }
43
+ if ($from.parent.type.spec.code) {
44
+ return false;
45
+ }
46
+ if (onInputEvent && !onInputEvent({ state, from, to })) {
47
+ return false;
48
+ }
45
49
 
46
- const textBefore =
47
- $from.parent.textBetween(
48
- Math.max(0, $from.parentOffset - MAX_REGEX_MATCH),
49
- $from.parentOffset,
50
- undefined,
51
- leafNodeReplacementCharacter,
52
- ) + text;
50
+ const textBefore =
51
+ $from.parent.textBetween(
52
+ Math.max(0, $from.parentOffset - MAX_REGEX_MATCH),
53
+ $from.parentOffset,
54
+ undefined,
55
+ leafNodeReplacementCharacter,
56
+ ) + text;
53
57
 
54
- const result = findMatchOnRules({
55
- rules,
56
- textBefore,
57
- from,
58
- to,
59
- state,
60
- });
61
-
62
- if (!result) {
63
- return false;
64
- }
58
+ const result = findMatchOnRules({
59
+ rules,
60
+ textBefore,
61
+ from,
62
+ to,
63
+ state,
64
+ });
65
65
 
66
- const tr = allowInsertTextOnDocument
67
- ? state.tr.insertText(text, from, to)
68
- : state.tr;
69
- tr.setMeta(TEXT_INPUT_RULE_TRANSACTION_KEY, true);
70
- tr.setMeta(pluginKey, {
71
- textInserted: text,
72
- from: result.from,
73
- to: result.to,
74
- matchedRule: result.matchedRule,
75
- } as InputRulePluginState);
76
-
77
- if (onBeforeRegexMatch) {
78
- onBeforeRegexMatch(tr);
79
- }
66
+ if (!result) {
67
+ return false;
68
+ }
80
69
 
81
- view.dispatch(tr);
82
- return true;
83
- };
70
+ const tr = allowInsertTextOnDocument
71
+ ? state.tr.insertText(text, from, to)
72
+ : state.tr;
73
+ tr.setMeta(TEXT_INPUT_RULE_TRANSACTION_KEY, true);
74
+ tr.setMeta(pluginKey, {
75
+ textInserted: text,
76
+ from: result.from,
77
+ to: result.to,
78
+ matchedRule: result.matchedRule,
79
+ } as InputRulePluginState);
80
+
81
+ if (onBeforeRegexMatch) {
82
+ onBeforeRegexMatch(tr);
83
+ }
84
+
85
+ view.dispatch(tr);
86
+ return true;
87
+ };
84
88
 
85
89
  type FindMatchOnRulesProps = {
86
90
  rules: InputRuleWrapper[];
@@ -103,7 +107,18 @@ function findMatchOnRules({
103
107
  }: FindMatchOnRulesProps): RuleMatchedResult | null {
104
108
  for (let i = 0; i < rules.length; i++) {
105
109
  const rule = rules[i];
106
- const match = rule.match.exec(textBefore);
110
+
111
+ // Some plugins like Typeahead require a whitespace before a trigger character.
112
+ // We want them to fire inside a gap cursor. Yet, a gap cursor is not considered a whitespace,
113
+ // and `textBefore` contains the text in the previous block before the gap cursor.
114
+ // Here is a workaround: if we inside a gap cursor, match the input rule only against the last typed character
115
+ // (which may be a typeahead trigger) and ignore the rest.
116
+ const matchString: string =
117
+ state.selection instanceof GapCursorSelection
118
+ ? textBefore.at(-1) ?? ''
119
+ : textBefore;
120
+
121
+ const match = rule.match.exec(matchString);
107
122
  if (!match) {
108
123
  continue;
109
124
  }
package/src/plugin.ts CHANGED
@@ -56,10 +56,8 @@ export function createInputRulePlugin(
56
56
  tr.getMeta(pluginKey),
57
57
  );
58
58
 
59
- const pluginState:
60
- | InputRulePluginState
61
- | undefined
62
- | null = transactionWithInputRuleMeta?.getMeta(pluginKey);
59
+ const pluginState: InputRulePluginState | undefined | null =
60
+ transactionWithInputRuleMeta?.getMeta(pluginKey);
63
61
 
64
62
  if (!pluginState || !transactionWithInputRuleMeta) {
65
63
  return null;
package/tsconfig.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "extends": "../../../tsconfig.json",
3
3
  "compilerOptions": {
4
- "noImplicitAny": true,
5
4
  "baseUrl": "./"
6
5
  },
7
6
  "include": [