@atlaskit/editor-plugin-synced-block 3.3.1 → 3.3.3
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 +16 -0
- package/afm-cc/tsconfig.json +3 -0
- package/afm-dev-agents/tsconfig.json +3 -0
- package/afm-jira/tsconfig.json +3 -0
- package/afm-passionfruit/tsconfig.json +3 -0
- package/afm-post-office/tsconfig.json +3 -0
- package/afm-rovo-extension/tsconfig.json +3 -0
- package/afm-townsquare/tsconfig.json +3 -0
- package/dist/cjs/nodeviews/syncedBlock.js +2 -0
- package/dist/cjs/pm-plugins/actions.js +32 -10
- package/dist/cjs/pm-plugins/main.js +1 -0
- package/dist/cjs/pm-plugins/utils/utils.js +49 -1
- package/dist/cjs/syncedBlockPlugin.js +11 -2
- package/dist/cjs/ui/CreateSyncedBlockDropdownItem.js +4 -2
- package/dist/es2019/nodeviews/syncedBlock.js +2 -0
- package/dist/es2019/pm-plugins/actions.js +35 -13
- package/dist/es2019/pm-plugins/main.js +1 -0
- package/dist/es2019/pm-plugins/utils/utils.js +48 -0
- package/dist/es2019/syncedBlockPlugin.js +11 -2
- package/dist/es2019/ui/CreateSyncedBlockDropdownItem.js +4 -2
- package/dist/esm/nodeviews/syncedBlock.js +2 -0
- package/dist/esm/pm-plugins/actions.js +33 -11
- package/dist/esm/pm-plugins/main.js +1 -0
- package/dist/esm/pm-plugins/utils/utils.js +48 -0
- package/dist/esm/syncedBlockPlugin.js +11 -2
- package/dist/esm/ui/CreateSyncedBlockDropdownItem.js +4 -2
- package/dist/types/pm-plugins/actions.d.ts +9 -2
- package/dist/types/pm-plugins/utils/utils.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/actions.d.ts +9 -2
- package/dist/types-ts4.5/pm-plugins/utils/utils.d.ts +7 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 3.3.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`e053b5e610ac2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e053b5e610ac2) -
|
|
8
|
+
[ux] EDITOR-1652 add convert to sync block to block menu
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 3.3.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`1256b3dd0431e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1256b3dd0431e) -
|
|
16
|
+
Fix isSource check in provider
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 3.3.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/afm-cc/tsconfig.json
CHANGED
package/afm-jira/tsconfig.json
CHANGED
|
@@ -70,6 +70,7 @@ var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
70
70
|
value: function setInnerEditorView(editorView) {
|
|
71
71
|
var _this$options;
|
|
72
72
|
// set inner editor view
|
|
73
|
+
this.syncBlockStore.setSyncBlockNestedEditorView(editorView);
|
|
73
74
|
var nodes = [(0, _editorSyncedBlockProvider.convertSyncBlockPMNodeToSyncBlockData)(this.node, false)];
|
|
74
75
|
(_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.dataProvider) === null || _this$options === void 0 || _this$options.fetchNodesData(nodes).then(function (data) {
|
|
75
76
|
var _data$;
|
|
@@ -162,6 +163,7 @@ var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
162
163
|
if (this.fetchIntervalId) {
|
|
163
164
|
window.clearInterval(this.fetchIntervalId);
|
|
164
165
|
}
|
|
166
|
+
this.syncBlockStore.setSyncBlockNestedEditorView(undefined);
|
|
165
167
|
(_this$unsubscribe = this.unsubscribe) === null || _this$unsubscribe === void 0 || _this$unsubscribe.call(this);
|
|
166
168
|
_superPropGet(SyncBlock, "destroy", this, 3)([]);
|
|
167
169
|
}
|
|
@@ -12,25 +12,47 @@ var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider
|
|
|
12
12
|
var _utils2 = require("./utils/utils");
|
|
13
13
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
14
14
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
15
|
-
var createSyncedBlock = exports.createSyncedBlock = function createSyncedBlock(
|
|
16
|
-
var
|
|
15
|
+
var createSyncedBlock = exports.createSyncedBlock = function createSyncedBlock(_ref) {
|
|
16
|
+
var tr = _ref.tr,
|
|
17
|
+
syncBlockStore = _ref.syncBlockStore,
|
|
18
|
+
typeAheadInsert = _ref.typeAheadInsert;
|
|
19
|
+
var _tr$doc$type$schema$n = tr.doc.type.schema.nodes,
|
|
20
|
+
syncBlock = _tr$doc$type$schema$n.syncBlock,
|
|
21
|
+
doc = _tr$doc$type$schema$n.doc;
|
|
17
22
|
var syncBlockNode = syncBlockStore.createSyncBlockNode();
|
|
23
|
+
var node = syncBlock.createAndFill(_objectSpread({}, syncBlockNode.attrs));
|
|
24
|
+
if (!node) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
18
27
|
|
|
19
|
-
// If the selection is empty, we want to insert the
|
|
28
|
+
// If the selection is empty, we want to insert the sync block on a new line
|
|
20
29
|
if (tr.selection.empty) {
|
|
21
|
-
var node = syncBlock.createAndFill(_objectSpread({}, syncBlockNode.attrs));
|
|
22
|
-
if (!node) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
30
|
if (typeAheadInsert) {
|
|
26
31
|
tr = typeAheadInsert(node);
|
|
27
32
|
} else {
|
|
28
33
|
tr = tr.replaceSelectionWith(node).scrollIntoView();
|
|
29
34
|
}
|
|
30
35
|
} else {
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
var conversionInfo = (0, _utils2.canBeConvertedToSyncBlock)(tr.selection);
|
|
37
|
+
if (conversionInfo) {
|
|
38
|
+
tr.replaceWith(conversionInfo.from, conversionInfo.to, node).scrollIntoView();
|
|
39
|
+
var innerNodeJson = doc.create({}, conversionInfo.contentToInclude).toJSON();
|
|
40
|
+
|
|
41
|
+
// TMP solution to wait for the nested editor view to be set
|
|
42
|
+
// this will be removed once we have a proper architecture settled
|
|
43
|
+
setTimeout(function () {
|
|
44
|
+
var editorView = syncBlockStore.getSyncBlockNestedEditorView();
|
|
45
|
+
if (editorView) {
|
|
46
|
+
var innerTr = editorView.state.tr;
|
|
47
|
+
var innerNode = editorView.state.schema.nodeFromJSON(innerNodeJson);
|
|
48
|
+
editorView.dispatch(innerTr.replaceWith(0, editorView.state.doc.nodeSize - 2, innerNode));
|
|
49
|
+
}
|
|
50
|
+
}, 1000);
|
|
51
|
+
} else {
|
|
52
|
+
var _safeInsert;
|
|
53
|
+
// still insert an empty sync block if conversion is not possible
|
|
54
|
+
(_safeInsert = (0, _utils.safeInsert)(syncBlock.createAndFill(syncBlockNode.attrs))(tr)) === null || _safeInsert === void 0 || _safeInsert.scrollIntoView();
|
|
55
|
+
}
|
|
34
56
|
}
|
|
35
57
|
return tr;
|
|
36
58
|
};
|
|
@@ -3,9 +3,57 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.findSyncBlock = void 0;
|
|
6
|
+
exports.findSyncBlock = exports.canBeConvertedToSyncBlock = void 0;
|
|
7
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
7
8
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
9
|
+
var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider");
|
|
10
|
+
var _editorTables = require("@atlaskit/editor-tables");
|
|
8
11
|
var findSyncBlock = exports.findSyncBlock = function findSyncBlock(state, selection) {
|
|
9
12
|
var syncBlock = state.schema.nodes.syncBlock;
|
|
10
13
|
return (0, _utils.findSelectedNodeOfType)(syncBlock)(selection || state.selection) || (0, _utils.findParentNodeOfType)(syncBlock)(selection || state.selection);
|
|
14
|
+
};
|
|
15
|
+
var canBeConvertedToSyncBlock = exports.canBeConvertedToSyncBlock = function canBeConvertedToSyncBlock(selection) {
|
|
16
|
+
var from = selection.from;
|
|
17
|
+
var to = selection.to;
|
|
18
|
+
var depth = selection.$from.depth;
|
|
19
|
+
var contentToInclude;
|
|
20
|
+
if (selection instanceof _editorTables.CellSelection) {
|
|
21
|
+
var table = (0, _editorTables.findTable)(selection);
|
|
22
|
+
if (!table) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
contentToInclude = _model.Fragment.from([table.node]);
|
|
26
|
+
from = table.pos;
|
|
27
|
+
to = table.pos + table.node.nodeSize;
|
|
28
|
+
depth = selection.$from.doc.resolve(table.pos).depth;
|
|
29
|
+
} else {
|
|
30
|
+
contentToInclude = _model.Fragment.from(selection.content().content);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// sync blocks can't be nested
|
|
34
|
+
if (depth > 1) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
var syncBlockSchema = (0, _editorSyncedBlockProvider.getDefaultSyncBlockSchema)();
|
|
38
|
+
var canBeConverted = true;
|
|
39
|
+
selection.$from.doc.nodesBetween(from, to, function (node) {
|
|
40
|
+
if (!(node.type.name in syncBlockSchema.nodes)) {
|
|
41
|
+
canBeConverted = false;
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
node.marks.forEach(function (mark) {
|
|
45
|
+
if (!(mark.type.name in syncBlockSchema.marks)) {
|
|
46
|
+
canBeConverted = false;
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
if (!canBeConverted) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
contentToInclude: contentToInclude,
|
|
56
|
+
from: from,
|
|
57
|
+
to: to
|
|
58
|
+
};
|
|
11
59
|
};
|
|
@@ -41,7 +41,11 @@ var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_
|
|
|
41
41
|
insertSyncedBlock: function insertSyncedBlock() {
|
|
42
42
|
return function (_ref2) {
|
|
43
43
|
var tr = _ref2.tr;
|
|
44
|
-
return (0, _actions.createSyncedBlock)(
|
|
44
|
+
return (0, _actions.createSyncedBlock)({
|
|
45
|
+
tr: tr,
|
|
46
|
+
syncBlockStore: syncBlockStore,
|
|
47
|
+
dataProvider: config === null || config === void 0 ? void 0 : config.dataProvider
|
|
48
|
+
}) || null;
|
|
45
49
|
};
|
|
46
50
|
}
|
|
47
51
|
},
|
|
@@ -61,7 +65,12 @@ var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_
|
|
|
61
65
|
});
|
|
62
66
|
},
|
|
63
67
|
action: function action(insert, state) {
|
|
64
|
-
return (0, _actions.createSyncedBlock)(
|
|
68
|
+
return (0, _actions.createSyncedBlock)({
|
|
69
|
+
tr: state.tr,
|
|
70
|
+
syncBlockStore: syncBlockStore,
|
|
71
|
+
dataProvider: config === null || config === void 0 ? void 0 : config.dataProvider,
|
|
72
|
+
typeAheadInsert: insert
|
|
73
|
+
});
|
|
65
74
|
}
|
|
66
75
|
}];
|
|
67
76
|
},
|
|
@@ -9,13 +9,15 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
9
9
|
var _reactIntlNext = require("react-intl-next");
|
|
10
10
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
11
11
|
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
12
|
+
var _utils = require("../pm-plugins/utils/utils");
|
|
12
13
|
var CreateSyncedBlockDropdownItem = exports.CreateSyncedBlockDropdownItem = function CreateSyncedBlockDropdownItem(_ref) {
|
|
13
14
|
var _api$selection;
|
|
14
15
|
var api = _ref.api;
|
|
15
16
|
var _useIntl = (0, _reactIntlNext.useIntl)(),
|
|
16
17
|
formatMessage = _useIntl.formatMessage;
|
|
17
18
|
var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState) === null || _api$selection === void 0 || (_api$selection = _api$selection.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
|
|
18
|
-
|
|
19
|
+
var canCreateSyncBlock = selection && (0, _utils.canBeConvertedToSyncBlock)(selection);
|
|
20
|
+
if (!canCreateSyncBlock) {
|
|
19
21
|
return null;
|
|
20
22
|
}
|
|
21
23
|
var onClick = function onClick() {
|
|
@@ -27,5 +29,5 @@ var CreateSyncedBlockDropdownItem = exports.CreateSyncedBlockDropdownItem = func
|
|
|
27
29
|
label: ""
|
|
28
30
|
}),
|
|
29
31
|
onClick: onClick
|
|
30
|
-
}, formatMessage(_messages.blockMenuMessages.createSyncedBlock));
|
|
32
|
+
}, selection !== null && selection !== void 0 && selection.empty ? formatMessage(_messages.blockMenuMessages.createSyncedBlock) : formatMessage(_messages.blockMenuMessages.convertToSyncedBlock));
|
|
31
33
|
};
|
|
@@ -44,6 +44,7 @@ class SyncBlock extends ReactNodeView {
|
|
|
44
44
|
setInnerEditorView(editorView) {
|
|
45
45
|
var _this$options, _this$options$dataPro;
|
|
46
46
|
// set inner editor view
|
|
47
|
+
this.syncBlockStore.setSyncBlockNestedEditorView(editorView);
|
|
47
48
|
const nodes = [convertSyncBlockPMNodeToSyncBlockData(this.node, false)];
|
|
48
49
|
(_this$options = this.options) === null || _this$options === void 0 ? void 0 : (_this$options$dataPro = _this$options.dataProvider) === null || _this$options$dataPro === void 0 ? void 0 : _this$options$dataPro.fetchNodesData(nodes).then(data => {
|
|
49
50
|
var _data$;
|
|
@@ -118,6 +119,7 @@ class SyncBlock extends ReactNodeView {
|
|
|
118
119
|
if (this.fetchIntervalId) {
|
|
119
120
|
window.clearInterval(this.fetchIntervalId);
|
|
120
121
|
}
|
|
122
|
+
this.syncBlockStore.setSyncBlockNestedEditorView(undefined);
|
|
121
123
|
(_this$unsubscribe = this.unsubscribe) === null || _this$unsubscribe === void 0 ? void 0 : _this$unsubscribe.call(this);
|
|
122
124
|
super.destroy();
|
|
123
125
|
}
|
|
@@ -1,34 +1,56 @@
|
|
|
1
1
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
3
3
|
import { generateSyncBlockSourceUrl } from '@atlaskit/editor-synced-block-provider';
|
|
4
|
-
import { findSyncBlock } from './utils/utils';
|
|
5
|
-
export const createSyncedBlock = (
|
|
4
|
+
import { canBeConvertedToSyncBlock, findSyncBlock } from './utils/utils';
|
|
5
|
+
export const createSyncedBlock = ({
|
|
6
|
+
tr,
|
|
7
|
+
syncBlockStore,
|
|
8
|
+
typeAheadInsert
|
|
9
|
+
}) => {
|
|
6
10
|
const {
|
|
7
11
|
schema: {
|
|
8
12
|
nodes: {
|
|
9
|
-
syncBlock
|
|
13
|
+
syncBlock,
|
|
14
|
+
doc
|
|
10
15
|
}
|
|
11
16
|
}
|
|
12
17
|
} = tr.doc.type;
|
|
13
18
|
const syncBlockNode = syncBlockStore.createSyncBlockNode();
|
|
19
|
+
const node = syncBlock.createAndFill({
|
|
20
|
+
...syncBlockNode.attrs
|
|
21
|
+
});
|
|
22
|
+
if (!node) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
14
25
|
|
|
15
|
-
// If the selection is empty, we want to insert the
|
|
26
|
+
// If the selection is empty, we want to insert the sync block on a new line
|
|
16
27
|
if (tr.selection.empty) {
|
|
17
|
-
const node = syncBlock.createAndFill({
|
|
18
|
-
...syncBlockNode.attrs
|
|
19
|
-
});
|
|
20
|
-
if (!node) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
28
|
if (typeAheadInsert) {
|
|
24
29
|
tr = typeAheadInsert(node);
|
|
25
30
|
} else {
|
|
26
31
|
tr = tr.replaceSelectionWith(node).scrollIntoView();
|
|
27
32
|
}
|
|
28
33
|
} else {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const conversionInfo = canBeConvertedToSyncBlock(tr.selection);
|
|
35
|
+
if (conversionInfo) {
|
|
36
|
+
tr.replaceWith(conversionInfo.from, conversionInfo.to, node).scrollIntoView();
|
|
37
|
+
const innerNodeJson = doc.create({}, conversionInfo.contentToInclude).toJSON();
|
|
38
|
+
|
|
39
|
+
// TMP solution to wait for the nested editor view to be set
|
|
40
|
+
// this will be removed once we have a proper architecture settled
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
const editorView = syncBlockStore.getSyncBlockNestedEditorView();
|
|
43
|
+
if (editorView) {
|
|
44
|
+
const innerTr = editorView.state.tr;
|
|
45
|
+
const innerNode = editorView.state.schema.nodeFromJSON(innerNodeJson);
|
|
46
|
+
editorView.dispatch(innerTr.replaceWith(0, editorView.state.doc.nodeSize - 2, innerNode));
|
|
47
|
+
}
|
|
48
|
+
}, 1000);
|
|
49
|
+
} else {
|
|
50
|
+
var _safeInsert;
|
|
51
|
+
// still insert an empty sync block if conversion is not possible
|
|
52
|
+
(_safeInsert = safeInsert(syncBlock.createAndFill(syncBlockNode.attrs))(tr)) === null || _safeInsert === void 0 ? void 0 : _safeInsert.scrollIntoView();
|
|
53
|
+
}
|
|
32
54
|
}
|
|
33
55
|
return tr;
|
|
34
56
|
};
|
|
@@ -1,7 +1,55 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
import { getDefaultSyncBlockSchema } from '@atlaskit/editor-synced-block-provider';
|
|
4
|
+
import { CellSelection, findTable } from '@atlaskit/editor-tables';
|
|
2
5
|
export const findSyncBlock = (state, selection) => {
|
|
3
6
|
const {
|
|
4
7
|
syncBlock
|
|
5
8
|
} = state.schema.nodes;
|
|
6
9
|
return findSelectedNodeOfType(syncBlock)(selection || state.selection) || findParentNodeOfType(syncBlock)(selection || state.selection);
|
|
10
|
+
};
|
|
11
|
+
export const canBeConvertedToSyncBlock = selection => {
|
|
12
|
+
let from = selection.from;
|
|
13
|
+
let to = selection.to;
|
|
14
|
+
let depth = selection.$from.depth;
|
|
15
|
+
let contentToInclude;
|
|
16
|
+
if (selection instanceof CellSelection) {
|
|
17
|
+
const table = findTable(selection);
|
|
18
|
+
if (!table) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
contentToInclude = Fragment.from([table.node]);
|
|
22
|
+
from = table.pos;
|
|
23
|
+
to = table.pos + table.node.nodeSize;
|
|
24
|
+
depth = selection.$from.doc.resolve(table.pos).depth;
|
|
25
|
+
} else {
|
|
26
|
+
contentToInclude = Fragment.from(selection.content().content);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// sync blocks can't be nested
|
|
30
|
+
if (depth > 1) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const syncBlockSchema = getDefaultSyncBlockSchema();
|
|
34
|
+
let canBeConverted = true;
|
|
35
|
+
selection.$from.doc.nodesBetween(from, to, node => {
|
|
36
|
+
if (!(node.type.name in syncBlockSchema.nodes)) {
|
|
37
|
+
canBeConverted = false;
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
node.marks.forEach(mark => {
|
|
41
|
+
if (!(mark.type.name in syncBlockSchema.marks)) {
|
|
42
|
+
canBeConverted = false;
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
if (!canBeConverted) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
contentToInclude,
|
|
52
|
+
from,
|
|
53
|
+
to
|
|
54
|
+
};
|
|
7
55
|
};
|
|
@@ -32,7 +32,11 @@ export const syncedBlockPlugin = ({
|
|
|
32
32
|
commands: {
|
|
33
33
|
insertSyncedBlock: () => ({
|
|
34
34
|
tr
|
|
35
|
-
}) => createSyncedBlock(
|
|
35
|
+
}) => createSyncedBlock({
|
|
36
|
+
tr,
|
|
37
|
+
syncBlockStore,
|
|
38
|
+
dataProvider: config === null || config === void 0 ? void 0 : config.dataProvider
|
|
39
|
+
}) || null
|
|
36
40
|
},
|
|
37
41
|
pluginsOptions: {
|
|
38
42
|
quickInsert: ({
|
|
@@ -48,7 +52,12 @@ export const syncedBlockPlugin = ({
|
|
|
48
52
|
label: formatMessage(blockTypeMessages.syncedBlock)
|
|
49
53
|
}),
|
|
50
54
|
action: (insert, state) => {
|
|
51
|
-
return createSyncedBlock(
|
|
55
|
+
return createSyncedBlock({
|
|
56
|
+
tr: state.tr,
|
|
57
|
+
syncBlockStore,
|
|
58
|
+
dataProvider: config === null || config === void 0 ? void 0 : config.dataProvider,
|
|
59
|
+
typeAheadInsert: insert
|
|
60
|
+
});
|
|
52
61
|
}
|
|
53
62
|
}],
|
|
54
63
|
floatingToolbar: (state, intl, providerFactory) => getToolbarConfig(state, intl, config, providerFactory, api, syncBlockStore)
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { useIntl } from 'react-intl-next';
|
|
3
3
|
import { blockMenuMessages } from '@atlaskit/editor-common/messages';
|
|
4
4
|
import { SyncBlocksIcon, ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
5
|
+
import { canBeConvertedToSyncBlock } from '../pm-plugins/utils/utils';
|
|
5
6
|
export const CreateSyncedBlockDropdownItem = ({
|
|
6
7
|
api
|
|
7
8
|
}) => {
|
|
@@ -10,7 +11,8 @@ export const CreateSyncedBlockDropdownItem = ({
|
|
|
10
11
|
formatMessage
|
|
11
12
|
} = useIntl();
|
|
12
13
|
const selection = api === null || api === void 0 ? void 0 : (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : (_api$selection$shared = _api$selection.sharedState) === null || _api$selection$shared === void 0 ? void 0 : (_api$selection$shared2 = _api$selection$shared.currentState()) === null || _api$selection$shared2 === void 0 ? void 0 : _api$selection$shared2.selection;
|
|
13
|
-
|
|
14
|
+
const canCreateSyncBlock = selection && canBeConvertedToSyncBlock(selection);
|
|
15
|
+
if (!canCreateSyncBlock) {
|
|
14
16
|
return null;
|
|
15
17
|
}
|
|
16
18
|
const onClick = () => {
|
|
@@ -22,5 +24,5 @@ export const CreateSyncedBlockDropdownItem = ({
|
|
|
22
24
|
label: ""
|
|
23
25
|
}),
|
|
24
26
|
onClick: onClick
|
|
25
|
-
}, formatMessage(blockMenuMessages.createSyncedBlock));
|
|
27
|
+
}, selection !== null && selection !== void 0 && selection.empty ? formatMessage(blockMenuMessages.createSyncedBlock) : formatMessage(blockMenuMessages.convertToSyncedBlock));
|
|
26
28
|
};
|
|
@@ -63,6 +63,7 @@ var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
63
63
|
value: function setInnerEditorView(editorView) {
|
|
64
64
|
var _this$options;
|
|
65
65
|
// set inner editor view
|
|
66
|
+
this.syncBlockStore.setSyncBlockNestedEditorView(editorView);
|
|
66
67
|
var nodes = [convertSyncBlockPMNodeToSyncBlockData(this.node, false)];
|
|
67
68
|
(_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.dataProvider) === null || _this$options === void 0 || _this$options.fetchNodesData(nodes).then(function (data) {
|
|
68
69
|
var _data$;
|
|
@@ -155,6 +156,7 @@ var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
155
156
|
if (this.fetchIntervalId) {
|
|
156
157
|
window.clearInterval(this.fetchIntervalId);
|
|
157
158
|
}
|
|
159
|
+
this.syncBlockStore.setSyncBlockNestedEditorView(undefined);
|
|
158
160
|
(_this$unsubscribe = this.unsubscribe) === null || _this$unsubscribe === void 0 || _this$unsubscribe.call(this);
|
|
159
161
|
_superPropGet(SyncBlock, "destroy", this, 3)([]);
|
|
160
162
|
}
|
|
@@ -4,26 +4,48 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
6
6
|
import { generateSyncBlockSourceUrl } from '@atlaskit/editor-synced-block-provider';
|
|
7
|
-
import { findSyncBlock } from './utils/utils';
|
|
8
|
-
export var createSyncedBlock = function createSyncedBlock(
|
|
9
|
-
var
|
|
7
|
+
import { canBeConvertedToSyncBlock, findSyncBlock } from './utils/utils';
|
|
8
|
+
export var createSyncedBlock = function createSyncedBlock(_ref) {
|
|
9
|
+
var tr = _ref.tr,
|
|
10
|
+
syncBlockStore = _ref.syncBlockStore,
|
|
11
|
+
typeAheadInsert = _ref.typeAheadInsert;
|
|
12
|
+
var _tr$doc$type$schema$n = tr.doc.type.schema.nodes,
|
|
13
|
+
syncBlock = _tr$doc$type$schema$n.syncBlock,
|
|
14
|
+
doc = _tr$doc$type$schema$n.doc;
|
|
10
15
|
var syncBlockNode = syncBlockStore.createSyncBlockNode();
|
|
16
|
+
var node = syncBlock.createAndFill(_objectSpread({}, syncBlockNode.attrs));
|
|
17
|
+
if (!node) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
11
20
|
|
|
12
|
-
// If the selection is empty, we want to insert the
|
|
21
|
+
// If the selection is empty, we want to insert the sync block on a new line
|
|
13
22
|
if (tr.selection.empty) {
|
|
14
|
-
var node = syncBlock.createAndFill(_objectSpread({}, syncBlockNode.attrs));
|
|
15
|
-
if (!node) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
23
|
if (typeAheadInsert) {
|
|
19
24
|
tr = typeAheadInsert(node);
|
|
20
25
|
} else {
|
|
21
26
|
tr = tr.replaceSelectionWith(node).scrollIntoView();
|
|
22
27
|
}
|
|
23
28
|
} else {
|
|
24
|
-
var
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
var conversionInfo = canBeConvertedToSyncBlock(tr.selection);
|
|
30
|
+
if (conversionInfo) {
|
|
31
|
+
tr.replaceWith(conversionInfo.from, conversionInfo.to, node).scrollIntoView();
|
|
32
|
+
var innerNodeJson = doc.create({}, conversionInfo.contentToInclude).toJSON();
|
|
33
|
+
|
|
34
|
+
// TMP solution to wait for the nested editor view to be set
|
|
35
|
+
// this will be removed once we have a proper architecture settled
|
|
36
|
+
setTimeout(function () {
|
|
37
|
+
var editorView = syncBlockStore.getSyncBlockNestedEditorView();
|
|
38
|
+
if (editorView) {
|
|
39
|
+
var innerTr = editorView.state.tr;
|
|
40
|
+
var innerNode = editorView.state.schema.nodeFromJSON(innerNodeJson);
|
|
41
|
+
editorView.dispatch(innerTr.replaceWith(0, editorView.state.doc.nodeSize - 2, innerNode));
|
|
42
|
+
}
|
|
43
|
+
}, 1000);
|
|
44
|
+
} else {
|
|
45
|
+
var _safeInsert;
|
|
46
|
+
// still insert an empty sync block if conversion is not possible
|
|
47
|
+
(_safeInsert = safeInsert(syncBlock.createAndFill(syncBlockNode.attrs))(tr)) === null || _safeInsert === void 0 || _safeInsert.scrollIntoView();
|
|
48
|
+
}
|
|
27
49
|
}
|
|
28
50
|
return tr;
|
|
29
51
|
};
|
|
@@ -1,5 +1,53 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
import { getDefaultSyncBlockSchema } from '@atlaskit/editor-synced-block-provider';
|
|
4
|
+
import { CellSelection, findTable } from '@atlaskit/editor-tables';
|
|
2
5
|
export var findSyncBlock = function findSyncBlock(state, selection) {
|
|
3
6
|
var syncBlock = state.schema.nodes.syncBlock;
|
|
4
7
|
return findSelectedNodeOfType(syncBlock)(selection || state.selection) || findParentNodeOfType(syncBlock)(selection || state.selection);
|
|
8
|
+
};
|
|
9
|
+
export var canBeConvertedToSyncBlock = function canBeConvertedToSyncBlock(selection) {
|
|
10
|
+
var from = selection.from;
|
|
11
|
+
var to = selection.to;
|
|
12
|
+
var depth = selection.$from.depth;
|
|
13
|
+
var contentToInclude;
|
|
14
|
+
if (selection instanceof CellSelection) {
|
|
15
|
+
var table = findTable(selection);
|
|
16
|
+
if (!table) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
contentToInclude = Fragment.from([table.node]);
|
|
20
|
+
from = table.pos;
|
|
21
|
+
to = table.pos + table.node.nodeSize;
|
|
22
|
+
depth = selection.$from.doc.resolve(table.pos).depth;
|
|
23
|
+
} else {
|
|
24
|
+
contentToInclude = Fragment.from(selection.content().content);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// sync blocks can't be nested
|
|
28
|
+
if (depth > 1) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
var syncBlockSchema = getDefaultSyncBlockSchema();
|
|
32
|
+
var canBeConverted = true;
|
|
33
|
+
selection.$from.doc.nodesBetween(from, to, function (node) {
|
|
34
|
+
if (!(node.type.name in syncBlockSchema.nodes)) {
|
|
35
|
+
canBeConverted = false;
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
node.marks.forEach(function (mark) {
|
|
39
|
+
if (!(mark.type.name in syncBlockSchema.marks)) {
|
|
40
|
+
canBeConverted = false;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
if (!canBeConverted) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
contentToInclude: contentToInclude,
|
|
50
|
+
from: from,
|
|
51
|
+
to: to
|
|
52
|
+
};
|
|
5
53
|
};
|
|
@@ -34,7 +34,11 @@ export var syncedBlockPlugin = function syncedBlockPlugin(_ref) {
|
|
|
34
34
|
insertSyncedBlock: function insertSyncedBlock() {
|
|
35
35
|
return function (_ref2) {
|
|
36
36
|
var tr = _ref2.tr;
|
|
37
|
-
return createSyncedBlock(
|
|
37
|
+
return createSyncedBlock({
|
|
38
|
+
tr: tr,
|
|
39
|
+
syncBlockStore: syncBlockStore,
|
|
40
|
+
dataProvider: config === null || config === void 0 ? void 0 : config.dataProvider
|
|
41
|
+
}) || null;
|
|
38
42
|
};
|
|
39
43
|
}
|
|
40
44
|
},
|
|
@@ -54,7 +58,12 @@ export var syncedBlockPlugin = function syncedBlockPlugin(_ref) {
|
|
|
54
58
|
});
|
|
55
59
|
},
|
|
56
60
|
action: function action(insert, state) {
|
|
57
|
-
return createSyncedBlock(
|
|
61
|
+
return createSyncedBlock({
|
|
62
|
+
tr: state.tr,
|
|
63
|
+
syncBlockStore: syncBlockStore,
|
|
64
|
+
dataProvider: config === null || config === void 0 ? void 0 : config.dataProvider,
|
|
65
|
+
typeAheadInsert: insert
|
|
66
|
+
});
|
|
58
67
|
}
|
|
59
68
|
}];
|
|
60
69
|
},
|
|
@@ -2,13 +2,15 @@ import React from 'react';
|
|
|
2
2
|
import { useIntl } from 'react-intl-next';
|
|
3
3
|
import { blockMenuMessages } from '@atlaskit/editor-common/messages';
|
|
4
4
|
import { SyncBlocksIcon, ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
5
|
+
import { canBeConvertedToSyncBlock } from '../pm-plugins/utils/utils';
|
|
5
6
|
export var CreateSyncedBlockDropdownItem = function CreateSyncedBlockDropdownItem(_ref) {
|
|
6
7
|
var _api$selection;
|
|
7
8
|
var api = _ref.api;
|
|
8
9
|
var _useIntl = useIntl(),
|
|
9
10
|
formatMessage = _useIntl.formatMessage;
|
|
10
11
|
var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState) === null || _api$selection === void 0 || (_api$selection = _api$selection.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
|
|
11
|
-
|
|
12
|
+
var canCreateSyncBlock = selection && canBeConvertedToSyncBlock(selection);
|
|
13
|
+
if (!canCreateSyncBlock) {
|
|
12
14
|
return null;
|
|
13
15
|
}
|
|
14
16
|
var onClick = function onClick() {
|
|
@@ -20,5 +22,5 @@ export var CreateSyncedBlockDropdownItem = function CreateSyncedBlockDropdownIte
|
|
|
20
22
|
label: ""
|
|
21
23
|
}),
|
|
22
24
|
onClick: onClick
|
|
23
|
-
}, formatMessage(blockMenuMessages.createSyncedBlock));
|
|
25
|
+
}, selection !== null && selection !== void 0 && selection.empty ? formatMessage(blockMenuMessages.createSyncedBlock) : formatMessage(blockMenuMessages.convertToSyncedBlock));
|
|
24
26
|
};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { Command, ExtractInjectionAPI, TypeAheadInsert } from '@atlaskit/editor-common/types';
|
|
2
2
|
import { type Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
-
import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
3
|
+
import type { SyncBlockDataProvider, SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
4
4
|
import type { SyncedBlockPlugin } from '../syncedBlockPluginType';
|
|
5
|
-
|
|
5
|
+
type createSyncedBlockProps = {
|
|
6
|
+
dataProvider?: SyncBlockDataProvider;
|
|
7
|
+
syncBlockStore: SyncBlockStoreManager;
|
|
8
|
+
tr: Transaction;
|
|
9
|
+
typeAheadInsert?: TypeAheadInsert;
|
|
10
|
+
};
|
|
11
|
+
export declare const createSyncedBlock: ({ tr, syncBlockStore, typeAheadInsert, }: createSyncedBlockProps) => false | Transaction;
|
|
6
12
|
export declare const copySyncedBlockReferenceToClipboard: (api?: ExtractInjectionAPI<SyncedBlockPlugin>) => Command;
|
|
7
13
|
export declare const editSyncedBlockSource: (_api?: ExtractInjectionAPI<SyncedBlockPlugin>) => Command;
|
|
8
14
|
export declare const removeSyncedBlock: (api?: ExtractInjectionAPI<SyncedBlockPlugin>) => Command;
|
|
15
|
+
export {};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
2
3
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
4
|
export declare const findSyncBlock: (state: EditorState, selection?: Selection | null) => ReturnType<ReturnType<typeof findSelectedNodeOfType>> | ReturnType<ReturnType<typeof findParentNodeOfType>>;
|
|
5
|
+
export interface SyncBlockConversionInfo {
|
|
6
|
+
contentToInclude: Fragment;
|
|
7
|
+
from: number;
|
|
8
|
+
to: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const canBeConvertedToSyncBlock: (selection: Selection) => SyncBlockConversionInfo | false;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { Command, ExtractInjectionAPI, TypeAheadInsert } from '@atlaskit/editor-common/types';
|
|
2
2
|
import { type Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
-
import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
3
|
+
import type { SyncBlockDataProvider, SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
4
4
|
import type { SyncedBlockPlugin } from '../syncedBlockPluginType';
|
|
5
|
-
|
|
5
|
+
type createSyncedBlockProps = {
|
|
6
|
+
dataProvider?: SyncBlockDataProvider;
|
|
7
|
+
syncBlockStore: SyncBlockStoreManager;
|
|
8
|
+
tr: Transaction;
|
|
9
|
+
typeAheadInsert?: TypeAheadInsert;
|
|
10
|
+
};
|
|
11
|
+
export declare const createSyncedBlock: ({ tr, syncBlockStore, typeAheadInsert, }: createSyncedBlockProps) => false | Transaction;
|
|
6
12
|
export declare const copySyncedBlockReferenceToClipboard: (api?: ExtractInjectionAPI<SyncedBlockPlugin>) => Command;
|
|
7
13
|
export declare const editSyncedBlockSource: (_api?: ExtractInjectionAPI<SyncedBlockPlugin>) => Command;
|
|
8
14
|
export declare const removeSyncedBlock: (api?: ExtractInjectionAPI<SyncedBlockPlugin>) => Command;
|
|
15
|
+
export {};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
2
3
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
4
|
export declare const findSyncBlock: (state: EditorState, selection?: Selection | null) => ReturnType<ReturnType<typeof findSelectedNodeOfType>> | ReturnType<ReturnType<typeof findParentNodeOfType>>;
|
|
5
|
+
export interface SyncBlockConversionInfo {
|
|
6
|
+
contentToInclude: Fragment;
|
|
7
|
+
from: number;
|
|
8
|
+
to: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const canBeConvertedToSyncBlock: (selection: Selection) => SyncBlockConversionInfo | false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.3",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
39
39
|
"@atlaskit/editor-shared-styles": "^3.6.0",
|
|
40
40
|
"@atlaskit/editor-synced-block-provider": "^0.5.0",
|
|
41
|
+
"@atlaskit/editor-tables": "^2.9.0",
|
|
41
42
|
"@atlaskit/editor-toolbar": "^0.14.0",
|
|
42
43
|
"@atlaskit/icon": "28.5.1",
|
|
43
44
|
"@atlaskit/modal-dialog": "^14.4.0",
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
|
-
"@atlaskit/editor-common": "^110.
|
|
49
|
+
"@atlaskit/editor-common": "^110.9.0",
|
|
49
50
|
"react": "^18.2.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|