@atlaskit/editor-core 159.0.1 → 162.0.0
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 +56 -0
- package/dist/cjs/actions/index.js +76 -48
- package/dist/cjs/extensibility.js +2 -2
- package/dist/cjs/labs/next/full-page.js +1 -1
- package/dist/cjs/plugins/block-type/styles.js +5 -2
- package/dist/cjs/plugins/block-type/ui/ToolbarBlockType/index.js +13 -11
- package/dist/cjs/plugins/block-type/ui/ToolbarBlockType/styled.js +11 -7
- package/dist/cjs/plugins/card/messages.js +4 -4
- package/dist/cjs/plugins/card/ui/LinkToolbarAppearance.js +29 -11
- package/dist/cjs/plugins/card/ui/LinkToolbarButtonGroup.js +66 -7
- package/dist/cjs/plugins/card/ui/LinkToolbarIconDropdown.js +166 -7
- package/dist/cjs/plugins/card/ui/ResizableEmbedCard.js +9 -6
- package/dist/cjs/plugins/card/ui/assets/card.js +1 -1
- package/dist/cjs/plugins/card/ui/assets/embed.js +1 -1
- package/dist/cjs/plugins/card/ui/assets/inline.js +1 -1
- package/dist/cjs/plugins/card/ui/assets/url.js +1 -1
- package/dist/cjs/plugins/card/ui/link-toolbar-button-group-options.js +60 -0
- package/dist/cjs/plugins/card/ui/link-toolbar-icon-dropdown-options.js +66 -0
- package/dist/cjs/plugins/card/ui/styled.js +5 -13
- package/dist/cjs/plugins/card/ui/types.js +5 -0
- package/dist/cjs/plugins/clipboard/pm-plugins/main.js +99 -3
- package/dist/cjs/plugins/code-block/styles.js +45 -38
- package/dist/cjs/plugins/extension/plugin-factory.js +4 -1
- package/dist/cjs/plugins/extension/pm-plugins/main.js +34 -11
- package/dist/cjs/plugins/extension/utils.js +57 -12
- package/dist/cjs/plugins/find-replace/ui/Find.js +12 -12
- package/dist/cjs/plugins/find-replace/ui/FindReplace.js +5 -5
- package/dist/cjs/plugins/find-replace/ui/Replace.js +5 -5
- package/dist/cjs/plugins/find-replace/ui/styles.js +12 -15
- package/dist/cjs/plugins/layout/styles.js +2 -2
- package/dist/cjs/plugins/list/actions/wrap-and-join-lists.js +180 -0
- package/dist/cjs/plugins/list/commands/index.js +35 -38
- package/dist/cjs/plugins/list/utils/replace-content.js +31 -0
- package/dist/cjs/plugins/media/nodeviews/mediaNodeUpdater.js +3 -3
- package/dist/cjs/plugins/media/styles.js +2 -2
- package/dist/cjs/plugins/media/utils/media-single.js +15 -2
- package/dist/cjs/plugins/paste/handlers.js +19 -5
- package/dist/cjs/plugins/paste/pm-plugins/analytics.js +1 -1
- package/dist/cjs/plugins/placeholder-text/index.js +45 -1
- package/dist/cjs/plugins/placeholder-text/placeholder-text-nodeview.js +66 -22
- package/dist/cjs/plugins/placeholder-text/selection-utils.js +19 -0
- package/dist/cjs/plugins/placeholder-text/styles.js +3 -1
- package/dist/cjs/plugins/table/commands/index.js +0 -6
- package/dist/cjs/plugins/table/commands/insert.js +1 -1
- package/dist/cjs/plugins/table/commands/misc.js +5 -18
- package/dist/cjs/plugins/table/commands-with-analytics.js +1 -1
- package/dist/cjs/plugins/table/handlers.js +6 -2
- package/dist/cjs/plugins/table/index.js +7 -13
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +2 -2
- package/dist/cjs/plugins/table/nodeviews/table.js +7 -38
- package/dist/cjs/plugins/table/pm-plugins/decorations/plugin.js +2 -2
- package/dist/cjs/plugins/table/pm-plugins/main.js +3 -1
- package/dist/cjs/plugins/table/pm-plugins/plugin-factory.js +4 -7
- package/dist/cjs/plugins/table/pm-plugins/plugin-key.js +11 -0
- package/dist/cjs/plugins/table/pm-plugins/safari-delayed-dom-selection-syncing-workaround.js +2 -0
- package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +3 -3
- package/dist/cjs/plugins/table/reducer.js +0 -7
- package/dist/cjs/plugins/table/toolbar.js +5 -15
- package/dist/cjs/plugins/table/transforms/metadata.js +2 -2
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/index.js +3 -1
- package/dist/cjs/plugins/table/ui/FloatingInsertButton/index.js +1 -1
- package/dist/cjs/plugins/table/ui/LayoutButton/index.js +47 -8
- package/dist/cjs/plugins/table/ui/common-styles.css.js +17 -8
- package/dist/cjs/plugins/table/ui/ui-styles.css.js +39 -25
- package/dist/cjs/plugins/table/utils/nodes.js +15 -15
- package/dist/cjs/plugins/tasks-and-decisions/commands.js +15 -1
- package/dist/cjs/plugins/text-formatting/styles.js +5 -2
- package/dist/cjs/plugins/text-formatting/ui/Toolbar/index.js +71 -1
- package/dist/cjs/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +30 -0
- package/dist/cjs/plugins/text-formatting/utils.js +30 -2
- package/dist/cjs/plugins/type-ahead/api.js +32 -1
- package/dist/cjs/plugins/type-ahead/transforms/open-typeahead-at-cursor.js +20 -5
- package/dist/cjs/plugins/type-ahead/utils.js +22 -4
- package/dist/cjs/ui/Appearance/Comment/Comment.js +1 -1
- package/dist/cjs/ui/Appearance/FullPage/StyledComponents.js +1 -1
- package/dist/cjs/ui/ContentStyles/index.js +32 -9
- package/dist/cjs/utils/index.js +1 -8
- package/dist/cjs/utils/insert.js +1 -9
- package/dist/cjs/utils/selection.js +2 -9
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/actions/index.js +20 -23
- package/dist/es2019/extensibility.js +1 -1
- package/dist/es2019/labs/next/full-page.js +2 -2
- package/dist/es2019/plugins/block-type/styles.js +3 -3
- package/dist/es2019/plugins/block-type/ui/ToolbarBlockType/index.js +15 -12
- package/dist/es2019/plugins/block-type/ui/ToolbarBlockType/styled.js +19 -14
- package/dist/es2019/plugins/card/messages.js +4 -4
- package/dist/es2019/plugins/card/ui/LinkToolbarAppearance.js +21 -9
- package/dist/es2019/plugins/card/ui/LinkToolbarButtonGroup.js +54 -3
- package/dist/es2019/plugins/card/ui/LinkToolbarIconDropdown.js +145 -3
- package/dist/es2019/plugins/card/ui/ResizableEmbedCard.js +10 -6
- package/dist/es2019/plugins/card/ui/assets/card.js +1 -1
- package/dist/es2019/plugins/card/ui/assets/embed.js +1 -1
- package/dist/es2019/plugins/card/ui/assets/inline.js +1 -1
- package/dist/es2019/plugins/card/ui/assets/url.js +1 -1
- package/dist/es2019/plugins/card/ui/link-toolbar-button-group-options.js +45 -0
- package/dist/es2019/plugins/card/ui/link-toolbar-icon-dropdown-options.js +51 -0
- package/dist/es2019/plugins/card/ui/styled.js +2 -2
- package/dist/es2019/plugins/card/ui/types.js +1 -0
- package/dist/es2019/plugins/clipboard/pm-plugins/main.js +91 -9
- package/dist/es2019/plugins/code-block/styles.js +14 -14
- package/dist/es2019/plugins/extension/plugin-factory.js +3 -1
- package/dist/es2019/plugins/extension/pm-plugins/main.js +38 -12
- package/dist/es2019/plugins/extension/utils.js +37 -2
- package/dist/es2019/plugins/find-replace/ui/Find.js +1 -1
- package/dist/es2019/plugins/find-replace/ui/FindReplace.js +1 -1
- package/dist/es2019/plugins/find-replace/ui/Replace.js +1 -1
- package/dist/es2019/plugins/find-replace/ui/styles.js +14 -9
- package/dist/es2019/plugins/layout/styles.js +5 -1
- package/dist/es2019/plugins/list/actions/wrap-and-join-lists.js +163 -0
- package/dist/es2019/plugins/list/commands/index.js +29 -28
- package/dist/es2019/plugins/list/utils/replace-content.js +22 -0
- package/dist/es2019/plugins/media/nodeviews/mediaNodeUpdater.js +3 -3
- package/dist/es2019/plugins/media/styles.js +1 -1
- package/dist/es2019/plugins/media/utils/media-single.js +14 -1
- package/dist/es2019/plugins/paste/handlers.js +19 -5
- package/dist/es2019/plugins/paste/pm-plugins/analytics.js +2 -2
- package/dist/es2019/plugins/placeholder-text/index.js +46 -1
- package/dist/es2019/plugins/placeholder-text/placeholder-text-nodeview.js +66 -20
- package/dist/es2019/plugins/placeholder-text/selection-utils.js +9 -0
- package/dist/es2019/plugins/placeholder-text/styles.js +22 -0
- package/dist/es2019/plugins/table/commands/index.js +1 -1
- package/dist/es2019/plugins/table/commands/insert.js +1 -1
- package/dist/es2019/plugins/table/commands/misc.js +5 -11
- package/dist/es2019/plugins/table/commands-with-analytics.js +1 -1
- package/dist/es2019/plugins/table/handlers.js +6 -2
- package/dist/es2019/plugins/table/index.js +4 -8
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +2 -2
- package/dist/es2019/plugins/table/nodeviews/table.js +2 -16
- package/dist/es2019/plugins/table/pm-plugins/decorations/plugin.js +1 -1
- package/dist/es2019/plugins/table/pm-plugins/main.js +2 -1
- package/dist/es2019/plugins/table/pm-plugins/plugin-factory.js +1 -2
- package/dist/es2019/plugins/table/pm-plugins/plugin-key.js +2 -0
- package/dist/es2019/plugins/table/pm-plugins/safari-delayed-dom-selection-syncing-workaround.js +2 -0
- package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +1 -1
- package/dist/es2019/plugins/table/reducer.js +0 -9
- package/dist/es2019/plugins/table/toolbar.js +1 -4
- package/dist/es2019/plugins/table/transforms/metadata.js +1 -1
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/index.js +2 -1
- package/dist/es2019/plugins/table/ui/FloatingInsertButton/index.js +1 -1
- package/dist/es2019/plugins/table/ui/LayoutButton/index.js +41 -8
- package/dist/es2019/plugins/table/ui/common-styles.css.js +51 -26
- package/dist/es2019/plugins/table/ui/ui-styles.css.js +57 -56
- package/dist/es2019/plugins/table/utils/nodes.js +11 -11
- package/dist/es2019/plugins/tasks-and-decisions/commands.js +13 -1
- package/dist/es2019/plugins/text-formatting/styles.js +3 -3
- package/dist/es2019/plugins/text-formatting/ui/Toolbar/index.js +61 -2
- package/dist/es2019/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +30 -0
- package/dist/es2019/plugins/text-formatting/utils.js +13 -1
- package/dist/es2019/plugins/type-ahead/api.js +31 -2
- package/dist/es2019/plugins/type-ahead/transforms/open-typeahead-at-cursor.js +17 -5
- package/dist/es2019/plugins/type-ahead/utils.js +15 -0
- package/dist/es2019/ui/Appearance/Comment/Comment.js +2 -2
- package/dist/es2019/ui/Appearance/FullPage/StyledComponents.js +2 -2
- package/dist/es2019/ui/ContentStyles/index.js +45 -23
- package/dist/es2019/utils/index.js +1 -1
- package/dist/es2019/utils/insert.js +2 -10
- package/dist/es2019/utils/selection.js +1 -6
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/actions/index.js +76 -48
- package/dist/esm/extensibility.js +1 -1
- package/dist/esm/labs/next/full-page.js +2 -2
- package/dist/esm/plugins/block-type/styles.js +4 -2
- package/dist/esm/plugins/block-type/ui/ToolbarBlockType/index.js +14 -12
- package/dist/esm/plugins/block-type/ui/ToolbarBlockType/styled.js +9 -5
- package/dist/esm/plugins/card/messages.js +4 -4
- package/dist/esm/plugins/card/ui/LinkToolbarAppearance.js +25 -9
- package/dist/esm/plugins/card/ui/LinkToolbarButtonGroup.js +57 -5
- package/dist/esm/plugins/card/ui/LinkToolbarIconDropdown.js +154 -5
- package/dist/esm/plugins/card/ui/ResizableEmbedCard.js +9 -6
- package/dist/esm/plugins/card/ui/assets/card.js +1 -1
- package/dist/esm/plugins/card/ui/assets/embed.js +1 -1
- package/dist/esm/plugins/card/ui/assets/inline.js +1 -1
- package/dist/esm/plugins/card/ui/assets/url.js +1 -1
- package/dist/esm/plugins/card/ui/link-toolbar-button-group-options.js +45 -0
- package/dist/esm/plugins/card/ui/link-toolbar-icon-dropdown-options.js +51 -0
- package/dist/esm/plugins/card/ui/styled.js +2 -2
- package/dist/esm/plugins/card/ui/types.js +1 -0
- package/dist/esm/plugins/clipboard/pm-plugins/main.js +91 -2
- package/dist/esm/plugins/code-block/styles.js +42 -38
- package/dist/esm/plugins/extension/plugin-factory.js +3 -1
- package/dist/esm/plugins/extension/pm-plugins/main.js +34 -11
- package/dist/esm/plugins/extension/utils.js +51 -9
- package/dist/esm/plugins/find-replace/ui/Find.js +1 -1
- package/dist/esm/plugins/find-replace/ui/FindReplace.js +1 -1
- package/dist/esm/plugins/find-replace/ui/Replace.js +1 -1
- package/dist/esm/plugins/find-replace/ui/styles.js +6 -10
- package/dist/esm/plugins/layout/styles.js +2 -2
- package/dist/esm/plugins/list/actions/wrap-and-join-lists.js +168 -0
- package/dist/esm/plugins/list/commands/index.js +33 -34
- package/dist/esm/plugins/list/utils/replace-content.js +21 -0
- package/dist/esm/plugins/media/nodeviews/mediaNodeUpdater.js +3 -3
- package/dist/esm/plugins/media/styles.js +1 -1
- package/dist/esm/plugins/media/utils/media-single.js +12 -1
- package/dist/esm/plugins/paste/handlers.js +19 -5
- package/dist/esm/plugins/paste/pm-plugins/analytics.js +2 -2
- package/dist/esm/plugins/placeholder-text/index.js +44 -1
- package/dist/esm/plugins/placeholder-text/placeholder-text-nodeview.js +67 -20
- package/dist/esm/plugins/placeholder-text/selection-utils.js +9 -0
- package/dist/esm/plugins/placeholder-text/styles.js +2 -1
- package/dist/esm/plugins/table/commands/index.js +1 -1
- package/dist/esm/plugins/table/commands/insert.js +1 -1
- package/dist/esm/plugins/table/commands/misc.js +5 -15
- package/dist/esm/plugins/table/commands-with-analytics.js +1 -1
- package/dist/esm/plugins/table/handlers.js +6 -2
- package/dist/esm/plugins/table/index.js +6 -11
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +2 -2
- package/dist/esm/plugins/table/nodeviews/table.js +6 -37
- package/dist/esm/plugins/table/pm-plugins/decorations/plugin.js +1 -1
- package/dist/esm/plugins/table/pm-plugins/main.js +2 -1
- package/dist/esm/plugins/table/pm-plugins/plugin-factory.js +1 -2
- package/dist/esm/plugins/table/pm-plugins/plugin-key.js +2 -0
- package/dist/esm/plugins/table/pm-plugins/safari-delayed-dom-selection-syncing-workaround.js +2 -0
- package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +1 -1
- package/dist/esm/plugins/table/reducer.js +0 -7
- package/dist/esm/plugins/table/toolbar.js +1 -10
- package/dist/esm/plugins/table/transforms/metadata.js +1 -1
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/index.js +2 -1
- package/dist/esm/plugins/table/ui/FloatingInsertButton/index.js +1 -1
- package/dist/esm/plugins/table/ui/LayoutButton/index.js +43 -8
- package/dist/esm/plugins/table/ui/common-styles.css.js +10 -6
- package/dist/esm/plugins/table/ui/ui-styles.css.js +20 -11
- package/dist/esm/plugins/table/utils/nodes.js +14 -14
- package/dist/esm/plugins/tasks-and-decisions/commands.js +13 -1
- package/dist/esm/plugins/text-formatting/styles.js +4 -2
- package/dist/esm/plugins/text-formatting/ui/Toolbar/index.js +69 -2
- package/dist/esm/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +30 -0
- package/dist/esm/plugins/text-formatting/utils.js +18 -0
- package/dist/esm/plugins/type-ahead/api.js +30 -2
- package/dist/esm/plugins/type-ahead/transforms/open-typeahead-at-cursor.js +16 -4
- package/dist/esm/plugins/type-ahead/utils.js +17 -3
- package/dist/esm/ui/Appearance/Comment/Comment.js +2 -2
- package/dist/esm/ui/Appearance/FullPage/StyledComponents.js +2 -2
- package/dist/esm/ui/ContentStyles/index.js +27 -9
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/utils/insert.js +2 -10
- package/dist/esm/utils/selection.js +1 -6
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/actions/index.d.ts +2 -2
- package/dist/types/extensibility.d.ts +1 -1
- package/dist/types/plugins/analytics/types/list-events.d.ts +0 -1
- package/dist/types/plugins/block-type/styles.d.ts +2 -1
- package/dist/types/plugins/block-type/ui/ToolbarBlockType/index.d.ts +1 -0
- package/dist/types/plugins/block-type/ui/ToolbarBlockType/styled.d.ts +2 -7
- package/dist/types/plugins/card/messages.d.ts +2 -2
- package/dist/types/plugins/card/ui/LinkToolbarButtonGroup.d.ts +18 -2
- package/dist/types/plugins/card/ui/LinkToolbarIconDropdown.d.ts +23 -3
- package/dist/types/plugins/card/ui/ResizableEmbedCard.d.ts +3 -1
- package/dist/types/plugins/card/ui/link-toolbar-button-group-options.d.ts +5 -0
- package/dist/types/plugins/card/ui/link-toolbar-icon-dropdown-options.d.ts +5 -0
- package/dist/types/plugins/card/ui/styled.d.ts +2 -3
- package/dist/types/plugins/card/ui/types.d.ts +12 -0
- package/dist/types/plugins/clipboard/pm-plugins/main.d.ts +10 -1
- package/dist/types/plugins/code-block/styles.d.ts +3 -2
- package/dist/types/plugins/extension/pm-plugins/main.d.ts +2 -1
- package/dist/types/plugins/extension/types.d.ts +1 -0
- package/dist/types/plugins/extension/utils.d.ts +3 -1
- package/dist/types/plugins/find-replace/ui/FindReplace.d.ts +2 -1
- package/dist/types/plugins/find-replace/ui/styles.d.ts +5 -5
- package/dist/types/plugins/layout/styles.d.ts +1 -1
- package/dist/types/plugins/list/actions/wrap-and-join-lists.d.ts +25 -0
- package/dist/types/plugins/list/commands/index.d.ts +0 -1
- package/dist/types/plugins/list/utils/replace-content.d.ts +8 -0
- package/dist/types/plugins/media/nodeviews/mediaNodeUpdater.d.ts +2 -2
- package/dist/types/plugins/media/styles.d.ts +1 -1
- package/dist/types/plugins/media/utils/media-single.d.ts +1 -0
- package/dist/types/plugins/panel/styles.d.ts +1 -1
- package/dist/types/plugins/paste/handlers.d.ts +1 -1
- package/dist/types/plugins/placeholder-text/placeholder-text-nodeview.d.ts +3 -2
- package/dist/types/plugins/placeholder-text/selection-utils.d.ts +2 -0
- package/dist/types/plugins/rule/styles.d.ts +1 -1
- package/dist/types/plugins/table/commands/index.d.ts +1 -1
- package/dist/types/plugins/table/commands/misc.d.ts +0 -1
- package/dist/types/plugins/table/nodeviews/table.d.ts +0 -1
- package/dist/types/plugins/table/pm-plugins/plugin-factory.d.ts +1 -4
- package/dist/types/plugins/table/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types/plugins/table/types.d.ts +1 -8
- package/dist/types/plugins/table/ui/LayoutButton/index.d.ts +0 -1
- package/dist/types/plugins/table/ui/common-styles.css.d.ts +6 -3
- package/dist/types/plugins/table/ui/ui-styles.css.d.ts +15 -14
- package/dist/types/plugins/table/utils/nodes.d.ts +6 -6
- package/dist/types/plugins/text-formatting/pm-plugins/smart-input-rule.d.ts +1 -1
- package/dist/types/plugins/text-formatting/styles.d.ts +2 -1
- package/dist/types/plugins/text-formatting/ui/Toolbar/toolbar-messages.d.ts +30 -0
- package/dist/types/plugins/text-formatting/utils.d.ts +4 -0
- package/dist/types/plugins/type-ahead/api.d.ts +11 -1
- package/dist/types/plugins/type-ahead/transforms/open-typeahead-at-cursor.d.ts +1 -0
- package/dist/types/plugins/type-ahead/utils.d.ts +4 -0
- package/dist/types/ui/ContentStyles/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types/utils/selection.d.ts +0 -1
- package/package.json +28 -26
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Fragment, Slice, NodeRange } from 'prosemirror-model';
|
|
2
|
+
import { ReplaceAroundStep, findWrapping, canSplit, canJoin } from 'prosemirror-transform';
|
|
3
|
+
/**
|
|
4
|
+
* Wraps the selection in a list with the given type. If this results in
|
|
5
|
+
* two adjacent lists of the same type, those will be joined together.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export function wrapInListAndJoin(nodeType, tr) {
|
|
9
|
+
wrapInList(nodeType)(tr);
|
|
10
|
+
autoJoin(tr, (before, after) => before.type === after.type && before.type === nodeType);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Wraps the selection in a list with the given type and attributes.
|
|
14
|
+
*
|
|
15
|
+
* Adapted from https://github.com/ProseMirror/prosemirror-schema-list/blob/master/src/schema-list.js#L64-L89
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export function wrapInList(listType, attrs) {
|
|
19
|
+
return function (tr) {
|
|
20
|
+
const {
|
|
21
|
+
$from,
|
|
22
|
+
$to
|
|
23
|
+
} = tr.selection;
|
|
24
|
+
let range = $from.blockRange($to);
|
|
25
|
+
let doJoin = false;
|
|
26
|
+
let outerRange = range;
|
|
27
|
+
|
|
28
|
+
if (!range) {
|
|
29
|
+
return false;
|
|
30
|
+
} // This is at the top of an existing list item
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if (range.depth >= 2 && // @ts-ignore - missing type for compatibleContent
|
|
34
|
+
$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex === 0) {
|
|
35
|
+
// Don't do anything if this is the top of the list
|
|
36
|
+
if ($from.index(range.depth - 1) === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let $insert = tr.doc.resolve(range.start - 2);
|
|
41
|
+
outerRange = new NodeRange($insert, $insert, range.depth);
|
|
42
|
+
|
|
43
|
+
if (range.endIndex < range.parent.childCount) {
|
|
44
|
+
range = new NodeRange($from, tr.doc.resolve($to.end(range.depth)), range.depth);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
doJoin = true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let wrap = findWrapping(outerRange, listType, attrs, range);
|
|
51
|
+
|
|
52
|
+
if (!wrap) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
tr = doWrapInList(tr, range, wrap, doJoin, listType);
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Internal function used by wrapInList
|
|
62
|
+
*
|
|
63
|
+
* Adapted from https://github.com/ProseMirror/prosemirror-schema-list/blob/master/src/schema-list.js#L91-L112
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
function doWrapInList(tr, range, wrappers, joinBefore, listType) {
|
|
67
|
+
let content = Fragment.empty;
|
|
68
|
+
|
|
69
|
+
for (let i = wrappers.length - 1; i >= 0; i--) {
|
|
70
|
+
content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
tr.step(new ReplaceAroundStep(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end, new Slice(content, 0, 0), wrappers.length, true));
|
|
74
|
+
let found = 0;
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < wrappers.length; i++) {
|
|
77
|
+
if (wrappers[i].type === listType) {
|
|
78
|
+
found = i + 1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const splitDepth = wrappers.length - found;
|
|
83
|
+
let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0);
|
|
84
|
+
const parent = range.parent;
|
|
85
|
+
|
|
86
|
+
for (let i = range.startIndex, e = range.endIndex, first = true; i < e; i++, first = false) {
|
|
87
|
+
if (!first && canSplit(tr.doc, splitPos, splitDepth)) {
|
|
88
|
+
tr.split(splitPos, splitDepth);
|
|
89
|
+
splitPos += 2 * splitDepth;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
splitPos += parent.child(i).nodeSize;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return tr;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Checks whether two adjacent nodes can be joined. If so, the document
|
|
99
|
+
* will be updated to join those nodes. If not, the original transaction
|
|
100
|
+
* remains untouched.
|
|
101
|
+
*
|
|
102
|
+
* Nodes are considered joinable if the `isJoinable` predicate returns true.
|
|
103
|
+
*
|
|
104
|
+
* Adapted from https://github.com/ProseMirror/prosemirror-commands/blob/master/src/commands.js#L597-L610
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
export function autoJoin(tr, isJoinable) {
|
|
109
|
+
if (!tr.isGeneric) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const ranges = [];
|
|
114
|
+
|
|
115
|
+
for (let i = 0; i < tr.mapping.maps.length; i++) {
|
|
116
|
+
const map = tr.mapping.maps[i];
|
|
117
|
+
|
|
118
|
+
for (let j = 0; j < ranges.length; j++) {
|
|
119
|
+
ranges[j] = map.map(ranges[j]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
map.forEach((_s, _e, from, to) => ranges.push(from, to));
|
|
123
|
+
} // Figure out which joinable points exist inside those ranges,
|
|
124
|
+
// by checking all node boundaries in their parent nodes.
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
const joinable = [];
|
|
128
|
+
|
|
129
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
130
|
+
const from = ranges[i];
|
|
131
|
+
const to = ranges[i + 1];
|
|
132
|
+
const $from = tr.doc.resolve(from);
|
|
133
|
+
const depth = $from.sharedDepth(to);
|
|
134
|
+
const parent = $from.node(depth);
|
|
135
|
+
|
|
136
|
+
for (let index = $from.indexAfter(depth), pos = $from.after(depth + 1); pos <= to; ++index) {
|
|
137
|
+
const after = parent.maybeChild(index);
|
|
138
|
+
|
|
139
|
+
if (!after) {
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (index && joinable.indexOf(pos) === -1) {
|
|
144
|
+
const before = parent.child(index - 1);
|
|
145
|
+
|
|
146
|
+
if (before.type === after.type && isJoinable(before, after)) {
|
|
147
|
+
joinable.push(pos);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
pos += after.nodeSize;
|
|
152
|
+
}
|
|
153
|
+
} // Join the joinable points
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
joinable.sort((a, b) => a - b);
|
|
157
|
+
|
|
158
|
+
for (let i = joinable.length - 1; i >= 0; i--) {
|
|
159
|
+
if (canJoin(tr.doc, joinable[i])) {
|
|
160
|
+
tr.join(joinable[i]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { Fragment, Slice } from 'prosemirror-model';
|
|
2
|
-
import { ReplaceAroundStep } from 'prosemirror-transform';
|
|
3
2
|
import * as baseCommand from 'prosemirror-commands';
|
|
4
|
-
import * as baseListCommand from 'prosemirror-schema-list';
|
|
5
3
|
import { hasParentNodeOfType, findPositionOfNodeBefore } from 'prosemirror-utils';
|
|
6
4
|
import { hasVisibleContent, isNodeEmpty } from '../../../utils/document';
|
|
7
5
|
import { findCutBefore, isEmptySelectionAtStart, isFirstChildOfParent, filter } from '../../../utils/commands';
|
|
@@ -14,8 +12,10 @@ import { getCommonListAnalyticsAttributes } from '../utils/analytics';
|
|
|
14
12
|
import { listBackspace } from './listBackspace';
|
|
15
13
|
import { joinListItemForward } from './join-list-item-forward';
|
|
16
14
|
import { convertListType } from '../actions/conversions';
|
|
15
|
+
import { wrapInListAndJoin } from '../actions/wrap-and-join-lists';
|
|
17
16
|
import { outdentList } from './outdent-list';
|
|
18
17
|
import { indentList } from './indent-list';
|
|
18
|
+
import { moveTargetIntoList } from '../utils/replace-content';
|
|
19
19
|
export { outdentList, indentList };
|
|
20
20
|
export const enterKeyCommand = (state, dispatch) => {
|
|
21
21
|
const {
|
|
@@ -91,8 +91,8 @@ function untoggleSelectedList(tr) {
|
|
|
91
91
|
|
|
92
92
|
export function toggleList(inputMethod, listType) {
|
|
93
93
|
return function (state, dispatch) {
|
|
94
|
-
let
|
|
95
|
-
const listInsideSelection = selectionContainsList(
|
|
94
|
+
let tr = state.tr;
|
|
95
|
+
const listInsideSelection = selectionContainsList(tr);
|
|
96
96
|
const listNodeType = state.schema.nodes[listType];
|
|
97
97
|
const actionSubjectId = listType === 'bulletList' ? ACTION_SUBJECT_ID.FORMAT_LIST_BULLET : ACTION_SUBJECT_ID.FORMAT_LIST_NUMBER;
|
|
98
98
|
|
|
@@ -126,10 +126,10 @@ export function toggleList(inputMethod, listType) {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
convertListType({
|
|
129
|
-
tr
|
|
129
|
+
tr,
|
|
130
130
|
nextListNodeType: listNodeType
|
|
131
131
|
});
|
|
132
|
-
addAnalytics(state,
|
|
132
|
+
addAnalytics(state, tr, {
|
|
133
133
|
action: ACTION.CONVERTED,
|
|
134
134
|
actionSubject: ACTION_SUBJECT.LIST,
|
|
135
135
|
actionSubjectId,
|
|
@@ -140,17 +140,11 @@ export function toggleList(inputMethod, listType) {
|
|
|
140
140
|
}
|
|
141
141
|
});
|
|
142
142
|
} else {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// until after wrapInList, since any changes made to it will be discarded when it
|
|
149
|
-
// gets replaced with the transaction generated by wrapInList.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
wrapInList(listNodeType)(state, replaceCurrentTr);
|
|
153
|
-
addAnalytics(state, customTr, {
|
|
143
|
+
// Need to have this before wrapInList so the wrapping is done with valid content
|
|
144
|
+
// For example, if trying to convert centre or right aligned paragraphs to lists
|
|
145
|
+
sanitiseMarksInSelection(tr, listNodeType);
|
|
146
|
+
wrapInListAndJoin(listNodeType, tr);
|
|
147
|
+
addAnalytics(state, tr, {
|
|
154
148
|
action: ACTION.INSERTED,
|
|
155
149
|
actionSubject: ACTION_SUBJECT.LIST,
|
|
156
150
|
actionSubjectId,
|
|
@@ -159,18 +153,16 @@ export function toggleList(inputMethod, listType) {
|
|
|
159
153
|
inputMethod
|
|
160
154
|
}
|
|
161
155
|
});
|
|
162
|
-
} //
|
|
163
|
-
//
|
|
156
|
+
} // If document wasn't changed, return false from the command to indicate that the
|
|
157
|
+
// editing action failed
|
|
164
158
|
|
|
165
159
|
|
|
166
|
-
if (!
|
|
160
|
+
if (!tr.docChanged) {
|
|
167
161
|
return false;
|
|
168
162
|
}
|
|
169
163
|
|
|
170
|
-
sanitiseMarksInSelection(customTr, listNodeType);
|
|
171
|
-
|
|
172
164
|
if (dispatch) {
|
|
173
|
-
dispatch(
|
|
165
|
+
dispatch(tr);
|
|
174
166
|
}
|
|
175
167
|
|
|
176
168
|
return true;
|
|
@@ -182,9 +174,6 @@ export function toggleBulletList(view, inputMethod = INPUT_METHOD.TOOLBAR) {
|
|
|
182
174
|
export function toggleOrderedList(view, inputMethod = INPUT_METHOD.TOOLBAR) {
|
|
183
175
|
return toggleList(inputMethod, 'orderedList')(view.state, view.dispatch);
|
|
184
176
|
}
|
|
185
|
-
export function wrapInList(nodeType) {
|
|
186
|
-
return baseCommand.autoJoin(baseListCommand.wrapInList(nodeType), (before, after) => before.type === after.type && before.type === nodeType);
|
|
187
|
-
}
|
|
188
177
|
/**
|
|
189
178
|
* Implementation taken and modified for our needs from PM
|
|
190
179
|
* @param itemType Node
|
|
@@ -326,8 +315,20 @@ const joinToPreviousListItem = (state, dispatch) => {
|
|
|
326
315
|
const list = $cut.nodeBefore.copy($cut.nodeBefore.content.append(Fragment.from(listItem.createChecked({}, $cut.nodeAfter))));
|
|
327
316
|
tr.replaceWith(nodeBeforePos, $from.pos + $cut.nodeAfter.nodeSize, list);
|
|
328
317
|
} else {
|
|
329
|
-
|
|
330
|
-
|
|
318
|
+
const step = moveTargetIntoList({
|
|
319
|
+
insertPosition: $lastNode.pos,
|
|
320
|
+
$target: $cut
|
|
321
|
+
}); // ED-13966: check if the step will cause an ProseMirror error
|
|
322
|
+
// if there's an error don't apply the step as it will might lead into a data loss.
|
|
323
|
+
// It doesn't play well with media being a leaf node.
|
|
324
|
+
|
|
325
|
+
const stepResult = state.tr.maybeStep(step);
|
|
326
|
+
|
|
327
|
+
if (stepResult.failed) {
|
|
328
|
+
return false;
|
|
329
|
+
} else {
|
|
330
|
+
tr = state.tr.step(step);
|
|
331
|
+
}
|
|
331
332
|
} // find out if there's now another list following and join them
|
|
332
333
|
// as in, [list, p, list] => [list with p, list], and we want [joined list]
|
|
333
334
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReplaceAroundStep, ReplaceStep } from 'prosemirror-transform';
|
|
2
|
+
export const moveTargetIntoList = ({
|
|
3
|
+
insertPosition,
|
|
4
|
+
$target
|
|
5
|
+
}) => {
|
|
6
|
+
var _$target$nodeAfter;
|
|
7
|
+
|
|
8
|
+
// take the text content of the paragraph and insert after the paragraph up until before the the cut
|
|
9
|
+
const from = insertPosition;
|
|
10
|
+
const to = $target.pos + (((_$target$nodeAfter = $target.nodeAfter) === null || _$target$nodeAfter === void 0 ? void 0 : _$target$nodeAfter.nodeSize) || 0); //$cut.pos + $cut.nodeAfter.nodeSize;
|
|
11
|
+
|
|
12
|
+
const gapFrom = $target.posAtIndex(0, $target.depth + 1); // start pos of the child
|
|
13
|
+
|
|
14
|
+
const gapTo = $target.doc.resolve(gapFrom).end(); // end pos of the paragraph
|
|
15
|
+
|
|
16
|
+
if (gapTo - gapFrom === 0) {
|
|
17
|
+
return new ReplaceStep(from, to, $target.doc.slice(insertPosition, $target.pos));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const step = new ReplaceAroundStep(from, to, gapFrom, gapTo, $target.doc.slice(insertPosition, $target.pos), 0, true);
|
|
21
|
+
return step;
|
|
22
|
+
};
|
|
@@ -86,7 +86,7 @@ export class MediaNodeUpdater {
|
|
|
86
86
|
|
|
87
87
|
_defineProperty(this, "getObjectId", async () => {
|
|
88
88
|
const contextIdentifierProvider = await this.props.contextIdentifierProvider;
|
|
89
|
-
return contextIdentifierProvider
|
|
89
|
+
return (contextIdentifierProvider === null || contextIdentifierProvider === void 0 ? void 0 : contextIdentifierProvider.objectId) || null;
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
_defineProperty(this, "uploadExternalMedia", async getPos => {
|
|
@@ -135,10 +135,10 @@ export class MediaNodeUpdater {
|
|
|
135
135
|
const attrs = this.getAttrs();
|
|
136
136
|
|
|
137
137
|
if (!attrs || attrs.type !== 'file') {
|
|
138
|
-
return
|
|
138
|
+
return null;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
return attrs.__contextId;
|
|
141
|
+
return attrs.__contextId || null;
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
_defineProperty(this, "updateDimensions", dimensions => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css } from '
|
|
1
|
+
import { css } from '@emotion/react';
|
|
2
2
|
import { mediaSingleSharedStyle, richMediaClassName } from '@atlaskit/editor-common/styles';
|
|
3
3
|
import { akEditorDeleteBorder, akEditorDeleteBackground, akEditorSelectedBorderBoldSize, akEditorMediaResizeHandlerPaddingWide, akEditorMediaResizeHandlerPadding, akEditorSelectedNodeClassName, akEditorDeleteIconColor } from '@atlaskit/editor-shared-styles';
|
|
4
4
|
import { N60, B200 } from '@atlaskit/theme/colors';
|
|
@@ -252,4 +252,17 @@ export const calcMediaPxWidth = opts => {
|
|
|
252
252
|
return origWidth;
|
|
253
253
|
};
|
|
254
254
|
|
|
255
|
-
const calcPctWidth = (containerWidth, pctWidth, origWidth, origHeight) => pctWidth && origWidth && origHeight && Math.ceil(calcPxFromPct(pctWidth / 100, containerWidth.lineLength || containerWidth.width));
|
|
255
|
+
const calcPctWidth = (containerWidth, pctWidth, origWidth, origHeight) => pctWidth && origWidth && origHeight && Math.ceil(calcPxFromPct(pctWidth / 100, containerWidth.lineLength || containerWidth.width));
|
|
256
|
+
|
|
257
|
+
export function isCaptionNode(editorView) {
|
|
258
|
+
const {
|
|
259
|
+
$from
|
|
260
|
+
} = editorView.state.selection;
|
|
261
|
+
const immediateWrapperParentNode = editorView.state.doc.nodeAt($from.before(Math.max($from.depth, 1)));
|
|
262
|
+
|
|
263
|
+
if (immediateWrapperParentNode && immediateWrapperParentNode.type.name === 'caption') {
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { closeHistory } from 'prosemirror-history';
|
|
2
2
|
import { Fragment, Node as PMNode, Slice } from 'prosemirror-model';
|
|
3
|
-
import { TextSelection } from 'prosemirror-state';
|
|
3
|
+
import { TextSelection, NodeSelection } from 'prosemirror-state';
|
|
4
4
|
import { findParentNodeOfType, hasParentNodeOfType, safeInsert } from 'prosemirror-utils';
|
|
5
5
|
import { compose, insideTable, isParagraph, isText, isLinkMark, processRawValue } from '../../utils';
|
|
6
6
|
import { mapSlice } from '../../utils/slice';
|
|
@@ -54,8 +54,10 @@ export function handlePasteIntoTaskAndDecision(slice) {
|
|
|
54
54
|
text
|
|
55
55
|
}
|
|
56
56
|
} = schema;
|
|
57
|
+
const isDecisionOrTaskNodeSelection = state.selection instanceof NodeSelection && ['decisionList', 'decisionItem', 'taskList', 'taskItem'].includes(state.selection.node.type.name);
|
|
58
|
+
const hasParentDecisionOrTaskItem = hasParentNodeOfType([decisionItem, taskItem])(state.selection);
|
|
57
59
|
|
|
58
|
-
if (!decisionItem || !decisionList || !taskList || !taskItem || !
|
|
60
|
+
if (!decisionItem || !decisionList || !taskList || !taskItem || !hasParentDecisionOrTaskItem && !isDecisionOrTaskNodeSelection) {
|
|
59
61
|
return false;
|
|
60
62
|
}
|
|
61
63
|
|
|
@@ -69,7 +71,15 @@ export function handlePasteIntoTaskAndDecision(slice) {
|
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
const transformedSlice = compose.apply(null, filters)(slice);
|
|
72
|
-
const tr = closeHistory(state.tr)
|
|
74
|
+
const tr = closeHistory(state.tr);
|
|
75
|
+
const transformedSliceIsValidNode = transformedSlice.content.firstChild.type.inlineContent || ['decisionList', 'decisionItem', 'taskList', 'taskItem'].includes(transformedSlice.content.firstChild.type.name);
|
|
76
|
+
|
|
77
|
+
if (transformedSliceIsValidNode || isDecisionOrTaskNodeSelection) {
|
|
78
|
+
tr.replaceSelection(transformedSlice).scrollIntoView();
|
|
79
|
+
} else {
|
|
80
|
+
safeInsert(transformedSlice.content)(tr).scrollIntoView();
|
|
81
|
+
}
|
|
82
|
+
|
|
73
83
|
queueCardsFromChangedTr(state, tr, INPUT_METHOD.CLIPBOARD);
|
|
74
84
|
|
|
75
85
|
if (dispatch) {
|
|
@@ -371,9 +381,13 @@ export function handleMediaSingle(inputMethod) {
|
|
|
371
381
|
};
|
|
372
382
|
};
|
|
373
383
|
}
|
|
374
|
-
export function
|
|
384
|
+
export function handleExpandPasteInTable(slice) {
|
|
375
385
|
return (state, dispatch) => {
|
|
376
|
-
|
|
386
|
+
var _slice$content$firstC;
|
|
387
|
+
|
|
388
|
+
// Do not handle expand if it's not being pasted into a table
|
|
389
|
+
// OR if it's nested within another node when being pasted into a table
|
|
390
|
+
if (!insideTable(state) || ((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.type.name) !== 'expand') {
|
|
377
391
|
return false;
|
|
378
392
|
}
|
|
379
393
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ACTION, INPUT_METHOD, EVENT_TYPE, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, PasteTypes, PasteContents, withAnalytics } from '../../analytics';
|
|
2
2
|
import { getPasteSource } from '../util';
|
|
3
|
-
import { handlePasteAsPlainText, handlePasteIntoTaskAndDecision, handleCodeBlock, handleMediaSingle, handlePastePreservingMarks, handleMarkdown, handleRichText,
|
|
3
|
+
import { handlePasteAsPlainText, handlePasteIntoTaskAndDecision, handleCodeBlock, handleMediaSingle, handlePastePreservingMarks, handleMarkdown, handleRichText, handleExpandPasteInTable, handleSelectedTable, handlePasteLinkOnSelectedText } from '../handlers';
|
|
4
4
|
import { pipe } from '../../../utils';
|
|
5
5
|
import { findParentNode } from 'prosemirror-utils';
|
|
6
6
|
import { mapSlice } from '../../../utils/slice';
|
|
@@ -239,7 +239,7 @@ export const handleMarkdownWithAnalytics = (view, event, slice) => pipe(handleMa
|
|
|
239
239
|
export const handleRichTextWithAnalytics = (view, event, slice) => pipe(handleRichText, pasteCommandWithAnalytics(view, event, slice, {
|
|
240
240
|
type: PasteTypes.richText
|
|
241
241
|
}))(slice);
|
|
242
|
-
export const handleExpandWithAnalytics = (view, event, slice) => pipe(
|
|
242
|
+
export const handleExpandWithAnalytics = (view, event, slice) => pipe(handleExpandPasteInTable, pasteCommandWithAnalytics(view, event, slice, {
|
|
243
243
|
type: PasteTypes.richText
|
|
244
244
|
}))(slice);
|
|
245
245
|
export const handleSelectedTableWithAnalytics = (view, event, slice) => pipe(handleSelectedTable, pasteCommandWithAnalytics(view, event, slice, {
|
|
@@ -12,6 +12,23 @@ import { PlaceholderTextNodeView } from './placeholder-text-nodeview';
|
|
|
12
12
|
import { pluginKey } from './plugin-key';
|
|
13
13
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, EVENT_TYPE, INPUT_METHOD } from '../analytics';
|
|
14
14
|
import { messages } from '../insert-block/ui/ToolbarInsertBlock/messages';
|
|
15
|
+
import { isSelectionAtPlaceholder } from './selection-utils';
|
|
16
|
+
import { createInternalTypeAheadTools } from '../type-ahead/api';
|
|
17
|
+
|
|
18
|
+
const getOpenTypeAhead = (view, content) => {
|
|
19
|
+
const typeAheadAPI = createInternalTypeAheadTools(view);
|
|
20
|
+
const typeAheadHandler = typeAheadAPI.findTypeAheadHandler(content);
|
|
21
|
+
|
|
22
|
+
if (!typeAheadHandler || !typeAheadHandler.id) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return typeAheadAPI.openTypeAheadHandler({
|
|
27
|
+
triggerHandler: typeAheadHandler,
|
|
28
|
+
inputMethod: INPUT_METHOD.KEYBOARD
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
15
32
|
export function createPlugin(dispatch, options) {
|
|
16
33
|
const allowInserting = !!options.allowInserting;
|
|
17
34
|
return new SafePlugin({
|
|
@@ -80,6 +97,34 @@ export function createPlugin(dispatch, options) {
|
|
|
80
97
|
},
|
|
81
98
|
|
|
82
99
|
props: {
|
|
100
|
+
handleDOMEvents: {
|
|
101
|
+
beforeinput: (view, event) => {
|
|
102
|
+
const {
|
|
103
|
+
state
|
|
104
|
+
} = view;
|
|
105
|
+
|
|
106
|
+
if (event instanceof InputEvent && !event.isComposing && event.inputType === 'insertText' && isSelectionAtPlaceholder(view.state.selection)) {
|
|
107
|
+
event.stopPropagation();
|
|
108
|
+
event.preventDefault();
|
|
109
|
+
const startNodePosition = state.selection.from;
|
|
110
|
+
const content = event.data || '';
|
|
111
|
+
const tr = view.state.tr;
|
|
112
|
+
tr.delete(startNodePosition, startNodePosition + 1);
|
|
113
|
+
const openTypeAhead = getOpenTypeAhead(view, content);
|
|
114
|
+
|
|
115
|
+
if (openTypeAhead) {
|
|
116
|
+
openTypeAhead(tr);
|
|
117
|
+
} else {
|
|
118
|
+
tr.insertText(content);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
view.dispatch(tr);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
83
128
|
nodeViews: {
|
|
84
129
|
placeholder: (node, view, getPos) => new PlaceholderTextNodeView(node, view, getPos)
|
|
85
130
|
}
|
|
@@ -168,7 +213,7 @@ const decorateWithPluginOptions = (plugin, options) => {
|
|
|
168
213
|
}),
|
|
169
214
|
|
|
170
215
|
action(insert, state) {
|
|
171
|
-
const tr =
|
|
216
|
+
const tr = state.tr;
|
|
172
217
|
tr.setMeta(pluginKey, {
|
|
173
218
|
showInsertPanelAt: tr.selection.anchor
|
|
174
219
|
});
|
|
@@ -1,38 +1,84 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Selection } from 'prosemirror-state';
|
|
2
|
+
import { browser, ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/utils';
|
|
3
|
+
|
|
4
|
+
const serializePlaceholderNode = node => {
|
|
5
|
+
const element = document.createElement('span');
|
|
6
|
+
element.classList.add('pm-placeholder');
|
|
7
|
+
|
|
8
|
+
if (browser.gecko) {
|
|
9
|
+
element.setAttribute('contenteditable', 'true');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
element.innerText = ZERO_WIDTH_SPACE;
|
|
13
|
+
const elementChildren = document.createElement('span');
|
|
14
|
+
elementChildren.classList.add('pm-placeholder__text');
|
|
15
|
+
elementChildren.dataset.placeholder = node.attrs.text;
|
|
16
|
+
elementChildren.setAttribute('contenteditable', 'false');
|
|
17
|
+
element.appendChild(elementChildren);
|
|
18
|
+
|
|
19
|
+
if (browser.safari) {
|
|
20
|
+
element.appendChild(document.createTextNode(ZERO_WIDTH_SPACE));
|
|
21
|
+
} else {
|
|
22
|
+
element.appendChild(document.createElement('wbr'));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return element;
|
|
26
|
+
};
|
|
27
|
+
|
|
3
28
|
export class PlaceholderTextNodeView {
|
|
4
29
|
constructor(node, view, getPos) {
|
|
5
30
|
this.node = node;
|
|
6
31
|
this.view = view;
|
|
7
32
|
this.getPos = getPos;
|
|
8
|
-
|
|
9
|
-
this.
|
|
33
|
+
this.dom = serializePlaceholderNode(this.node);
|
|
34
|
+
this.getPos = getPos;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
stopEvent(e) {
|
|
38
|
+
if (e.type === 'mousedown' && typeof this.getPos === 'function') {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
const {
|
|
41
|
+
view
|
|
42
|
+
} = this;
|
|
43
|
+
const startNodePosition = this.getPos();
|
|
44
|
+
const tr = view.state.tr;
|
|
45
|
+
tr.setSelection(Selection.near(tr.doc.resolve(startNodePosition)));
|
|
46
|
+
view.dispatch(tr);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return false;
|
|
10
51
|
}
|
|
11
52
|
|
|
12
53
|
ignoreMutation(record) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// when we detect a characterData mutation inside
|
|
54
|
+
if (typeof this.getPos !== 'function' || record.type !== 'selection') {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
18
58
|
const {
|
|
19
59
|
view,
|
|
20
|
-
dom,
|
|
21
60
|
node
|
|
22
61
|
} = this;
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
62
|
+
const placeholderStartPosition = this.getPos();
|
|
63
|
+
const placeholderEndPosition = this.getPos() + node.nodeSize;
|
|
64
|
+
const selection = view.state.selection; // when the selection is set right after the placeholder.
|
|
65
|
+
// we should let ProseMirror deal with this edge-case
|
|
66
|
+
|
|
67
|
+
if (selection.from === placeholderEndPosition) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const isSelectionAtPlaceholder = selection.from === placeholderStartPosition;
|
|
72
|
+
const isSelectionAfterlaceholder = selection.from > placeholderEndPosition;
|
|
73
|
+
|
|
74
|
+
if (isSelectionAtPlaceholder || isSelectionAfterlaceholder) {
|
|
75
|
+
const tr = view.state.tr;
|
|
76
|
+
tr.setSelection(Selection.near(tr.doc.resolve(placeholderEndPosition)));
|
|
32
77
|
view.dispatch(tr);
|
|
78
|
+
return true;
|
|
33
79
|
}
|
|
34
80
|
|
|
35
|
-
return
|
|
81
|
+
return true;
|
|
36
82
|
}
|
|
37
83
|
|
|
38
84
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TextSelection } from 'prosemirror-state';
|
|
2
|
+
export const isSelectionAtPlaceholder = selection => {
|
|
3
|
+
if (!(selection instanceof TextSelection) || !selection.$cursor) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const node = selection.$cursor.doc.nodeAt(selection.$cursor.pos);
|
|
8
|
+
return (node === null || node === void 0 ? void 0 : node.type.name) === 'placeholder';
|
|
9
|
+
};
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import { css } from 'styled-components';
|
|
2
2
|
import { N300 } from '@atlaskit/theme/colors';
|
|
3
|
+
import { SelectionStyle, getSelectionStyles, akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles';
|
|
3
4
|
export const placeholderTextStyles = css`
|
|
4
5
|
.ProseMirror span[data-placeholder] {
|
|
5
6
|
color: ${N300};
|
|
7
|
+
display: inline;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.ProseMirror span.pm-placeholder {
|
|
11
|
+
display: inline;
|
|
12
|
+
color: ${N300};
|
|
13
|
+
}
|
|
14
|
+
.ProseMirror span.pm-placeholder__text {
|
|
15
|
+
display: inline;
|
|
16
|
+
color: ${N300};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.ProseMirror span.pm-placeholder.${akEditorSelectedNodeClassName} {
|
|
20
|
+
${getSelectionStyles([SelectionStyle.Background])}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.ProseMirror span.pm-placeholder__text[data-placeholder]::after {
|
|
24
|
+
color: ${N300};
|
|
25
|
+
cursor: text;
|
|
26
|
+
content: attr(data-placeholder);
|
|
27
|
+
display: inline;
|
|
6
28
|
}
|
|
7
29
|
`;
|
|
@@ -2,6 +2,6 @@ export { hoverColumns, hoverRows, hoverTable, hoverMergedCells, clearHoverSelect
|
|
|
2
2
|
export { insertColumn, insertRow, createTable } from './insert';
|
|
3
3
|
export { getNextLayout, toggleContextualMenu, toggleHeaderColumn, toggleHeaderRow, toggleNumberColumn, toggleTableLayout } from './toggle';
|
|
4
4
|
export { clearMultipleCells } from './clear';
|
|
5
|
-
export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectRow, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations
|
|
5
|
+
export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectRow, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
|
|
6
6
|
export { sortByColumn } from './sort';
|
|
7
7
|
export { goToNextCell } from './go-to-next-cell';
|
|
@@ -94,7 +94,7 @@ export const insertColumn = column => (state, dispatch, view) => {
|
|
|
94
94
|
};
|
|
95
95
|
export const insertRow = (row, moveCursorToTheNewRow) => (state, dispatch) => {
|
|
96
96
|
// Don't clone the header row
|
|
97
|
-
const headerRowEnabled = checkIfHeaderRowEnabled(state);
|
|
97
|
+
const headerRowEnabled = checkIfHeaderRowEnabled(state.selection);
|
|
98
98
|
const clonePreviousRow = headerRowEnabled && row > 1 || !headerRowEnabled && row > 0; // When the table have header row
|
|
99
99
|
// we should not add row on the position zero
|
|
100
100
|
|