@atlaskit/editor-plugin-local-id 4.0.0 → 4.2.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 +30 -0
- package/dist/cjs/editor-actions/index.js +54 -0
- package/dist/cjs/localIdPlugin.js +7 -1
- package/dist/cjs/pm-plugins/main.js +63 -8
- package/dist/es2019/editor-actions/index.js +47 -0
- package/dist/es2019/localIdPlugin.js +8 -1
- package/dist/es2019/pm-plugins/main.js +57 -7
- package/dist/esm/editor-actions/index.js +47 -0
- package/dist/esm/localIdPlugin.js +7 -1
- package/dist/esm/pm-plugins/main.js +61 -7
- package/dist/types/editor-actions/index.d.ts +12 -0
- package/dist/types/localIdPluginType.d.ts +26 -1
- package/dist/types/pm-plugins/main.d.ts +6 -0
- package/dist/types-ts4.5/editor-actions/index.d.ts +12 -0
- package/dist/types-ts4.5/localIdPluginType.d.ts +26 -1
- package/dist/types-ts4.5/pm-plugins/main.d.ts +6 -0
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-local-id
|
|
2
2
|
|
|
3
|
+
## 4.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`5167552fe1a93`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5167552fe1a93) -
|
|
8
|
+
[EDITOR-2339] Bump @atlaskit/adf-schema to 51.3.0
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
14
|
+
## 4.1.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- [`1b290cb1f993b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1b290cb1f993b) -
|
|
19
|
+
Adds actions to get and replace nodes by their localId
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// Replace a local id with a ProseMirror node
|
|
23
|
+
api?.localId.actions.replaceNode({ localId: 'example-id', value: node });
|
|
24
|
+
|
|
25
|
+
// Get a prosemirror node based on its local id
|
|
26
|
+
api?.localId.actions.getNode({ localId: 'example-id' });
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies
|
|
32
|
+
|
|
3
33
|
## 4.0.0
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.findNodeByLocalId = findNodeByLocalId;
|
|
7
|
+
exports.replaceNode = exports.getNode = void 0;
|
|
8
|
+
function findNodeByLocalId(tr, localId) {
|
|
9
|
+
var result;
|
|
10
|
+
tr.doc.descendants(function (node, pos) {
|
|
11
|
+
if (result) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (node.attrs.localId === localId) {
|
|
15
|
+
result = {
|
|
16
|
+
node: node,
|
|
17
|
+
pos: pos
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return result === undefined;
|
|
21
|
+
});
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
var replaceNode = exports.replaceNode = function replaceNode(api) {
|
|
25
|
+
return function (_ref) {
|
|
26
|
+
var _api$core$actions$exe;
|
|
27
|
+
var localId = _ref.localId,
|
|
28
|
+
value = _ref.value;
|
|
29
|
+
var nodeWithPos = getNode(api)({
|
|
30
|
+
localId: localId
|
|
31
|
+
});
|
|
32
|
+
if (!nodeWithPos) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
var pos = nodeWithPos.pos,
|
|
36
|
+
node = nodeWithPos.node;
|
|
37
|
+
return (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref2) {
|
|
38
|
+
var tr = _ref2.tr;
|
|
39
|
+
return tr.replaceWith(pos, pos + node.nodeSize, value).scrollIntoView();
|
|
40
|
+
})) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
var getNode = exports.getNode = function getNode(api) {
|
|
44
|
+
return function (_ref3) {
|
|
45
|
+
var localId = _ref3.localId;
|
|
46
|
+
var result;
|
|
47
|
+
api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
|
|
48
|
+
var tr = _ref4.tr;
|
|
49
|
+
result = findNodeByLocalId(tr, localId);
|
|
50
|
+
return null;
|
|
51
|
+
});
|
|
52
|
+
return result;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -4,10 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.localIdPlugin = void 0;
|
|
7
|
+
var _editorActions = require("./editor-actions");
|
|
7
8
|
var _main = require("./pm-plugins/main");
|
|
8
|
-
var localIdPlugin = exports.localIdPlugin = function localIdPlugin() {
|
|
9
|
+
var localIdPlugin = exports.localIdPlugin = function localIdPlugin(_ref) {
|
|
10
|
+
var api = _ref.api;
|
|
9
11
|
return {
|
|
10
12
|
name: 'localId',
|
|
13
|
+
actions: {
|
|
14
|
+
replaceNode: (0, _editorActions.replaceNode)(api),
|
|
15
|
+
getNode: (0, _editorActions.getNode)(api)
|
|
16
|
+
},
|
|
11
17
|
pmPlugins: function pmPlugins() {
|
|
12
18
|
return [{
|
|
13
19
|
name: 'localIdPlugin',
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
|
-
exports.localIdPluginKey = exports.createPlugin = exports.addLocalIdToNode = void 0;
|
|
7
|
+
exports.localIdPluginKey = exports.createPlugin = exports.batchAddLocalIdToNodes = exports.addLocalIdToNode = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
7
9
|
var _adfSchema = require("@atlaskit/adf-schema");
|
|
10
|
+
var _steps = require("@atlaskit/adf-schema/steps");
|
|
8
11
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
9
12
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
10
13
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
@@ -35,6 +38,8 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
35
38
|
requestIdleCallbackWithFallback(function () {
|
|
36
39
|
var tr = editorView.state.tr;
|
|
37
40
|
var localIdWasAdded = false;
|
|
41
|
+
var nodesToUpdate = new Map(); // position -> localId
|
|
42
|
+
|
|
38
43
|
var _editorView$state$sch = editorView.state.schema.nodes,
|
|
39
44
|
text = _editorView$state$sch.text,
|
|
40
45
|
hardBreak = _editorView$state$sch.hardBreak,
|
|
@@ -45,14 +50,21 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
45
50
|
editorView.state.doc.descendants(function (node, pos) {
|
|
46
51
|
var _node$type$spec$attrs;
|
|
47
52
|
if (!ignoredNodeTypes.includes(node.type.name) && !node.attrs.localId && !!((_node$type$spec$attrs = node.type.spec.attrs) !== null && _node$type$spec$attrs !== void 0 && _node$type$spec$attrs.localId)) {
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
54
|
+
nodesToUpdate.set(pos, _adfSchema.uuid.generate());
|
|
55
|
+
} else {
|
|
56
|
+
localIdWasAdded = true;
|
|
57
|
+
addLocalIdToNode(pos, tr);
|
|
58
|
+
}
|
|
50
59
|
}
|
|
51
60
|
return true; // Continue traversing
|
|
52
61
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
63
|
+
if (nodesToUpdate.size > 0) {
|
|
64
|
+
batchAddLocalIdToNodes(nodesToUpdate, tr);
|
|
65
|
+
editorView.dispatch(tr);
|
|
66
|
+
}
|
|
67
|
+
} else if (localIdWasAdded) {
|
|
56
68
|
tr.setMeta('addToHistory', false);
|
|
57
69
|
editorView.dispatch(tr);
|
|
58
70
|
}
|
|
@@ -78,6 +90,7 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
78
90
|
var addedNodes = new Set();
|
|
79
91
|
var addedNodePos = new Map();
|
|
80
92
|
var localIds = new Set();
|
|
93
|
+
var nodesToUpdate = new Map(); // position -> localId
|
|
81
94
|
|
|
82
95
|
// Process only the nodes added in the transactions
|
|
83
96
|
transactions.forEach(function (transaction) {
|
|
@@ -114,7 +127,12 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
114
127
|
addedNodePos.set(node, pos);
|
|
115
128
|
} else {
|
|
116
129
|
if (!(node !== null && node !== void 0 && node.attrs.localId)) {
|
|
117
|
-
|
|
130
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
131
|
+
nodesToUpdate.set(pos, _adfSchema.uuid.generate());
|
|
132
|
+
} else {
|
|
133
|
+
// Legacy behavior - individual steps
|
|
134
|
+
addLocalIdToNode(pos, tr);
|
|
135
|
+
}
|
|
118
136
|
}
|
|
119
137
|
}
|
|
120
138
|
return true;
|
|
@@ -138,7 +156,11 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
138
156
|
if (!node.attrs.localId || localIds.has(node.attrs.localId)) {
|
|
139
157
|
var pos = addedNodePos.get(node);
|
|
140
158
|
if (pos !== undefined) {
|
|
141
|
-
|
|
159
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
160
|
+
nodesToUpdate.set(pos, _adfSchema.uuid.generate());
|
|
161
|
+
} else {
|
|
162
|
+
addLocalIdToNode(pos, tr);
|
|
163
|
+
}
|
|
142
164
|
modified = true;
|
|
143
165
|
}
|
|
144
166
|
}
|
|
@@ -149,6 +171,13 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
149
171
|
_iterator.f();
|
|
150
172
|
}
|
|
151
173
|
}
|
|
174
|
+
|
|
175
|
+
// Apply local ID updates based on the improvements feature flag:
|
|
176
|
+
// - When enabled: Batch all updates into a single BatchAttrsStep
|
|
177
|
+
// - When disabled: Individual steps were already applied above during node processing
|
|
178
|
+
if (modified && nodesToUpdate.size > 0 && (0, _platformFeatureFlags.fg)('platform_editor_localid_improvements')) {
|
|
179
|
+
batchAddLocalIdToNodes(nodesToUpdate, tr);
|
|
180
|
+
}
|
|
152
181
|
return modified ? tr : undefined;
|
|
153
182
|
}
|
|
154
183
|
});
|
|
@@ -164,4 +193,30 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
164
193
|
var addLocalIdToNode = exports.addLocalIdToNode = function addLocalIdToNode(pos, tr) {
|
|
165
194
|
tr.setNodeAttribute(pos, 'localId', _adfSchema.uuid.generate());
|
|
166
195
|
tr.setMeta('addToHistory', false);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
200
|
+
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
|
201
|
+
* @param tr
|
|
202
|
+
*/
|
|
203
|
+
var batchAddLocalIdToNodes = exports.batchAddLocalIdToNodes = function batchAddLocalIdToNodes(nodesToUpdate, tr) {
|
|
204
|
+
var batchData = Array.from(nodesToUpdate.entries()).map(function (_ref) {
|
|
205
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
206
|
+
pos = _ref2[0],
|
|
207
|
+
localId = _ref2[1];
|
|
208
|
+
var node = tr.doc.nodeAt(pos);
|
|
209
|
+
if (!node) {
|
|
210
|
+
throw new Error("Node does not exist at position ".concat(pos));
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
position: pos,
|
|
214
|
+
attrs: {
|
|
215
|
+
localId: localId
|
|
216
|
+
},
|
|
217
|
+
nodeType: node.type.name
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
tr.step(new _steps.BatchAttrsStep(batchData));
|
|
221
|
+
tr.setMeta('addToHistory', false);
|
|
167
222
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export function findNodeByLocalId(tr, localId) {
|
|
2
|
+
let result;
|
|
3
|
+
tr.doc.descendants((node, pos) => {
|
|
4
|
+
if (result) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (node.attrs.localId === localId) {
|
|
8
|
+
result = {
|
|
9
|
+
node,
|
|
10
|
+
pos
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return result === undefined;
|
|
14
|
+
});
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
export const replaceNode = api => ({
|
|
18
|
+
localId,
|
|
19
|
+
value
|
|
20
|
+
}) => {
|
|
21
|
+
var _api$core$actions$exe;
|
|
22
|
+
const nodeWithPos = getNode(api)({
|
|
23
|
+
localId
|
|
24
|
+
});
|
|
25
|
+
if (!nodeWithPos) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const {
|
|
29
|
+
pos,
|
|
30
|
+
node
|
|
31
|
+
} = nodeWithPos;
|
|
32
|
+
return (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(({
|
|
33
|
+
tr
|
|
34
|
+
}) => tr.replaceWith(pos, pos + node.nodeSize, value).scrollIntoView())) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false;
|
|
35
|
+
};
|
|
36
|
+
export const getNode = api => ({
|
|
37
|
+
localId
|
|
38
|
+
}) => {
|
|
39
|
+
let result;
|
|
40
|
+
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
|
|
41
|
+
tr
|
|
42
|
+
}) => {
|
|
43
|
+
result = findNodeByLocalId(tr, localId);
|
|
44
|
+
return null;
|
|
45
|
+
});
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { replaceNode, getNode } from './editor-actions';
|
|
1
2
|
import { createPlugin } from './pm-plugins/main';
|
|
2
|
-
export const localIdPlugin = (
|
|
3
|
+
export const localIdPlugin = ({
|
|
4
|
+
api
|
|
5
|
+
}) => ({
|
|
3
6
|
name: 'localId',
|
|
7
|
+
actions: {
|
|
8
|
+
replaceNode: replaceNode(api),
|
|
9
|
+
getNode: getNode(api)
|
|
10
|
+
},
|
|
4
11
|
pmPlugins() {
|
|
5
12
|
return [{
|
|
6
13
|
name: 'localIdPlugin',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { uuid } from '@atlaskit/adf-schema';
|
|
2
|
+
import { BatchAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
2
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
4
|
import { stepHasSlice } from '@atlaskit/editor-common/utils';
|
|
4
5
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
@@ -26,6 +27,8 @@ export const createPlugin = () => {
|
|
|
26
27
|
requestIdleCallbackWithFallback(() => {
|
|
27
28
|
const tr = editorView.state.tr;
|
|
28
29
|
let localIdWasAdded = false;
|
|
30
|
+
const nodesToUpdate = new Map(); // position -> localId
|
|
31
|
+
|
|
29
32
|
const {
|
|
30
33
|
text,
|
|
31
34
|
hardBreak,
|
|
@@ -37,14 +40,21 @@ export const createPlugin = () => {
|
|
|
37
40
|
editorView.state.doc.descendants((node, pos) => {
|
|
38
41
|
var _node$type$spec$attrs;
|
|
39
42
|
if (!ignoredNodeTypes.includes(node.type.name) && !node.attrs.localId && !!((_node$type$spec$attrs = node.type.spec.attrs) !== null && _node$type$spec$attrs !== void 0 && _node$type$spec$attrs.localId)) {
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
44
|
+
nodesToUpdate.set(pos, uuid.generate());
|
|
45
|
+
} else {
|
|
46
|
+
localIdWasAdded = true;
|
|
47
|
+
addLocalIdToNode(pos, tr);
|
|
48
|
+
}
|
|
42
49
|
}
|
|
43
50
|
return true; // Continue traversing
|
|
44
51
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
53
|
+
if (nodesToUpdate.size > 0) {
|
|
54
|
+
batchAddLocalIdToNodes(nodesToUpdate, tr);
|
|
55
|
+
editorView.dispatch(tr);
|
|
56
|
+
}
|
|
57
|
+
} else if (localIdWasAdded) {
|
|
48
58
|
tr.setMeta('addToHistory', false);
|
|
49
59
|
editorView.dispatch(tr);
|
|
50
60
|
}
|
|
@@ -71,6 +81,7 @@ export const createPlugin = () => {
|
|
|
71
81
|
const addedNodes = new Set();
|
|
72
82
|
const addedNodePos = new Map();
|
|
73
83
|
const localIds = new Set();
|
|
84
|
+
const nodesToUpdate = new Map(); // position -> localId
|
|
74
85
|
|
|
75
86
|
// Process only the nodes added in the transactions
|
|
76
87
|
transactions.forEach(transaction => {
|
|
@@ -107,7 +118,12 @@ export const createPlugin = () => {
|
|
|
107
118
|
addedNodePos.set(node, pos);
|
|
108
119
|
} else {
|
|
109
120
|
if (!(node !== null && node !== void 0 && node.attrs.localId)) {
|
|
110
|
-
|
|
121
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
122
|
+
nodesToUpdate.set(pos, uuid.generate());
|
|
123
|
+
} else {
|
|
124
|
+
// Legacy behavior - individual steps
|
|
125
|
+
addLocalIdToNode(pos, tr);
|
|
126
|
+
}
|
|
111
127
|
}
|
|
112
128
|
}
|
|
113
129
|
return true;
|
|
@@ -127,12 +143,23 @@ export const createPlugin = () => {
|
|
|
127
143
|
if (!node.attrs.localId || localIds.has(node.attrs.localId)) {
|
|
128
144
|
const pos = addedNodePos.get(node);
|
|
129
145
|
if (pos !== undefined) {
|
|
130
|
-
|
|
146
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
147
|
+
nodesToUpdate.set(pos, uuid.generate());
|
|
148
|
+
} else {
|
|
149
|
+
addLocalIdToNode(pos, tr);
|
|
150
|
+
}
|
|
131
151
|
modified = true;
|
|
132
152
|
}
|
|
133
153
|
}
|
|
134
154
|
}
|
|
135
155
|
}
|
|
156
|
+
|
|
157
|
+
// Apply local ID updates based on the improvements feature flag:
|
|
158
|
+
// - When enabled: Batch all updates into a single BatchAttrsStep
|
|
159
|
+
// - When disabled: Individual steps were already applied above during node processing
|
|
160
|
+
if (modified && nodesToUpdate.size > 0 && fg('platform_editor_localid_improvements')) {
|
|
161
|
+
batchAddLocalIdToNodes(nodesToUpdate, tr);
|
|
162
|
+
}
|
|
136
163
|
return modified ? tr : undefined;
|
|
137
164
|
}
|
|
138
165
|
});
|
|
@@ -148,4 +175,27 @@ export const createPlugin = () => {
|
|
|
148
175
|
export const addLocalIdToNode = (pos, tr) => {
|
|
149
176
|
tr.setNodeAttribute(pos, 'localId', uuid.generate());
|
|
150
177
|
tr.setMeta('addToHistory', false);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
182
|
+
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
|
183
|
+
* @param tr
|
|
184
|
+
*/
|
|
185
|
+
export const batchAddLocalIdToNodes = (nodesToUpdate, tr) => {
|
|
186
|
+
const batchData = Array.from(nodesToUpdate.entries()).map(([pos, localId]) => {
|
|
187
|
+
const node = tr.doc.nodeAt(pos);
|
|
188
|
+
if (!node) {
|
|
189
|
+
throw new Error(`Node does not exist at position ${pos}`);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
position: pos,
|
|
193
|
+
attrs: {
|
|
194
|
+
localId
|
|
195
|
+
},
|
|
196
|
+
nodeType: node.type.name
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
tr.step(new BatchAttrsStep(batchData));
|
|
200
|
+
tr.setMeta('addToHistory', false);
|
|
151
201
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export function findNodeByLocalId(tr, localId) {
|
|
2
|
+
var result;
|
|
3
|
+
tr.doc.descendants(function (node, pos) {
|
|
4
|
+
if (result) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (node.attrs.localId === localId) {
|
|
8
|
+
result = {
|
|
9
|
+
node: node,
|
|
10
|
+
pos: pos
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return result === undefined;
|
|
14
|
+
});
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
export var replaceNode = function replaceNode(api) {
|
|
18
|
+
return function (_ref) {
|
|
19
|
+
var _api$core$actions$exe;
|
|
20
|
+
var localId = _ref.localId,
|
|
21
|
+
value = _ref.value;
|
|
22
|
+
var nodeWithPos = getNode(api)({
|
|
23
|
+
localId: localId
|
|
24
|
+
});
|
|
25
|
+
if (!nodeWithPos) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
var pos = nodeWithPos.pos,
|
|
29
|
+
node = nodeWithPos.node;
|
|
30
|
+
return (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref2) {
|
|
31
|
+
var tr = _ref2.tr;
|
|
32
|
+
return tr.replaceWith(pos, pos + node.nodeSize, value).scrollIntoView();
|
|
33
|
+
})) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export var getNode = function getNode(api) {
|
|
37
|
+
return function (_ref3) {
|
|
38
|
+
var localId = _ref3.localId;
|
|
39
|
+
var result;
|
|
40
|
+
api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
|
|
41
|
+
var tr = _ref4.tr;
|
|
42
|
+
result = findNodeByLocalId(tr, localId);
|
|
43
|
+
return null;
|
|
44
|
+
});
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import { replaceNode, getNode } from './editor-actions';
|
|
1
2
|
import { createPlugin } from './pm-plugins/main';
|
|
2
|
-
export var localIdPlugin = function localIdPlugin() {
|
|
3
|
+
export var localIdPlugin = function localIdPlugin(_ref) {
|
|
4
|
+
var api = _ref.api;
|
|
3
5
|
return {
|
|
4
6
|
name: 'localId',
|
|
7
|
+
actions: {
|
|
8
|
+
replaceNode: replaceNode(api),
|
|
9
|
+
getNode: getNode(api)
|
|
10
|
+
},
|
|
5
11
|
pmPlugins: function pmPlugins() {
|
|
6
12
|
return [{
|
|
7
13
|
name: 'localIdPlugin',
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
2
3
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
3
4
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
4
5
|
import { uuid } from '@atlaskit/adf-schema';
|
|
6
|
+
import { BatchAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
5
7
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
8
|
import { stepHasSlice } from '@atlaskit/editor-common/utils';
|
|
7
9
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
@@ -29,6 +31,8 @@ export var createPlugin = function createPlugin() {
|
|
|
29
31
|
requestIdleCallbackWithFallback(function () {
|
|
30
32
|
var tr = editorView.state.tr;
|
|
31
33
|
var localIdWasAdded = false;
|
|
34
|
+
var nodesToUpdate = new Map(); // position -> localId
|
|
35
|
+
|
|
32
36
|
var _editorView$state$sch = editorView.state.schema.nodes,
|
|
33
37
|
text = _editorView$state$sch.text,
|
|
34
38
|
hardBreak = _editorView$state$sch.hardBreak,
|
|
@@ -39,14 +43,21 @@ export var createPlugin = function createPlugin() {
|
|
|
39
43
|
editorView.state.doc.descendants(function (node, pos) {
|
|
40
44
|
var _node$type$spec$attrs;
|
|
41
45
|
if (!ignoredNodeTypes.includes(node.type.name) && !node.attrs.localId && !!((_node$type$spec$attrs = node.type.spec.attrs) !== null && _node$type$spec$attrs !== void 0 && _node$type$spec$attrs.localId)) {
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
47
|
+
nodesToUpdate.set(pos, uuid.generate());
|
|
48
|
+
} else {
|
|
49
|
+
localIdWasAdded = true;
|
|
50
|
+
addLocalIdToNode(pos, tr);
|
|
51
|
+
}
|
|
44
52
|
}
|
|
45
53
|
return true; // Continue traversing
|
|
46
54
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
56
|
+
if (nodesToUpdate.size > 0) {
|
|
57
|
+
batchAddLocalIdToNodes(nodesToUpdate, tr);
|
|
58
|
+
editorView.dispatch(tr);
|
|
59
|
+
}
|
|
60
|
+
} else if (localIdWasAdded) {
|
|
50
61
|
tr.setMeta('addToHistory', false);
|
|
51
62
|
editorView.dispatch(tr);
|
|
52
63
|
}
|
|
@@ -72,6 +83,7 @@ export var createPlugin = function createPlugin() {
|
|
|
72
83
|
var addedNodes = new Set();
|
|
73
84
|
var addedNodePos = new Map();
|
|
74
85
|
var localIds = new Set();
|
|
86
|
+
var nodesToUpdate = new Map(); // position -> localId
|
|
75
87
|
|
|
76
88
|
// Process only the nodes added in the transactions
|
|
77
89
|
transactions.forEach(function (transaction) {
|
|
@@ -108,7 +120,12 @@ export var createPlugin = function createPlugin() {
|
|
|
108
120
|
addedNodePos.set(node, pos);
|
|
109
121
|
} else {
|
|
110
122
|
if (!(node !== null && node !== void 0 && node.attrs.localId)) {
|
|
111
|
-
|
|
123
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
124
|
+
nodesToUpdate.set(pos, uuid.generate());
|
|
125
|
+
} else {
|
|
126
|
+
// Legacy behavior - individual steps
|
|
127
|
+
addLocalIdToNode(pos, tr);
|
|
128
|
+
}
|
|
112
129
|
}
|
|
113
130
|
}
|
|
114
131
|
return true;
|
|
@@ -132,7 +149,11 @@ export var createPlugin = function createPlugin() {
|
|
|
132
149
|
if (!node.attrs.localId || localIds.has(node.attrs.localId)) {
|
|
133
150
|
var pos = addedNodePos.get(node);
|
|
134
151
|
if (pos !== undefined) {
|
|
135
|
-
|
|
152
|
+
if (fg('platform_editor_localid_improvements')) {
|
|
153
|
+
nodesToUpdate.set(pos, uuid.generate());
|
|
154
|
+
} else {
|
|
155
|
+
addLocalIdToNode(pos, tr);
|
|
156
|
+
}
|
|
136
157
|
modified = true;
|
|
137
158
|
}
|
|
138
159
|
}
|
|
@@ -143,6 +164,13 @@ export var createPlugin = function createPlugin() {
|
|
|
143
164
|
_iterator.f();
|
|
144
165
|
}
|
|
145
166
|
}
|
|
167
|
+
|
|
168
|
+
// Apply local ID updates based on the improvements feature flag:
|
|
169
|
+
// - When enabled: Batch all updates into a single BatchAttrsStep
|
|
170
|
+
// - When disabled: Individual steps were already applied above during node processing
|
|
171
|
+
if (modified && nodesToUpdate.size > 0 && fg('platform_editor_localid_improvements')) {
|
|
172
|
+
batchAddLocalIdToNodes(nodesToUpdate, tr);
|
|
173
|
+
}
|
|
146
174
|
return modified ? tr : undefined;
|
|
147
175
|
}
|
|
148
176
|
});
|
|
@@ -158,4 +186,30 @@ export var createPlugin = function createPlugin() {
|
|
|
158
186
|
export var addLocalIdToNode = function addLocalIdToNode(pos, tr) {
|
|
159
187
|
tr.setNodeAttribute(pos, 'localId', uuid.generate());
|
|
160
188
|
tr.setMeta('addToHistory', false);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
193
|
+
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
|
194
|
+
* @param tr
|
|
195
|
+
*/
|
|
196
|
+
export var batchAddLocalIdToNodes = function batchAddLocalIdToNodes(nodesToUpdate, tr) {
|
|
197
|
+
var batchData = Array.from(nodesToUpdate.entries()).map(function (_ref) {
|
|
198
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
199
|
+
pos = _ref2[0],
|
|
200
|
+
localId = _ref2[1];
|
|
201
|
+
var node = tr.doc.nodeAt(pos);
|
|
202
|
+
if (!node) {
|
|
203
|
+
throw new Error("Node does not exist at position ".concat(pos));
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
position: pos,
|
|
207
|
+
attrs: {
|
|
208
|
+
localId: localId
|
|
209
|
+
},
|
|
210
|
+
nodeType: node.type.name
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
tr.step(new BatchAttrsStep(batchData));
|
|
214
|
+
tr.setMeta('addToHistory', false);
|
|
161
215
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { Transform } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
5
|
+
import type { ActionProps, LocalIdPlugin } from '../localIdPluginType';
|
|
6
|
+
type EditorActionProps = ActionProps;
|
|
7
|
+
export declare function findNodeByLocalId(tr: Transform, localId: string): NodeWithPos | undefined;
|
|
8
|
+
export declare const replaceNode: (api: ExtractInjectionAPI<LocalIdPlugin> | undefined) => ({ localId, value }: EditorActionProps & {
|
|
9
|
+
value: Node;
|
|
10
|
+
}) => boolean;
|
|
11
|
+
export declare const getNode: (api: ExtractInjectionAPI<LocalIdPlugin> | undefined) => ({ localId }: EditorActionProps) => NodeWithPos | undefined;
|
|
12
|
+
export {};
|
|
@@ -1,2 +1,27 @@
|
|
|
1
1
|
import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
-
|
|
2
|
+
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
+
export type ActionProps = {
|
|
5
|
+
localId: string;
|
|
6
|
+
};
|
|
7
|
+
export type LocalIdPlugin = NextEditorPlugin<'localId', {
|
|
8
|
+
actions: {
|
|
9
|
+
/**
|
|
10
|
+
* Get the node with its position in the document
|
|
11
|
+
*
|
|
12
|
+
* @param props.localId Local id of the node in question
|
|
13
|
+
* @returns { node: ProsemirrorNode, pos: number } Object containing prosemirror node and position in the document
|
|
14
|
+
*/
|
|
15
|
+
getNode: (props: ActionProps) => NodeWithPos | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Replace the node in the document by its local id
|
|
18
|
+
*
|
|
19
|
+
* @param props.localId Local id of the node in question
|
|
20
|
+
* @param props.value Prosemirror node to replace the node with
|
|
21
|
+
* @returns boolean if the replace was successful
|
|
22
|
+
*/
|
|
23
|
+
replaceNode: (props: ActionProps & {
|
|
24
|
+
value: Node;
|
|
25
|
+
}) => boolean;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
@@ -11,3 +11,9 @@ export declare const createPlugin: () => SafePlugin<any>;
|
|
|
11
11
|
* @param tr - The transaction to apply the change to
|
|
12
12
|
*/
|
|
13
13
|
export declare const addLocalIdToNode: (pos: number, tr: Transaction) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
16
|
+
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
|
17
|
+
* @param tr
|
|
18
|
+
*/
|
|
19
|
+
export declare const batchAddLocalIdToNodes: (nodesToUpdate: Map<number, string>, tr: Transaction) => void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { Transform } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
5
|
+
import type { ActionProps, LocalIdPlugin } from '../localIdPluginType';
|
|
6
|
+
type EditorActionProps = ActionProps;
|
|
7
|
+
export declare function findNodeByLocalId(tr: Transform, localId: string): NodeWithPos | undefined;
|
|
8
|
+
export declare const replaceNode: (api: ExtractInjectionAPI<LocalIdPlugin> | undefined) => ({ localId, value }: EditorActionProps & {
|
|
9
|
+
value: Node;
|
|
10
|
+
}) => boolean;
|
|
11
|
+
export declare const getNode: (api: ExtractInjectionAPI<LocalIdPlugin> | undefined) => ({ localId }: EditorActionProps) => NodeWithPos | undefined;
|
|
12
|
+
export {};
|
|
@@ -1,2 +1,27 @@
|
|
|
1
1
|
import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
-
|
|
2
|
+
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
+
export type ActionProps = {
|
|
5
|
+
localId: string;
|
|
6
|
+
};
|
|
7
|
+
export type LocalIdPlugin = NextEditorPlugin<'localId', {
|
|
8
|
+
actions: {
|
|
9
|
+
/**
|
|
10
|
+
* Get the node with its position in the document
|
|
11
|
+
*
|
|
12
|
+
* @param props.localId Local id of the node in question
|
|
13
|
+
* @returns { node: ProsemirrorNode, pos: number } Object containing prosemirror node and position in the document
|
|
14
|
+
*/
|
|
15
|
+
getNode: (props: ActionProps) => NodeWithPos | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Replace the node in the document by its local id
|
|
18
|
+
*
|
|
19
|
+
* @param props.localId Local id of the node in question
|
|
20
|
+
* @param props.value Prosemirror node to replace the node with
|
|
21
|
+
* @returns boolean if the replace was successful
|
|
22
|
+
*/
|
|
23
|
+
replaceNode: (props: ActionProps & {
|
|
24
|
+
value: Node;
|
|
25
|
+
}) => boolean;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
@@ -11,3 +11,9 @@ export declare const createPlugin: () => SafePlugin<any>;
|
|
|
11
11
|
* @param tr - The transaction to apply the change to
|
|
12
12
|
*/
|
|
13
13
|
export declare const addLocalIdToNode: (pos: number, tr: Transaction) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Batch adds local IDs to nodes using a BatchAttrsStep
|
|
16
|
+
* @param nodesToUpdate Map of position -> localId for nodes that need updates
|
|
17
|
+
* @param tr
|
|
18
|
+
*/
|
|
19
|
+
export declare const batchAddLocalIdToNodes: (nodesToUpdate: Map<number, string>, tr: Transaction) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-local-id",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "LocalId plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@atlaskit/adf-schema": "^51.
|
|
31
|
+
"@atlaskit/adf-schema": "^51.3.0",
|
|
32
32
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
33
33
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
34
34
|
"@babel/runtime": "^7.0.0",
|
|
35
35
|
"raf-schd": "^4.0.3"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@atlaskit/editor-common": "^110.
|
|
38
|
+
"@atlaskit/editor-common": "^110.14.0",
|
|
39
39
|
"react": "^18.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
@@ -80,6 +80,9 @@
|
|
|
80
80
|
"platform-feature-flags": {
|
|
81
81
|
"platform_editor_use_localid_dedupe": {
|
|
82
82
|
"type": "boolean"
|
|
83
|
+
},
|
|
84
|
+
"platform_editor_localid_improvements": {
|
|
85
|
+
"type": "boolean"
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
}
|