@atlaskit/editor-plugin-code-block 3.4.1 → 3.4.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/dist/cjs/pm-plugins/decorators.js +30 -19
- package/dist/cjs/pm-plugins/main.js +6 -4
- package/dist/cjs/utils.js +27 -0
- package/dist/es2019/pm-plugins/decorators.js +26 -14
- package/dist/es2019/pm-plugins/main.js +7 -5
- package/dist/es2019/utils.js +26 -0
- package/dist/esm/pm-plugins/decorators.js +30 -18
- package/dist/esm/pm-plugins/main.js +7 -5
- package/dist/esm/utils.js +26 -0
- package/dist/types/pm-plugins/decorators.d.ts +2 -2
- package/dist/types/utils.d.ts +2 -1
- package/dist/types-ts4.5/pm-plugins/decorators.d.ts +2 -2
- package/dist/types-ts4.5/utils.d.ts +2 -1
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-code-block
|
|
2
2
|
|
|
3
|
+
## 3.4.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#149087](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/149087)
|
|
8
|
+
[`8b2dcb618ccf8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/8b2dcb618ccf8) -
|
|
9
|
+
ED-25141: Code block wrapping performance improvement. Only update the line number decorators on a
|
|
10
|
+
given code block when a line has been added or removed. Previously was updating line number
|
|
11
|
+
decorators on every update for all code blocks.
|
|
12
|
+
|
|
13
|
+
## 3.4.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 3.4.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.validateWordWrappedDecorators = exports.updateDecorationSetWithWordWrappedDecorator = exports.updateDecorationSetWithLineNumberDecorators = exports.updateCodeBlockDecorations = exports.getWordWrapDecoratorsFromNodePos = exports.generateLineAttributesFromNode = exports.generateInitialDecorations = exports.
|
|
7
|
+
exports.validateWordWrappedDecorators = exports.updateDecorationSetWithWordWrappedDecorator = exports.updateDecorationSetWithLineNumberDecorators = exports.updateCodeBlockDecorations = exports.getWordWrapDecoratorsFromNodePos = exports.generateLineAttributesFromNode = exports.generateInitialDecorations = exports.createDecorationSetFromLineAttributes = exports.DECORATION_WRAPPED_BLOCK_NODE_TYPE = exports.DECORATION_WIDGET_TYPE = void 0;
|
|
8
8
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
9
|
var _codeBlock = require("@atlaskit/editor-common/code-block");
|
|
10
10
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
@@ -22,7 +22,7 @@ var DECORATION_WRAPPED_BLOCK_NODE_TYPE = exports.DECORATION_WRAPPED_BLOCK_NODE_T
|
|
|
22
22
|
var generateInitialDecorations = exports.generateInitialDecorations = function generateInitialDecorations(state) {
|
|
23
23
|
var codeBlockNodes = (0, _utils.getAllCodeBlockNodesInDoc)(state);
|
|
24
24
|
return codeBlockNodes.flatMap(function (node) {
|
|
25
|
-
return
|
|
25
|
+
return createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node));
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -31,8 +31,7 @@ var generateInitialDecorations = exports.generateInitialDecorations = function g
|
|
|
31
31
|
*/
|
|
32
32
|
var updateCodeBlockDecorations = exports.updateCodeBlockDecorations = function updateCodeBlockDecorations(tr, codeBlockNodes, decorationSet) {
|
|
33
33
|
var updatedDecorationSet = decorationSet;
|
|
34
|
-
|
|
35
|
-
// All the line numbers decorators are refreshed on doc change.
|
|
34
|
+
// Update line number decorators for changed code block nodes if new line added or line removed.
|
|
36
35
|
updatedDecorationSet = updateDecorationSetWithLineNumberDecorators(tr, codeBlockNodes, updatedDecorationSet);
|
|
37
36
|
|
|
38
37
|
// Check to make sure the word wrap decorators are still valid.
|
|
@@ -41,23 +40,36 @@ var updateCodeBlockDecorations = exports.updateCodeBlockDecorations = function u
|
|
|
41
40
|
};
|
|
42
41
|
|
|
43
42
|
/**
|
|
44
|
-
* Update the decorations set with the line number decorators.
|
|
43
|
+
* Update the decorations set with the line number decorators. This will only happen for the code blocks passed to this function
|
|
44
|
+
* when there has been a new line added or removed. The line decorations will not update the code block node otherwise.
|
|
45
45
|
*/
|
|
46
46
|
var updateDecorationSetWithLineNumberDecorators = exports.updateDecorationSetWithLineNumberDecorators = function updateDecorationSetWithLineNumberDecorators(tr, codeBlockNodes, decorationSet) {
|
|
47
47
|
var updatedDecorationSet = decorationSet;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// regenerate all the line number for the documents code blocks
|
|
48
|
+
if (!(0, _platformFeatureFlags.fg)('editor_code_wrapping_perf_improvement_ed-25141')) {
|
|
49
|
+
var children = updatedDecorationSet.find(undefined, undefined, function (spec) {
|
|
50
|
+
return spec.type === DECORATION_WIDGET_TYPE;
|
|
51
|
+
});
|
|
52
|
+
updatedDecorationSet = updatedDecorationSet.remove(children);
|
|
53
|
+
}
|
|
55
54
|
var lineNumberDecorators = [];
|
|
56
55
|
codeBlockNodes.forEach(function (node) {
|
|
57
|
-
|
|
56
|
+
if ((0, _platformFeatureFlags.fg)('editor_code_wrapping_perf_improvement_ed-25141')) {
|
|
57
|
+
var existingWidgetsOnNode = updatedDecorationSet.find(node.pos, node.pos + node.node.nodeSize, function (spec) {
|
|
58
|
+
return spec.type === DECORATION_WIDGET_TYPE;
|
|
59
|
+
});
|
|
60
|
+
var newLineAttributes = generateLineAttributesFromNode(node);
|
|
61
|
+
|
|
62
|
+
// There will be no widgets on initialisation. If the number of existing widgets does not equal the amount of lines, regenerate the widgets.
|
|
63
|
+
// There may be a case where the number of existing widgets and the number of lines are the same, that's why we track totalLineCount. This allows
|
|
64
|
+
// us to know how many lines there were when the widget was created. It avoids a break in line numbers, e.g. "1, 2, 3, 5, 6". Happens on line removal.
|
|
65
|
+
if (existingWidgetsOnNode.length === 0 || existingWidgetsOnNode.length !== newLineAttributes.length || existingWidgetsOnNode[0].spec.totalLineCount !== newLineAttributes.length) {
|
|
66
|
+
updatedDecorationSet = updatedDecorationSet.remove(existingWidgetsOnNode);
|
|
67
|
+
lineNumberDecorators.push.apply(lineNumberDecorators, (0, _toConsumableArray2.default)(createDecorationSetFromLineAttributes(newLineAttributes)));
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
lineNumberDecorators.push.apply(lineNumberDecorators, (0, _toConsumableArray2.default)(createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node))));
|
|
71
|
+
}
|
|
58
72
|
});
|
|
59
|
-
|
|
60
|
-
// add the newly generated line numbers to the decorations set
|
|
61
73
|
return updatedDecorationSet.add(tr.doc, [].concat(lineNumberDecorators));
|
|
62
74
|
};
|
|
63
75
|
var generateLineAttributesFromNode = exports.generateLineAttributesFromNode = function generateLineAttributesFromNode(node) {
|
|
@@ -110,16 +122,15 @@ var createDecorationSetFromLineAttributes = exports.createDecorationSetFromLineA
|
|
|
110
122
|
};
|
|
111
123
|
|
|
112
124
|
// side -1 is used so the line numbers are the first thing to the left of the lines of code.
|
|
125
|
+
// totalLineCount is used to know whether or not to update the line numbers when a new line is added or removed.
|
|
113
126
|
return _view.Decoration.widget(lineStart, createLineNumberWidget, {
|
|
114
127
|
type: DECORATION_WIDGET_TYPE,
|
|
115
|
-
side: -1
|
|
128
|
+
side: -1,
|
|
129
|
+
totalLineCount: (0, _platformFeatureFlags.fg)('editor_code_wrapping_perf_improvement_ed-25141') ? lineAttributes.length : undefined
|
|
116
130
|
});
|
|
117
131
|
});
|
|
118
132
|
return widgetDecorations;
|
|
119
133
|
};
|
|
120
|
-
var createLineNumbersDecorations = exports.createLineNumbersDecorations = function createLineNumbersDecorations(node) {
|
|
121
|
-
return createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node));
|
|
122
|
-
};
|
|
123
134
|
|
|
124
135
|
/**
|
|
125
136
|
* There are edge cases like when a user drags and drops a code block node where the decorator breaks and no longer reflects
|
|
@@ -98,11 +98,13 @@ var createPlugin = exports.createPlugin = function createPlugin(_ref) {
|
|
|
98
98
|
// specifically used for updating word wrap node decorators (does not cover drag & drop, validateWordWrappedDecorators does).
|
|
99
99
|
var updatedDecorationSet = pluginState.decorations.map(tr.mapping, tr.doc);
|
|
100
100
|
if ((0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping')) {
|
|
101
|
-
var codeBlockNodes = (0, _utils.getAllCodeBlockNodesInDoc)(newState);
|
|
102
|
-
if (
|
|
103
|
-
(0,
|
|
101
|
+
var codeBlockNodes = (0, _platformFeatureFlags.fg)('editor_code_wrapping_perf_improvement_ed-25141') ? (0, _utils.getAllChangedCodeBlocksInTransaction)(tr, newState) : (0, _utils.getAllCodeBlockNodesInDoc)(newState);
|
|
102
|
+
if (codeBlockNodes) {
|
|
103
|
+
if ((0, _platformFeatureFlags.fg)('editor_code_block_wrapping_language_change_bug')) {
|
|
104
|
+
(0, _codeBlock.updateCodeBlockWrappedStateNodeKeys)(codeBlockNodes, _oldState);
|
|
105
|
+
}
|
|
106
|
+
updatedDecorationSet = (0, _decorators.updateCodeBlockDecorations)(tr, codeBlockNodes, updatedDecorationSet);
|
|
104
107
|
}
|
|
105
|
-
updatedDecorationSet = (0, _decorators.updateCodeBlockDecorations)(tr, codeBlockNodes, updatedDecorationSet);
|
|
106
108
|
}
|
|
107
109
|
var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
108
110
|
pos: _node ? _node.pos : null,
|
package/dist/cjs/utils.js
CHANGED
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "findCodeBlock", {
|
|
|
9
9
|
return _transforms.findCodeBlock;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
exports.getAllChangedCodeBlocksInTransaction = getAllChangedCodeBlocksInTransaction;
|
|
12
13
|
exports.getAllCodeBlockNodesInDoc = getAllCodeBlockNodesInDoc;
|
|
13
14
|
exports.getCursor = getCursor;
|
|
14
15
|
Object.defineProperty(exports, "transformSingleLineCodeBlockToCodeMark", {
|
|
@@ -27,6 +28,8 @@ var _transforms = require("@atlaskit/editor-common/transforms");
|
|
|
27
28
|
function getCursor(selection) {
|
|
28
29
|
return selection.$cursor || undefined;
|
|
29
30
|
}
|
|
31
|
+
|
|
32
|
+
// Replaced by getAllChangedCodeBlocksInTransaction with FG editor_code_wrapping_perf_improvement_ed-25141.
|
|
30
33
|
function getAllCodeBlockNodesInDoc(state) {
|
|
31
34
|
var codeBlockNodes = [];
|
|
32
35
|
state.doc.descendants(function (node, pos) {
|
|
@@ -40,4 +43,28 @@ function getAllCodeBlockNodesInDoc(state) {
|
|
|
40
43
|
return true;
|
|
41
44
|
});
|
|
42
45
|
return codeBlockNodes;
|
|
46
|
+
}
|
|
47
|
+
function getAllChangedCodeBlocksInTransaction(tr, state) {
|
|
48
|
+
var changedCodeBlocks = [];
|
|
49
|
+
var nodePositions = new Set();
|
|
50
|
+
tr.steps.forEach(function (step) {
|
|
51
|
+
var mapResult = step.getMap();
|
|
52
|
+
mapResult.forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
53
|
+
state.doc.nodesBetween(newStart, newEnd, function (node, pos) {
|
|
54
|
+
if (node.type.name === 'codeBlock') {
|
|
55
|
+
if (!nodePositions.has(pos)) {
|
|
56
|
+
nodePositions.add(pos);
|
|
57
|
+
changedCodeBlocks.push({
|
|
58
|
+
node: node,
|
|
59
|
+
pos: pos
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
if (changedCodeBlocks.length < 1) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return changedCodeBlocks;
|
|
43
70
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
|
|
2
|
+
|
|
2
3
|
import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
3
4
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
4
5
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -12,7 +13,7 @@ export const DECORATION_WRAPPED_BLOCK_NODE_TYPE = 'decorationNodeType';
|
|
|
12
13
|
*/
|
|
13
14
|
export const generateInitialDecorations = state => {
|
|
14
15
|
const codeBlockNodes = getAllCodeBlockNodesInDoc(state);
|
|
15
|
-
return codeBlockNodes.flatMap(node =>
|
|
16
|
+
return codeBlockNodes.flatMap(node => createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node)));
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -20,8 +21,7 @@ export const generateInitialDecorations = state => {
|
|
|
20
21
|
*/
|
|
21
22
|
export const updateCodeBlockDecorations = (tr, codeBlockNodes, decorationSet) => {
|
|
22
23
|
let updatedDecorationSet = decorationSet;
|
|
23
|
-
|
|
24
|
-
// All the line numbers decorators are refreshed on doc change.
|
|
24
|
+
// Update line number decorators for changed code block nodes if new line added or line removed.
|
|
25
25
|
updatedDecorationSet = updateDecorationSetWithLineNumberDecorators(tr, codeBlockNodes, updatedDecorationSet);
|
|
26
26
|
|
|
27
27
|
// Check to make sure the word wrap decorators are still valid.
|
|
@@ -30,21 +30,32 @@ export const updateCodeBlockDecorations = (tr, codeBlockNodes, decorationSet) =>
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* Update the decorations set with the line number decorators.
|
|
33
|
+
* Update the decorations set with the line number decorators. This will only happen for the code blocks passed to this function
|
|
34
|
+
* when there has been a new line added or removed. The line decorations will not update the code block node otherwise.
|
|
34
35
|
*/
|
|
35
36
|
export const updateDecorationSetWithLineNumberDecorators = (tr, codeBlockNodes, decorationSet) => {
|
|
36
37
|
let updatedDecorationSet = decorationSet;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// regenerate all the line number for the documents code blocks
|
|
38
|
+
if (!fg('editor_code_wrapping_perf_improvement_ed-25141')) {
|
|
39
|
+
const children = updatedDecorationSet.find(undefined, undefined, spec => spec.type === DECORATION_WIDGET_TYPE);
|
|
40
|
+
updatedDecorationSet = updatedDecorationSet.remove(children);
|
|
41
|
+
}
|
|
42
42
|
const lineNumberDecorators = [];
|
|
43
43
|
codeBlockNodes.forEach(node => {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
if (fg('editor_code_wrapping_perf_improvement_ed-25141')) {
|
|
45
|
+
const existingWidgetsOnNode = updatedDecorationSet.find(node.pos, node.pos + node.node.nodeSize, spec => spec.type === DECORATION_WIDGET_TYPE);
|
|
46
|
+
const newLineAttributes = generateLineAttributesFromNode(node);
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
// There will be no widgets on initialisation. If the number of existing widgets does not equal the amount of lines, regenerate the widgets.
|
|
49
|
+
// There may be a case where the number of existing widgets and the number of lines are the same, that's why we track totalLineCount. This allows
|
|
50
|
+
// us to know how many lines there were when the widget was created. It avoids a break in line numbers, e.g. "1, 2, 3, 5, 6". Happens on line removal.
|
|
51
|
+
if (existingWidgetsOnNode.length === 0 || existingWidgetsOnNode.length !== newLineAttributes.length || existingWidgetsOnNode[0].spec.totalLineCount !== newLineAttributes.length) {
|
|
52
|
+
updatedDecorationSet = updatedDecorationSet.remove(existingWidgetsOnNode);
|
|
53
|
+
lineNumberDecorators.push(...createDecorationSetFromLineAttributes(newLineAttributes));
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
lineNumberDecorators.push(...createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node)));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
48
59
|
return updatedDecorationSet.add(tr.doc, [...lineNumberDecorators]);
|
|
49
60
|
};
|
|
50
61
|
export const generateLineAttributesFromNode = node => {
|
|
@@ -101,14 +112,15 @@ export const createDecorationSetFromLineAttributes = lineAttributes => {
|
|
|
101
112
|
};
|
|
102
113
|
|
|
103
114
|
// side -1 is used so the line numbers are the first thing to the left of the lines of code.
|
|
115
|
+
// totalLineCount is used to know whether or not to update the line numbers when a new line is added or removed.
|
|
104
116
|
return Decoration.widget(lineStart, createLineNumberWidget, {
|
|
105
117
|
type: DECORATION_WIDGET_TYPE,
|
|
106
|
-
side: -1
|
|
118
|
+
side: -1,
|
|
119
|
+
totalLineCount: fg('editor_code_wrapping_perf_improvement_ed-25141') ? lineAttributes.length : undefined
|
|
107
120
|
});
|
|
108
121
|
});
|
|
109
122
|
return widgetDecorations;
|
|
110
123
|
};
|
|
111
|
-
export const createLineNumbersDecorations = node => createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node));
|
|
112
124
|
|
|
113
125
|
/**
|
|
114
126
|
* There are edge cases like when a user drags and drops a code block node where the decorator breaks and no longer reflects
|
|
@@ -12,7 +12,7 @@ import { ignoreFollowingMutations, resetShouldIgnoreFollowingMutations } from '.
|
|
|
12
12
|
import { codeBlockNodeView } from '../nodeviews/code-block';
|
|
13
13
|
import { pluginKey } from '../plugin-key';
|
|
14
14
|
import { codeBlockClassNames } from '../ui/class-names';
|
|
15
|
-
import { findCodeBlock, getAllCodeBlockNodesInDoc } from '../utils';
|
|
15
|
+
import { findCodeBlock, getAllChangedCodeBlocksInTransaction, getAllCodeBlockNodesInDoc } from '../utils';
|
|
16
16
|
import { ACTIONS } from './actions';
|
|
17
17
|
import { generateInitialDecorations, updateCodeBlockDecorations, updateDecorationSetWithWordWrappedDecorator } from './decorators';
|
|
18
18
|
export const createPlugin = ({
|
|
@@ -88,11 +88,13 @@ export const createPlugin = ({
|
|
|
88
88
|
// specifically used for updating word wrap node decorators (does not cover drag & drop, validateWordWrappedDecorators does).
|
|
89
89
|
let updatedDecorationSet = pluginState.decorations.map(tr.mapping, tr.doc);
|
|
90
90
|
if (fg('editor_support_code_block_wrapping')) {
|
|
91
|
-
const codeBlockNodes = getAllCodeBlockNodesInDoc(newState);
|
|
92
|
-
if (
|
|
93
|
-
|
|
91
|
+
const codeBlockNodes = fg('editor_code_wrapping_perf_improvement_ed-25141') ? getAllChangedCodeBlocksInTransaction(tr, newState) : getAllCodeBlockNodesInDoc(newState);
|
|
92
|
+
if (codeBlockNodes) {
|
|
93
|
+
if (fg('editor_code_block_wrapping_language_change_bug')) {
|
|
94
|
+
updateCodeBlockWrappedStateNodeKeys(codeBlockNodes, _oldState);
|
|
95
|
+
}
|
|
96
|
+
updatedDecorationSet = updateCodeBlockDecorations(tr, codeBlockNodes, updatedDecorationSet);
|
|
94
97
|
}
|
|
95
|
-
updatedDecorationSet = updateCodeBlockDecorations(tr, codeBlockNodes, updatedDecorationSet);
|
|
96
98
|
}
|
|
97
99
|
const newPluginState = {
|
|
98
100
|
...pluginState,
|
package/dist/es2019/utils.js
CHANGED
|
@@ -2,6 +2,8 @@ export { findCodeBlock, transformSliceToJoinAdjacentCodeBlocks, transformSingleL
|
|
|
2
2
|
export function getCursor(selection) {
|
|
3
3
|
return selection.$cursor || undefined;
|
|
4
4
|
}
|
|
5
|
+
|
|
6
|
+
// Replaced by getAllChangedCodeBlocksInTransaction with FG editor_code_wrapping_perf_improvement_ed-25141.
|
|
5
7
|
export function getAllCodeBlockNodesInDoc(state) {
|
|
6
8
|
const codeBlockNodes = [];
|
|
7
9
|
state.doc.descendants((node, pos) => {
|
|
@@ -15,4 +17,28 @@ export function getAllCodeBlockNodesInDoc(state) {
|
|
|
15
17
|
return true;
|
|
16
18
|
});
|
|
17
19
|
return codeBlockNodes;
|
|
20
|
+
}
|
|
21
|
+
export function getAllChangedCodeBlocksInTransaction(tr, state) {
|
|
22
|
+
const changedCodeBlocks = [];
|
|
23
|
+
const nodePositions = new Set();
|
|
24
|
+
tr.steps.forEach(step => {
|
|
25
|
+
const mapResult = step.getMap();
|
|
26
|
+
mapResult.forEach((oldStart, oldEnd, newStart, newEnd) => {
|
|
27
|
+
state.doc.nodesBetween(newStart, newEnd, (node, pos) => {
|
|
28
|
+
if (node.type.name === 'codeBlock') {
|
|
29
|
+
if (!nodePositions.has(pos)) {
|
|
30
|
+
nodePositions.add(pos);
|
|
31
|
+
changedCodeBlocks.push({
|
|
32
|
+
node,
|
|
33
|
+
pos
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
if (changedCodeBlocks.length < 1) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return changedCodeBlocks;
|
|
18
44
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
2
|
/* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
|
|
3
|
+
|
|
3
4
|
import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
4
5
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
6
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -14,7 +15,7 @@ export var DECORATION_WRAPPED_BLOCK_NODE_TYPE = 'decorationNodeType';
|
|
|
14
15
|
export var generateInitialDecorations = function generateInitialDecorations(state) {
|
|
15
16
|
var codeBlockNodes = getAllCodeBlockNodesInDoc(state);
|
|
16
17
|
return codeBlockNodes.flatMap(function (node) {
|
|
17
|
-
return
|
|
18
|
+
return createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node));
|
|
18
19
|
});
|
|
19
20
|
};
|
|
20
21
|
|
|
@@ -23,8 +24,7 @@ export var generateInitialDecorations = function generateInitialDecorations(stat
|
|
|
23
24
|
*/
|
|
24
25
|
export var updateCodeBlockDecorations = function updateCodeBlockDecorations(tr, codeBlockNodes, decorationSet) {
|
|
25
26
|
var updatedDecorationSet = decorationSet;
|
|
26
|
-
|
|
27
|
-
// All the line numbers decorators are refreshed on doc change.
|
|
27
|
+
// Update line number decorators for changed code block nodes if new line added or line removed.
|
|
28
28
|
updatedDecorationSet = updateDecorationSetWithLineNumberDecorators(tr, codeBlockNodes, updatedDecorationSet);
|
|
29
29
|
|
|
30
30
|
// Check to make sure the word wrap decorators are still valid.
|
|
@@ -33,23 +33,36 @@ export var updateCodeBlockDecorations = function updateCodeBlockDecorations(tr,
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* Update the decorations set with the line number decorators.
|
|
36
|
+
* Update the decorations set with the line number decorators. This will only happen for the code blocks passed to this function
|
|
37
|
+
* when there has been a new line added or removed. The line decorations will not update the code block node otherwise.
|
|
37
38
|
*/
|
|
38
39
|
export var updateDecorationSetWithLineNumberDecorators = function updateDecorationSetWithLineNumberDecorators(tr, codeBlockNodes, decorationSet) {
|
|
39
40
|
var updatedDecorationSet = decorationSet;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// regenerate all the line number for the documents code blocks
|
|
41
|
+
if (!fg('editor_code_wrapping_perf_improvement_ed-25141')) {
|
|
42
|
+
var children = updatedDecorationSet.find(undefined, undefined, function (spec) {
|
|
43
|
+
return spec.type === DECORATION_WIDGET_TYPE;
|
|
44
|
+
});
|
|
45
|
+
updatedDecorationSet = updatedDecorationSet.remove(children);
|
|
46
|
+
}
|
|
47
47
|
var lineNumberDecorators = [];
|
|
48
48
|
codeBlockNodes.forEach(function (node) {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
if (fg('editor_code_wrapping_perf_improvement_ed-25141')) {
|
|
50
|
+
var existingWidgetsOnNode = updatedDecorationSet.find(node.pos, node.pos + node.node.nodeSize, function (spec) {
|
|
51
|
+
return spec.type === DECORATION_WIDGET_TYPE;
|
|
52
|
+
});
|
|
53
|
+
var newLineAttributes = generateLineAttributesFromNode(node);
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
// There will be no widgets on initialisation. If the number of existing widgets does not equal the amount of lines, regenerate the widgets.
|
|
56
|
+
// There may be a case where the number of existing widgets and the number of lines are the same, that's why we track totalLineCount. This allows
|
|
57
|
+
// us to know how many lines there were when the widget was created. It avoids a break in line numbers, e.g. "1, 2, 3, 5, 6". Happens on line removal.
|
|
58
|
+
if (existingWidgetsOnNode.length === 0 || existingWidgetsOnNode.length !== newLineAttributes.length || existingWidgetsOnNode[0].spec.totalLineCount !== newLineAttributes.length) {
|
|
59
|
+
updatedDecorationSet = updatedDecorationSet.remove(existingWidgetsOnNode);
|
|
60
|
+
lineNumberDecorators.push.apply(lineNumberDecorators, _toConsumableArray(createDecorationSetFromLineAttributes(newLineAttributes)));
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
lineNumberDecorators.push.apply(lineNumberDecorators, _toConsumableArray(createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node))));
|
|
64
|
+
}
|
|
65
|
+
});
|
|
53
66
|
return updatedDecorationSet.add(tr.doc, [].concat(lineNumberDecorators));
|
|
54
67
|
};
|
|
55
68
|
export var generateLineAttributesFromNode = function generateLineAttributesFromNode(node) {
|
|
@@ -102,16 +115,15 @@ export var createDecorationSetFromLineAttributes = function createDecorationSetF
|
|
|
102
115
|
};
|
|
103
116
|
|
|
104
117
|
// side -1 is used so the line numbers are the first thing to the left of the lines of code.
|
|
118
|
+
// totalLineCount is used to know whether or not to update the line numbers when a new line is added or removed.
|
|
105
119
|
return Decoration.widget(lineStart, createLineNumberWidget, {
|
|
106
120
|
type: DECORATION_WIDGET_TYPE,
|
|
107
|
-
side: -1
|
|
121
|
+
side: -1,
|
|
122
|
+
totalLineCount: fg('editor_code_wrapping_perf_improvement_ed-25141') ? lineAttributes.length : undefined
|
|
108
123
|
});
|
|
109
124
|
});
|
|
110
125
|
return widgetDecorations;
|
|
111
126
|
};
|
|
112
|
-
export var createLineNumbersDecorations = function createLineNumbersDecorations(node) {
|
|
113
|
-
return createDecorationSetFromLineAttributes(generateLineAttributesFromNode(node));
|
|
114
|
-
};
|
|
115
127
|
|
|
116
128
|
/**
|
|
117
129
|
* There are edge cases like when a user drags and drops a code block node where the decorator breaks and no longer reflects
|
|
@@ -15,7 +15,7 @@ import { ignoreFollowingMutations, resetShouldIgnoreFollowingMutations } from '.
|
|
|
15
15
|
import { codeBlockNodeView } from '../nodeviews/code-block';
|
|
16
16
|
import { pluginKey } from '../plugin-key';
|
|
17
17
|
import { codeBlockClassNames } from '../ui/class-names';
|
|
18
|
-
import { findCodeBlock, getAllCodeBlockNodesInDoc } from '../utils';
|
|
18
|
+
import { findCodeBlock, getAllChangedCodeBlocksInTransaction, getAllCodeBlockNodesInDoc } from '../utils';
|
|
19
19
|
import { ACTIONS } from './actions';
|
|
20
20
|
import { generateInitialDecorations, updateCodeBlockDecorations, updateDecorationSetWithWordWrappedDecorator } from './decorators';
|
|
21
21
|
export var createPlugin = function createPlugin(_ref) {
|
|
@@ -93,11 +93,13 @@ export var createPlugin = function createPlugin(_ref) {
|
|
|
93
93
|
// specifically used for updating word wrap node decorators (does not cover drag & drop, validateWordWrappedDecorators does).
|
|
94
94
|
var updatedDecorationSet = pluginState.decorations.map(tr.mapping, tr.doc);
|
|
95
95
|
if (fg('editor_support_code_block_wrapping')) {
|
|
96
|
-
var codeBlockNodes = getAllCodeBlockNodesInDoc(newState);
|
|
97
|
-
if (
|
|
98
|
-
|
|
96
|
+
var codeBlockNodes = fg('editor_code_wrapping_perf_improvement_ed-25141') ? getAllChangedCodeBlocksInTransaction(tr, newState) : getAllCodeBlockNodesInDoc(newState);
|
|
97
|
+
if (codeBlockNodes) {
|
|
98
|
+
if (fg('editor_code_block_wrapping_language_change_bug')) {
|
|
99
|
+
updateCodeBlockWrappedStateNodeKeys(codeBlockNodes, _oldState);
|
|
100
|
+
}
|
|
101
|
+
updatedDecorationSet = updateCodeBlockDecorations(tr, codeBlockNodes, updatedDecorationSet);
|
|
99
102
|
}
|
|
100
|
-
updatedDecorationSet = updateCodeBlockDecorations(tr, codeBlockNodes, updatedDecorationSet);
|
|
101
103
|
}
|
|
102
104
|
var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
103
105
|
pos: _node ? _node.pos : null,
|
package/dist/esm/utils.js
CHANGED
|
@@ -2,6 +2,8 @@ export { findCodeBlock, transformSliceToJoinAdjacentCodeBlocks, transformSingleL
|
|
|
2
2
|
export function getCursor(selection) {
|
|
3
3
|
return selection.$cursor || undefined;
|
|
4
4
|
}
|
|
5
|
+
|
|
6
|
+
// Replaced by getAllChangedCodeBlocksInTransaction with FG editor_code_wrapping_perf_improvement_ed-25141.
|
|
5
7
|
export function getAllCodeBlockNodesInDoc(state) {
|
|
6
8
|
var codeBlockNodes = [];
|
|
7
9
|
state.doc.descendants(function (node, pos) {
|
|
@@ -15,4 +17,28 @@ export function getAllCodeBlockNodesInDoc(state) {
|
|
|
15
17
|
return true;
|
|
16
18
|
});
|
|
17
19
|
return codeBlockNodes;
|
|
20
|
+
}
|
|
21
|
+
export function getAllChangedCodeBlocksInTransaction(tr, state) {
|
|
22
|
+
var changedCodeBlocks = [];
|
|
23
|
+
var nodePositions = new Set();
|
|
24
|
+
tr.steps.forEach(function (step) {
|
|
25
|
+
var mapResult = step.getMap();
|
|
26
|
+
mapResult.forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
27
|
+
state.doc.nodesBetween(newStart, newEnd, function (node, pos) {
|
|
28
|
+
if (node.type.name === 'codeBlock') {
|
|
29
|
+
if (!nodePositions.has(pos)) {
|
|
30
|
+
nodePositions.add(pos);
|
|
31
|
+
changedCodeBlocks.push({
|
|
32
|
+
node: node,
|
|
33
|
+
pos: pos
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
if (changedCodeBlocks.length < 1) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return changedCodeBlocks;
|
|
18
44
|
}
|
|
@@ -13,12 +13,12 @@ export declare const generateInitialDecorations: (state: EditorState) => Decorat
|
|
|
13
13
|
*/
|
|
14
14
|
export declare const updateCodeBlockDecorations: (tr: ReadonlyTransaction, codeBlockNodes: NodeWithPos[], decorationSet: DecorationSet) => DecorationSet;
|
|
15
15
|
/**
|
|
16
|
-
* Update the decorations set with the line number decorators.
|
|
16
|
+
* Update the decorations set with the line number decorators. This will only happen for the code blocks passed to this function
|
|
17
|
+
* when there has been a new line added or removed. The line decorations will not update the code block node otherwise.
|
|
17
18
|
*/
|
|
18
19
|
export declare const updateDecorationSetWithLineNumberDecorators: (tr: ReadonlyTransaction, codeBlockNodes: NodeWithPos[], decorationSet: DecorationSet) => DecorationSet;
|
|
19
20
|
export declare const generateLineAttributesFromNode: (node: NodeWithPos) => CodeBlockLineAttributes[];
|
|
20
21
|
export declare const createDecorationSetFromLineAttributes: (lineAttributes: CodeBlockLineAttributes[]) => Decoration[];
|
|
21
|
-
export declare const createLineNumbersDecorations: (node: NodeWithPos) => Decoration[];
|
|
22
22
|
/**
|
|
23
23
|
* There are edge cases like when a user drags and drops a code block node where the decorator breaks and no longer reflects
|
|
24
24
|
* the correct word wrap state. This function validates that the decorator and the state are in line, otherwise it will
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { findCodeBlock, transformSliceToJoinAdjacentCodeBlocks, transformSingleLineCodeBlockToCodeMark, } from '@atlaskit/editor-common/transforms';
|
|
2
2
|
import type { ResolvedPos } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { EditorState, ReadonlyTransaction, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
5
5
|
export declare function getCursor(selection: Selection): ResolvedPos | undefined;
|
|
6
6
|
export declare function getAllCodeBlockNodesInDoc(state: EditorState): NodeWithPos[];
|
|
7
|
+
export declare function getAllChangedCodeBlocksInTransaction(tr: ReadonlyTransaction, state: EditorState): NodeWithPos[] | null;
|
|
@@ -13,12 +13,12 @@ export declare const generateInitialDecorations: (state: EditorState) => Decorat
|
|
|
13
13
|
*/
|
|
14
14
|
export declare const updateCodeBlockDecorations: (tr: ReadonlyTransaction, codeBlockNodes: NodeWithPos[], decorationSet: DecorationSet) => DecorationSet;
|
|
15
15
|
/**
|
|
16
|
-
* Update the decorations set with the line number decorators.
|
|
16
|
+
* Update the decorations set with the line number decorators. This will only happen for the code blocks passed to this function
|
|
17
|
+
* when there has been a new line added or removed. The line decorations will not update the code block node otherwise.
|
|
17
18
|
*/
|
|
18
19
|
export declare const updateDecorationSetWithLineNumberDecorators: (tr: ReadonlyTransaction, codeBlockNodes: NodeWithPos[], decorationSet: DecorationSet) => DecorationSet;
|
|
19
20
|
export declare const generateLineAttributesFromNode: (node: NodeWithPos) => CodeBlockLineAttributes[];
|
|
20
21
|
export declare const createDecorationSetFromLineAttributes: (lineAttributes: CodeBlockLineAttributes[]) => Decoration[];
|
|
21
|
-
export declare const createLineNumbersDecorations: (node: NodeWithPos) => Decoration[];
|
|
22
22
|
/**
|
|
23
23
|
* There are edge cases like when a user drags and drops a code block node where the decorator breaks and no longer reflects
|
|
24
24
|
* the correct word wrap state. This function validates that the decorator and the state are in line, otherwise it will
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { findCodeBlock, transformSliceToJoinAdjacentCodeBlocks, transformSingleLineCodeBlockToCodeMark, } from '@atlaskit/editor-common/transforms';
|
|
2
2
|
import type { ResolvedPos } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { EditorState, ReadonlyTransaction, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
import type { NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
5
5
|
export declare function getCursor(selection: Selection): ResolvedPos | undefined;
|
|
6
6
|
export declare function getAllCodeBlockNodesInDoc(state: EditorState): NodeWithPos[];
|
|
7
|
+
export declare function getAllChangedCodeBlocksInTransaction(tr: ReadonlyTransaction, state: EditorState): NodeWithPos[] | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-code-block",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.3",
|
|
4
4
|
"description": "Code block plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@atlaskit/adf-schema": "^40.9.0",
|
|
35
35
|
"@atlaskit/code": "^15.6.0",
|
|
36
|
-
"@atlaskit/editor-common": "^
|
|
36
|
+
"@atlaskit/editor-common": "^93.1.0",
|
|
37
37
|
"@atlaskit/editor-plugin-analytics": "^1.8.0",
|
|
38
38
|
"@atlaskit/editor-plugin-composition": "^1.2.0",
|
|
39
39
|
"@atlaskit/editor-plugin-decorations": "^1.3.0",
|
|
40
40
|
"@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
|
|
41
41
|
"@atlaskit/editor-prosemirror": "6.0.0",
|
|
42
|
-
"@atlaskit/icon": "^22.
|
|
42
|
+
"@atlaskit/icon": "^22.20.0",
|
|
43
43
|
"@atlaskit/platform-feature-flags": "^0.3.0",
|
|
44
44
|
"@atlaskit/prosemirror-input-rules": "^3.2.0",
|
|
45
45
|
"@babel/runtime": "^7.0.0",
|
|
@@ -102,6 +102,9 @@
|
|
|
102
102
|
},
|
|
103
103
|
"editor_nest_media_and_codeblock_in_quotes_jira": {
|
|
104
104
|
"type": "boolean"
|
|
105
|
+
},
|
|
106
|
+
"editor_code_wrapping_perf_improvement_ed-25141": {
|
|
107
|
+
"type": "boolean"
|
|
105
108
|
}
|
|
106
109
|
}
|
|
107
110
|
}
|