@atlaskit/editor-plugin-block-type 16.1.29 → 16.1.31
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 +18 -0
- package/dist/cjs/pm-plugins/commands/split-heading-with-trailing-space.js +92 -0
- package/dist/cjs/pm-plugins/keymap.js +11 -0
- package/dist/es2019/pm-plugins/commands/split-heading-with-trailing-space.js +88 -0
- package/dist/es2019/pm-plugins/keymap.js +12 -1
- package/dist/esm/pm-plugins/commands/split-heading-with-trailing-space.js +86 -0
- package/dist/esm/pm-plugins/keymap.js +12 -1
- package/dist/types/pm-plugins/commands/split-heading-with-trailing-space.d.ts +16 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-type
|
|
2
2
|
|
|
3
|
+
## 16.1.31
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 16.1.30
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`bed6e0c408de8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bed6e0c408de8) -
|
|
14
|
+
[ux] Fix: pressing Enter after a heading that has trailing whitespace now creates a paragraph
|
|
15
|
+
instead of another heading — but only when the caret sits after all heading content and
|
|
16
|
+
immediately before the trailing whitespace (so it looks like the end of the heading). Mid-heading
|
|
17
|
+
splits still produce a heading. Behind the `platform_editor_fix_new_line_after_heading`
|
|
18
|
+
experiment.
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
|
|
3
21
|
## 16.1.29
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.splitHeadingWithTrailingSpace = void 0;
|
|
7
|
+
var _commands = require("@atlaskit/editor-prosemirror/commands");
|
|
8
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
9
|
+
var WHITESPACE_ONLY = /^\s+$/;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Determines whether the current selection is inside a heading, positioned after
|
|
13
|
+
* all of the heading's visible (non-whitespace) content but *before* one or more
|
|
14
|
+
* trailing whitespace characters.
|
|
15
|
+
*
|
|
16
|
+
* In this scenario ProseMirror's default `splitBlock` treats the cursor as *not*
|
|
17
|
+
* being at the end of the node (`atEnd === false`), because there is still
|
|
18
|
+
* (whitespace) content between the cursor and the node boundary. As a result the
|
|
19
|
+
* newly split-off block inherits the heading type instead of becoming a
|
|
20
|
+
* paragraph — even though, visually, the cursor looks like it is at the end of
|
|
21
|
+
* the heading.
|
|
22
|
+
*
|
|
23
|
+
* We intentionally scope this to *only* that case:
|
|
24
|
+
* - The parent must be a heading.
|
|
25
|
+
* - The selection must be empty (a plain caret, not a range).
|
|
26
|
+
* - There must be at least one character between the caret and the end of the
|
|
27
|
+
* heading, and every such character must be whitespace.
|
|
28
|
+
*
|
|
29
|
+
* All other cases (caret mid-word, caret at the true end, empty heading, etc.)
|
|
30
|
+
* return `false` so the default behaviour is preserved.
|
|
31
|
+
*/
|
|
32
|
+
var isCursorAfterHeadingContentBeforeTrailingWhitespace = function isCursorAfterHeadingContentBeforeTrailingWhitespace($from) {
|
|
33
|
+
var parent = $from.parent;
|
|
34
|
+
var headingType = $from.doc.type.schema.nodes.heading;
|
|
35
|
+
if (!headingType || parent.type !== headingType) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Offset of the caret within the heading's content.
|
|
40
|
+
var offsetInParent = $from.parentOffset;
|
|
41
|
+
var contentSize = parent.content.size;
|
|
42
|
+
|
|
43
|
+
// If the caret is already at (or past) the end of the heading content, this is
|
|
44
|
+
// the normal "atEnd" case handled correctly by the default split — skip.
|
|
45
|
+
if (offsetInParent >= contentSize) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The remaining text between the caret and the end of the heading.
|
|
50
|
+
var trailingText = parent.textBetween(offsetInParent, contentSize);
|
|
51
|
+
|
|
52
|
+
// Must be non-empty and consist solely of whitespace.
|
|
53
|
+
return trailingText.length > 0 && WHITESPACE_ONLY.test(trailingText);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A plain-Enter command that fixes the "new line after a heading with a trailing
|
|
58
|
+
* space becomes another heading" bug.
|
|
59
|
+
*
|
|
60
|
+
* It reuses ProseMirror's `splitBlockAs` but supplies a custom `splitNode`
|
|
61
|
+
* callback that forces the newly split-off block to be a paragraph *only* when
|
|
62
|
+
* the caret is in a heading, after all visible content, immediately before
|
|
63
|
+
* trailing whitespace. In every other case it returns `null`, which makes
|
|
64
|
+
* `splitBlockAs` fall back to its default type resolution — identical to the
|
|
65
|
+
* default `splitBlock` behaviour.
|
|
66
|
+
*
|
|
67
|
+
* The command returns `false` when the target scenario does not apply, allowing
|
|
68
|
+
* other Enter handlers (lists, code blocks, base keymap) to run unchanged.
|
|
69
|
+
*/
|
|
70
|
+
var splitHeadingWithTrailingSpace = exports.splitHeadingWithTrailingSpace = function splitHeadingWithTrailingSpace(state, dispatch, view) {
|
|
71
|
+
var $from = state.selection.$from;
|
|
72
|
+
|
|
73
|
+
// Only act on an empty caret selection inside a matching heading.
|
|
74
|
+
if (!state.selection.empty || !isCursorAfterHeadingContentBeforeTrailingWhitespace($from)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
var paragraphType = state.schema.nodes.paragraph;
|
|
78
|
+
if (!paragraphType) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return (0, _commands.splitBlockAs)(function (_node, atEnd) {
|
|
82
|
+
// Guard again inside the callback: only override the type for the exact
|
|
83
|
+
// scenario. If ProseMirror already considers us at the end, defer to the
|
|
84
|
+
// default (return null).
|
|
85
|
+
if (atEnd) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
type: paragraphType
|
|
90
|
+
};
|
|
91
|
+
})(state, dispatch, view);
|
|
92
|
+
};
|
|
@@ -10,10 +10,12 @@ var _keymaps = require("@atlaskit/editor-common/keymaps");
|
|
|
10
10
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
11
11
|
var _commands = require("@atlaskit/editor-prosemirror/commands");
|
|
12
12
|
var _prosemirrorHistory = require("@atlaskit/prosemirror-history");
|
|
13
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
13
14
|
var blockTypes = _interopRequireWildcard(require("./block-types"));
|
|
14
15
|
var _blockType = require("./commands/block-type");
|
|
15
16
|
var _deleteAndMoveCursor = require("./commands/delete-and-move-cursor");
|
|
16
17
|
var _deleteBlockContent = require("./commands/delete-block-content");
|
|
18
|
+
var _splitHeadingWithTrailingSpace = require("./commands/split-heading-with-trailing-space");
|
|
17
19
|
var _utils2 = require("./utils");
|
|
18
20
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
19
21
|
// Ignored via go/ees005
|
|
@@ -27,6 +29,15 @@ function keymapPlugin(editorAnalyticsApi, schema, _featureFlags) {
|
|
|
27
29
|
// Ignored via go/ees005
|
|
28
30
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
29
31
|
_keymaps.insertNewLine.common, (0, _utils.insertNewLineWithAnalytics)(editorAnalyticsApi), list);
|
|
32
|
+
|
|
33
|
+
// Fixes the "Enter after a heading with trailing whitespace creates another
|
|
34
|
+
// heading instead of a paragraph" bug. The command is a no-op (returns false)
|
|
35
|
+
// in every case except that exact scenario, so other Enter handlers are
|
|
36
|
+
// unaffected.
|
|
37
|
+
if ((0, _expValEquals.expValEquals)('platform_editor_fix_new_line_after_heading', 'isEnabled', true)) {
|
|
38
|
+
var _enter$common;
|
|
39
|
+
(0, _keymaps.bindKeymapWithCommand)((_enter$common = _keymaps.enter.common) !== null && _enter$common !== void 0 ? _enter$common : 'Enter', _splitHeadingWithTrailingSpace.splitHeadingWithTrailingSpace, list);
|
|
40
|
+
}
|
|
30
41
|
// Ignored via go/ees005
|
|
31
42
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
32
43
|
(0, _keymaps.bindKeymapWithCommand)(_keymaps.moveUp.common, _utils.createNewParagraphAbove, list);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { splitBlockAs } from '@atlaskit/editor-prosemirror/commands';
|
|
2
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
3
|
+
const WHITESPACE_ONLY = /^\s+$/;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Determines whether the current selection is inside a heading, positioned after
|
|
7
|
+
* all of the heading's visible (non-whitespace) content but *before* one or more
|
|
8
|
+
* trailing whitespace characters.
|
|
9
|
+
*
|
|
10
|
+
* In this scenario ProseMirror's default `splitBlock` treats the cursor as *not*
|
|
11
|
+
* being at the end of the node (`atEnd === false`), because there is still
|
|
12
|
+
* (whitespace) content between the cursor and the node boundary. As a result the
|
|
13
|
+
* newly split-off block inherits the heading type instead of becoming a
|
|
14
|
+
* paragraph — even though, visually, the cursor looks like it is at the end of
|
|
15
|
+
* the heading.
|
|
16
|
+
*
|
|
17
|
+
* We intentionally scope this to *only* that case:
|
|
18
|
+
* - The parent must be a heading.
|
|
19
|
+
* - The selection must be empty (a plain caret, not a range).
|
|
20
|
+
* - There must be at least one character between the caret and the end of the
|
|
21
|
+
* heading, and every such character must be whitespace.
|
|
22
|
+
*
|
|
23
|
+
* All other cases (caret mid-word, caret at the true end, empty heading, etc.)
|
|
24
|
+
* return `false` so the default behaviour is preserved.
|
|
25
|
+
*/
|
|
26
|
+
const isCursorAfterHeadingContentBeforeTrailingWhitespace = $from => {
|
|
27
|
+
const parent = $from.parent;
|
|
28
|
+
const headingType = $from.doc.type.schema.nodes.heading;
|
|
29
|
+
if (!headingType || parent.type !== headingType) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Offset of the caret within the heading's content.
|
|
34
|
+
const offsetInParent = $from.parentOffset;
|
|
35
|
+
const contentSize = parent.content.size;
|
|
36
|
+
|
|
37
|
+
// If the caret is already at (or past) the end of the heading content, this is
|
|
38
|
+
// the normal "atEnd" case handled correctly by the default split — skip.
|
|
39
|
+
if (offsetInParent >= contentSize) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// The remaining text between the caret and the end of the heading.
|
|
44
|
+
const trailingText = parent.textBetween(offsetInParent, contentSize);
|
|
45
|
+
|
|
46
|
+
// Must be non-empty and consist solely of whitespace.
|
|
47
|
+
return trailingText.length > 0 && WHITESPACE_ONLY.test(trailingText);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A plain-Enter command that fixes the "new line after a heading with a trailing
|
|
52
|
+
* space becomes another heading" bug.
|
|
53
|
+
*
|
|
54
|
+
* It reuses ProseMirror's `splitBlockAs` but supplies a custom `splitNode`
|
|
55
|
+
* callback that forces the newly split-off block to be a paragraph *only* when
|
|
56
|
+
* the caret is in a heading, after all visible content, immediately before
|
|
57
|
+
* trailing whitespace. In every other case it returns `null`, which makes
|
|
58
|
+
* `splitBlockAs` fall back to its default type resolution — identical to the
|
|
59
|
+
* default `splitBlock` behaviour.
|
|
60
|
+
*
|
|
61
|
+
* The command returns `false` when the target scenario does not apply, allowing
|
|
62
|
+
* other Enter handlers (lists, code blocks, base keymap) to run unchanged.
|
|
63
|
+
*/
|
|
64
|
+
export const splitHeadingWithTrailingSpace = (state, dispatch, view) => {
|
|
65
|
+
const {
|
|
66
|
+
$from
|
|
67
|
+
} = state.selection;
|
|
68
|
+
|
|
69
|
+
// Only act on an empty caret selection inside a matching heading.
|
|
70
|
+
if (!state.selection.empty || !isCursorAfterHeadingContentBeforeTrailingWhitespace($from)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const paragraphType = state.schema.nodes.paragraph;
|
|
74
|
+
if (!paragraphType) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return splitBlockAs((_node, atEnd) => {
|
|
78
|
+
// Guard again inside the callback: only override the type for the exact
|
|
79
|
+
// scenario. If ProseMirror already considers us at the end, defer to the
|
|
80
|
+
// default (return null).
|
|
81
|
+
if (atEnd) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
type: paragraphType
|
|
86
|
+
};
|
|
87
|
+
})(state, dispatch, view);
|
|
88
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
-
import { backspace, bindKeymapWithCommand, deleteKey, findKeyMapForBrowser, findShortcutByKeymap, forwardDelete, insertNewLine, keymap, moveDown, moveUp, redo as redoKeymap, toggleBlockQuote, undo as undoKeymap } from '@atlaskit/editor-common/keymaps';
|
|
2
|
+
import { backspace, bindKeymapWithCommand, deleteKey, enter, findKeyMapForBrowser, findShortcutByKeymap, forwardDelete, insertNewLine, keymap, moveDown, moveUp, redo as redoKeymap, toggleBlockQuote, undo as undoKeymap } from '@atlaskit/editor-common/keymaps';
|
|
3
3
|
import { createNewParagraphAbove, createNewParagraphBelow, deleteEmptyParagraphAndMoveBlockUp, insertNewLineWithAnalytics } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
|
5
5
|
import { redo, undo } from '@atlaskit/prosemirror-history';
|
|
6
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
7
|
|
|
7
8
|
// Ignored via go/ees005
|
|
8
9
|
// eslint-disable-next-line import/no-namespace
|
|
@@ -10,6 +11,7 @@ import * as blockTypes from './block-types';
|
|
|
10
11
|
import { cleanUpAtTheStartOfDocument, insertBlockQuoteWithAnalytics } from './commands/block-type';
|
|
11
12
|
import { deleteAndMoveCursor } from './commands/delete-and-move-cursor';
|
|
12
13
|
import { deleteBlockContent } from './commands/delete-block-content';
|
|
14
|
+
import { splitHeadingWithTrailingSpace } from './commands/split-heading-with-trailing-space';
|
|
13
15
|
import { isNodeAWrappingBlockNode } from './utils';
|
|
14
16
|
const backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
|
15
17
|
const del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
|
@@ -19,6 +21,15 @@ export default function keymapPlugin(editorAnalyticsApi, schema, _featureFlags)
|
|
|
19
21
|
// Ignored via go/ees005
|
|
20
22
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
21
23
|
insertNewLine.common, insertNewLineWithAnalytics(editorAnalyticsApi), list);
|
|
24
|
+
|
|
25
|
+
// Fixes the "Enter after a heading with trailing whitespace creates another
|
|
26
|
+
// heading instead of a paragraph" bug. The command is a no-op (returns false)
|
|
27
|
+
// in every case except that exact scenario, so other Enter handlers are
|
|
28
|
+
// unaffected.
|
|
29
|
+
if (expValEquals('platform_editor_fix_new_line_after_heading', 'isEnabled', true)) {
|
|
30
|
+
var _enter$common;
|
|
31
|
+
bindKeymapWithCommand((_enter$common = enter.common) !== null && _enter$common !== void 0 ? _enter$common : 'Enter', splitHeadingWithTrailingSpace, list);
|
|
32
|
+
}
|
|
22
33
|
// Ignored via go/ees005
|
|
23
34
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
24
35
|
bindKeymapWithCommand(moveUp.common, createNewParagraphAbove, list);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { splitBlockAs } from '@atlaskit/editor-prosemirror/commands';
|
|
2
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
3
|
+
var WHITESPACE_ONLY = /^\s+$/;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Determines whether the current selection is inside a heading, positioned after
|
|
7
|
+
* all of the heading's visible (non-whitespace) content but *before* one or more
|
|
8
|
+
* trailing whitespace characters.
|
|
9
|
+
*
|
|
10
|
+
* In this scenario ProseMirror's default `splitBlock` treats the cursor as *not*
|
|
11
|
+
* being at the end of the node (`atEnd === false`), because there is still
|
|
12
|
+
* (whitespace) content between the cursor and the node boundary. As a result the
|
|
13
|
+
* newly split-off block inherits the heading type instead of becoming a
|
|
14
|
+
* paragraph — even though, visually, the cursor looks like it is at the end of
|
|
15
|
+
* the heading.
|
|
16
|
+
*
|
|
17
|
+
* We intentionally scope this to *only* that case:
|
|
18
|
+
* - The parent must be a heading.
|
|
19
|
+
* - The selection must be empty (a plain caret, not a range).
|
|
20
|
+
* - There must be at least one character between the caret and the end of the
|
|
21
|
+
* heading, and every such character must be whitespace.
|
|
22
|
+
*
|
|
23
|
+
* All other cases (caret mid-word, caret at the true end, empty heading, etc.)
|
|
24
|
+
* return `false` so the default behaviour is preserved.
|
|
25
|
+
*/
|
|
26
|
+
var isCursorAfterHeadingContentBeforeTrailingWhitespace = function isCursorAfterHeadingContentBeforeTrailingWhitespace($from) {
|
|
27
|
+
var parent = $from.parent;
|
|
28
|
+
var headingType = $from.doc.type.schema.nodes.heading;
|
|
29
|
+
if (!headingType || parent.type !== headingType) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Offset of the caret within the heading's content.
|
|
34
|
+
var offsetInParent = $from.parentOffset;
|
|
35
|
+
var contentSize = parent.content.size;
|
|
36
|
+
|
|
37
|
+
// If the caret is already at (or past) the end of the heading content, this is
|
|
38
|
+
// the normal "atEnd" case handled correctly by the default split — skip.
|
|
39
|
+
if (offsetInParent >= contentSize) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// The remaining text between the caret and the end of the heading.
|
|
44
|
+
var trailingText = parent.textBetween(offsetInParent, contentSize);
|
|
45
|
+
|
|
46
|
+
// Must be non-empty and consist solely of whitespace.
|
|
47
|
+
return trailingText.length > 0 && WHITESPACE_ONLY.test(trailingText);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A plain-Enter command that fixes the "new line after a heading with a trailing
|
|
52
|
+
* space becomes another heading" bug.
|
|
53
|
+
*
|
|
54
|
+
* It reuses ProseMirror's `splitBlockAs` but supplies a custom `splitNode`
|
|
55
|
+
* callback that forces the newly split-off block to be a paragraph *only* when
|
|
56
|
+
* the caret is in a heading, after all visible content, immediately before
|
|
57
|
+
* trailing whitespace. In every other case it returns `null`, which makes
|
|
58
|
+
* `splitBlockAs` fall back to its default type resolution — identical to the
|
|
59
|
+
* default `splitBlock` behaviour.
|
|
60
|
+
*
|
|
61
|
+
* The command returns `false` when the target scenario does not apply, allowing
|
|
62
|
+
* other Enter handlers (lists, code blocks, base keymap) to run unchanged.
|
|
63
|
+
*/
|
|
64
|
+
export var splitHeadingWithTrailingSpace = function splitHeadingWithTrailingSpace(state, dispatch, view) {
|
|
65
|
+
var $from = state.selection.$from;
|
|
66
|
+
|
|
67
|
+
// Only act on an empty caret selection inside a matching heading.
|
|
68
|
+
if (!state.selection.empty || !isCursorAfterHeadingContentBeforeTrailingWhitespace($from)) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
var paragraphType = state.schema.nodes.paragraph;
|
|
72
|
+
if (!paragraphType) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return splitBlockAs(function (_node, atEnd) {
|
|
76
|
+
// Guard again inside the callback: only override the type for the exact
|
|
77
|
+
// scenario. If ProseMirror already considers us at the end, defer to the
|
|
78
|
+
// default (return null).
|
|
79
|
+
if (atEnd) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
type: paragraphType
|
|
84
|
+
};
|
|
85
|
+
})(state, dispatch, view);
|
|
86
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
-
import { backspace, bindKeymapWithCommand, deleteKey, findKeyMapForBrowser, findShortcutByKeymap, forwardDelete, insertNewLine, keymap, moveDown, moveUp, redo as redoKeymap, toggleBlockQuote, undo as undoKeymap } from '@atlaskit/editor-common/keymaps';
|
|
2
|
+
import { backspace, bindKeymapWithCommand, deleteKey, enter, findKeyMapForBrowser, findShortcutByKeymap, forwardDelete, insertNewLine, keymap, moveDown, moveUp, redo as redoKeymap, toggleBlockQuote, undo as undoKeymap } from '@atlaskit/editor-common/keymaps';
|
|
3
3
|
import { createNewParagraphAbove, createNewParagraphBelow, deleteEmptyParagraphAndMoveBlockUp, insertNewLineWithAnalytics } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
|
5
5
|
import { redo, undo } from '@atlaskit/prosemirror-history';
|
|
6
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
7
|
|
|
7
8
|
// Ignored via go/ees005
|
|
8
9
|
// eslint-disable-next-line import/no-namespace
|
|
@@ -10,6 +11,7 @@ import * as blockTypes from './block-types';
|
|
|
10
11
|
import { cleanUpAtTheStartOfDocument, insertBlockQuoteWithAnalytics } from './commands/block-type';
|
|
11
12
|
import { deleteAndMoveCursor } from './commands/delete-and-move-cursor';
|
|
12
13
|
import { deleteBlockContent } from './commands/delete-block-content';
|
|
14
|
+
import { splitHeadingWithTrailingSpace } from './commands/split-heading-with-trailing-space';
|
|
13
15
|
import { isNodeAWrappingBlockNode } from './utils';
|
|
14
16
|
var backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
|
15
17
|
var del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
|
@@ -19,6 +21,15 @@ export default function keymapPlugin(editorAnalyticsApi, schema, _featureFlags)
|
|
|
19
21
|
// Ignored via go/ees005
|
|
20
22
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
21
23
|
insertNewLine.common, insertNewLineWithAnalytics(editorAnalyticsApi), list);
|
|
24
|
+
|
|
25
|
+
// Fixes the "Enter after a heading with trailing whitespace creates another
|
|
26
|
+
// heading instead of a paragraph" bug. The command is a no-op (returns false)
|
|
27
|
+
// in every case except that exact scenario, so other Enter handlers are
|
|
28
|
+
// unaffected.
|
|
29
|
+
if (expValEquals('platform_editor_fix_new_line_after_heading', 'isEnabled', true)) {
|
|
30
|
+
var _enter$common;
|
|
31
|
+
bindKeymapWithCommand((_enter$common = enter.common) !== null && _enter$common !== void 0 ? _enter$common : 'Enter', splitHeadingWithTrailingSpace, list);
|
|
32
|
+
}
|
|
22
33
|
// Ignored via go/ees005
|
|
23
34
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
24
35
|
bindKeymapWithCommand(moveUp.common, createNewParagraphAbove, list);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Command } from '@atlaskit/editor-common/types';
|
|
2
|
+
/**
|
|
3
|
+
* A plain-Enter command that fixes the "new line after a heading with a trailing
|
|
4
|
+
* space becomes another heading" bug.
|
|
5
|
+
*
|
|
6
|
+
* It reuses ProseMirror's `splitBlockAs` but supplies a custom `splitNode`
|
|
7
|
+
* callback that forces the newly split-off block to be a paragraph *only* when
|
|
8
|
+
* the caret is in a heading, after all visible content, immediately before
|
|
9
|
+
* trailing whitespace. In every other case it returns `null`, which makes
|
|
10
|
+
* `splitBlockAs` fall back to its default type resolution — identical to the
|
|
11
|
+
* default `splitBlock` behaviour.
|
|
12
|
+
*
|
|
13
|
+
* The command returns `false` when the target scenario does not apply, allowing
|
|
14
|
+
* other Enter handlers (lists, code blocks, base keymap) to run unchanged.
|
|
15
|
+
*/
|
|
16
|
+
export declare const splitHeadingWithTrailingSpace: Command;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-type",
|
|
3
|
-
"version": "16.1.
|
|
3
|
+
"version": "16.1.31",
|
|
4
4
|
"description": "BlockType plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -36,20 +36,20 @@
|
|
|
36
36
|
"@atlaskit/editor-tables": "^3.0.0",
|
|
37
37
|
"@atlaskit/editor-toolbar": "^2.3.0",
|
|
38
38
|
"@atlaskit/editor-toolbar-model": "^1.1.0",
|
|
39
|
-
"@atlaskit/icon": "^37.
|
|
39
|
+
"@atlaskit/icon": "^37.2.0",
|
|
40
40
|
"@atlaskit/icon-lab": "^7.4.0",
|
|
41
41
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
42
42
|
"@atlaskit/primitives": "^22.2.0",
|
|
43
43
|
"@atlaskit/prosemirror-history": "^1.0.0",
|
|
44
44
|
"@atlaskit/prosemirror-input-rules": "^4.0.0",
|
|
45
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
45
|
+
"@atlaskit/tmp-editor-statsig": "^134.0.0",
|
|
46
46
|
"@atlaskit/tokens": "^16.3.0",
|
|
47
47
|
"@babel/runtime": "^7.0.0",
|
|
48
48
|
"@compiled/react": "^1.0.0",
|
|
49
49
|
"@emotion/react": "^11.7.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@atlaskit/editor-common": "^116.
|
|
52
|
+
"@atlaskit/editor-common": "^116.40.0",
|
|
53
53
|
"react": "^18.2.0",
|
|
54
54
|
"react-dom": "^18.2.0",
|
|
55
55
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|