@atlaskit/editor-plugin-code-block-advanced 3.2.1 → 3.2.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 +2 -2
- package/dist/cjs/nodeviews/codeBlockAdvanced.js +24 -1
- package/dist/cjs/nodeviews/extensions/foldGutter.js +53 -1
- package/dist/es2019/nodeviews/codeBlockAdvanced.js +21 -2
- package/dist/es2019/nodeviews/extensions/foldGutter.js +42 -2
- package/dist/esm/nodeviews/codeBlockAdvanced.js +25 -2
- package/dist/esm/nodeviews/extensions/foldGutter.js +53 -2
- package/dist/types/codeBlockAdvancedPluginType.d.ts +1 -1
- package/dist/types/nodeviews/codeBlockAdvanced.d.ts +2 -1
- package/dist/types/nodeviews/codemirrorSync/syncCMWithPM.d.ts +2 -2
- package/dist/types/nodeviews/extensions/foldGutter.d.ts +9 -1
- package/dist/types/nodeviews/extensions/keymap/backspace.d.ts +2 -2
- package/dist/types/nodeviews/extensions/keymap/index.d.ts +3 -3
- package/dist/types/nodeviews/extensions/keymap/maybeEscape.d.ts +4 -4
- package/dist/types/nodeviews/lazyCodeBlockAdvanced.d.ts +1 -1
- package/dist/types/pm-plugins/main.d.ts +1 -1
- package/dist/types-ts4.5/codeBlockAdvancedPluginType.d.ts +1 -1
- package/dist/types-ts4.5/nodeviews/codeBlockAdvanced.d.ts +2 -1
- package/dist/types-ts4.5/nodeviews/codemirrorSync/syncCMWithPM.d.ts +2 -2
- package/dist/types-ts4.5/nodeviews/extensions/foldGutter.d.ts +9 -1
- package/dist/types-ts4.5/nodeviews/extensions/keymap/backspace.d.ts +2 -2
- package/dist/types-ts4.5/nodeviews/extensions/keymap/index.d.ts +3 -3
- package/dist/types-ts4.5/nodeviews/extensions/keymap/maybeEscape.d.ts +4 -4
- package/dist/types-ts4.5/nodeviews/lazyCodeBlockAdvanced.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -1
- package/package.json +5 -5
- package/src/codeBlockAdvancedPluginType.ts +1 -1
- package/src/nodeviews/codeBlockAdvanced.ts +19 -3
- package/src/nodeviews/codemirrorSync/syncCMWithPM.ts +2 -2
- package/src/nodeviews/extensions/foldGutter.ts +54 -3
- package/src/nodeviews/extensions/keymap/backspace.ts +2 -2
- package/src/nodeviews/extensions/keymap/index.ts +3 -3
- package/src/nodeviews/extensions/keymap/maybeEscape.ts +5 -5
- package/src/nodeviews/extensions/prosemirrorDecorations.ts +2 -2
- package/src/nodeviews/lazyCodeBlockAdvanced.ts +1 -1
- package/src/pm-plugins/main.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-code-block-advanced
|
|
2
2
|
|
|
3
|
+
## 3.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`0ff4a6c7a39ef`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0ff4a6c7a39ef) -
|
|
8
|
+
Creates global fold state to retain folds after breakouts and page resizing
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 3.2.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`265c1bf0cefa4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/265c1bf0cefa4) -
|
|
16
|
+
Sorted type and interface props to improve Atlaskit docs
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 3.2.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/afm-cc/tsconfig.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"extends": "../../../../tsconfig.entry-points.confluence.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"target": "es5",
|
|
5
|
-
"composite": true,
|
|
6
5
|
"outDir": "../../../../../confluence/tsDist/@atlaskit__editor-plugin-code-block-advanced",
|
|
7
|
-
"rootDir": "../"
|
|
6
|
+
"rootDir": "../",
|
|
7
|
+
"composite": true
|
|
8
8
|
},
|
|
9
9
|
"include": [
|
|
10
10
|
"../src/**/*.ts",
|
|
@@ -106,7 +106,10 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
106
106
|
}), (0, _manageSelectionMarker.manageSelectionMarker)(config.api), (0, _prosemirrorDecorations.prosemirrorDecorationPlugin)(this.pmFacet, view, getPos), (0, _tripleClickExtension.tripleClickSelectAllExtension)(), (0, _firstCodeBlockInDocument.firstCodeBlockInDocument)(getPos), _view.EditorView.contentAttributes.of({
|
|
107
107
|
'aria-label': formattedAriaLabel
|
|
108
108
|
}), config.allowCodeFolding ? [(0, _foldGutter.foldGutterExtension)({
|
|
109
|
-
selectNode: selectNode
|
|
109
|
+
selectNode: selectNode,
|
|
110
|
+
getNode: function getNode() {
|
|
111
|
+
return _this.node;
|
|
112
|
+
}
|
|
110
113
|
})] : []])
|
|
111
114
|
});
|
|
112
115
|
|
|
@@ -124,6 +127,11 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
124
127
|
this.updating = false;
|
|
125
128
|
this.updateLanguage();
|
|
126
129
|
this.wordWrappingEnabled = (0, _codeBlock.isCodeBlockWordWrapEnabled)(node);
|
|
130
|
+
|
|
131
|
+
// Restore fold state after initialization
|
|
132
|
+
if (config.allowCodeFolding) {
|
|
133
|
+
this.restoreFoldState();
|
|
134
|
+
}
|
|
127
135
|
}
|
|
128
136
|
return (0, _createClass2.default)(CodeBlockAdvancedNodeView, [{
|
|
129
137
|
key: "destroy",
|
|
@@ -201,6 +209,21 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
201
209
|
}
|
|
202
210
|
return undefined;
|
|
203
211
|
}
|
|
212
|
+
}, {
|
|
213
|
+
key: "restoreFoldState",
|
|
214
|
+
value: function restoreFoldState() {
|
|
215
|
+
this.updating = true;
|
|
216
|
+
var effects = (0, _foldGutter.getCodeBlockFoldStateEffects)({
|
|
217
|
+
node: this.node,
|
|
218
|
+
cm: this.cm
|
|
219
|
+
});
|
|
220
|
+
if (effects) {
|
|
221
|
+
this.cm.dispatch({
|
|
222
|
+
effects: effects
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
this.updating = false;
|
|
226
|
+
}
|
|
204
227
|
}, {
|
|
205
228
|
key: "update",
|
|
206
229
|
value: function update(node, _, innerDecorations) {
|
|
@@ -4,9 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.foldGutterExtension = foldGutterExtension;
|
|
7
|
+
exports.getCodeBlockFoldStateEffects = getCodeBlockFoldStateEffects;
|
|
7
8
|
var _language = require("@codemirror/language");
|
|
9
|
+
var _codeBlock = require("@atlaskit/editor-common/code-block");
|
|
8
10
|
var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
|
|
9
11
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
12
|
+
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; } } }; }
|
|
13
|
+
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; } }
|
|
14
|
+
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; }
|
|
10
15
|
// Based on platform/packages/design-system/icon/svgs/utility/add.svg
|
|
11
16
|
var chevronDown = ['http://www.w3.org/2000/svg svg', {
|
|
12
17
|
width: '12',
|
|
@@ -35,8 +40,24 @@ var chevronRight = ['http://www.w3.org/2000/svg svg', {
|
|
|
35
40
|
style: 'pointer-events: none;'
|
|
36
41
|
}]];
|
|
37
42
|
function foldGutterExtension(_ref) {
|
|
38
|
-
var selectNode = _ref.selectNode
|
|
43
|
+
var selectNode = _ref.selectNode,
|
|
44
|
+
getNode = _ref.getNode;
|
|
39
45
|
return [(0, _language.foldGutter)({
|
|
46
|
+
foldingChanged: function foldingChanged(update) {
|
|
47
|
+
var folds = update.state.field(_language.foldState, false);
|
|
48
|
+
if (!folds) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
var foldRanges = [];
|
|
52
|
+
folds.between(0, update.state.doc.length, function (from, to) {
|
|
53
|
+
foldRanges.push({
|
|
54
|
+
from: from,
|
|
55
|
+
to: to
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
(0, _codeBlock.setCodeBlockFoldState)(getNode(), foldRanges);
|
|
59
|
+
return false;
|
|
60
|
+
},
|
|
40
61
|
domEventHandlers: {
|
|
41
62
|
click: function click(_view, _, event) {
|
|
42
63
|
// If we're trying to click the button, don't select
|
|
@@ -97,4 +118,35 @@ function foldGutterExtension(_ref) {
|
|
|
97
118
|
return htmlElement;
|
|
98
119
|
}
|
|
99
120
|
})];
|
|
121
|
+
}
|
|
122
|
+
function getCodeBlockFoldStateEffects(_ref2) {
|
|
123
|
+
var node = _ref2.node,
|
|
124
|
+
cm = _ref2.cm;
|
|
125
|
+
var savedFolds = (0, _codeBlock.getCodeBlockFoldState)(node);
|
|
126
|
+
if (savedFolds.length === 0) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Create fold effects for each saved fold range
|
|
131
|
+
var effects = [];
|
|
132
|
+
var _iterator = _createForOfIteratorHelper(savedFolds),
|
|
133
|
+
_step;
|
|
134
|
+
try {
|
|
135
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
136
|
+
var foldRange = _step.value;
|
|
137
|
+
// Validate that the fold range is still valid for the current document
|
|
138
|
+
var docLength = cm.state.doc.length;
|
|
139
|
+
if (foldRange.from >= 0 && foldRange.to <= docLength && foldRange.from < foldRange.to) {
|
|
140
|
+
effects.push(_language.foldEffect.of({
|
|
141
|
+
from: foldRange.from,
|
|
142
|
+
to: foldRange.to
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch (err) {
|
|
147
|
+
_iterator.e(err);
|
|
148
|
+
} finally {
|
|
149
|
+
_iterator.f();
|
|
150
|
+
}
|
|
151
|
+
return effects;
|
|
100
152
|
}
|
|
@@ -14,7 +14,7 @@ import { cmTheme, codeFoldingTheme } from '../ui/theme';
|
|
|
14
14
|
import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
|
|
15
15
|
import { getCMSelectionChanges } from './codemirrorSync/updateCMSelection';
|
|
16
16
|
import { firstCodeBlockInDocument } from './extensions/firstCodeBlockInDocument';
|
|
17
|
-
import { foldGutterExtension } from './extensions/foldGutter';
|
|
17
|
+
import { foldGutterExtension, getCodeBlockFoldStateEffects } from './extensions/foldGutter';
|
|
18
18
|
import { keymapExtension } from './extensions/keymap';
|
|
19
19
|
import { manageSelectionMarker } from './extensions/manageSelectionMarker';
|
|
20
20
|
import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
|
|
@@ -85,7 +85,8 @@ class CodeBlockAdvancedNodeView {
|
|
|
85
85
|
}), manageSelectionMarker(config.api), prosemirrorDecorationPlugin(this.pmFacet, view, getPos), tripleClickSelectAllExtension(), firstCodeBlockInDocument(getPos), CodeMirror.contentAttributes.of({
|
|
86
86
|
'aria-label': formattedAriaLabel
|
|
87
87
|
}), config.allowCodeFolding ? [foldGutterExtension({
|
|
88
|
-
selectNode
|
|
88
|
+
selectNode,
|
|
89
|
+
getNode: () => this.node
|
|
89
90
|
})] : []]
|
|
90
91
|
});
|
|
91
92
|
|
|
@@ -103,6 +104,11 @@ class CodeBlockAdvancedNodeView {
|
|
|
103
104
|
this.updating = false;
|
|
104
105
|
this.updateLanguage();
|
|
105
106
|
this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
|
|
107
|
+
|
|
108
|
+
// Restore fold state after initialization
|
|
109
|
+
if (config.allowCodeFolding) {
|
|
110
|
+
this.restoreFoldState();
|
|
111
|
+
}
|
|
106
112
|
}
|
|
107
113
|
destroy() {
|
|
108
114
|
var _this$cleanupDisabled;
|
|
@@ -166,6 +172,19 @@ class CodeBlockAdvancedNodeView {
|
|
|
166
172
|
}
|
|
167
173
|
return undefined;
|
|
168
174
|
}
|
|
175
|
+
restoreFoldState() {
|
|
176
|
+
this.updating = true;
|
|
177
|
+
const effects = getCodeBlockFoldStateEffects({
|
|
178
|
+
node: this.node,
|
|
179
|
+
cm: this.cm
|
|
180
|
+
});
|
|
181
|
+
if (effects) {
|
|
182
|
+
this.cm.dispatch({
|
|
183
|
+
effects
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
this.updating = false;
|
|
187
|
+
}
|
|
169
188
|
update(node, _, innerDecorations) {
|
|
170
189
|
this.maybeTryingToReachNodeSelection = false;
|
|
171
190
|
if (node.type !== this.node.type) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { foldGutter, codeFolding } from '@codemirror/language';
|
|
1
|
+
import { foldGutter, codeFolding, foldState, foldEffect } from '@codemirror/language';
|
|
2
|
+
import { setCodeBlockFoldState, getCodeBlockFoldState } from '@atlaskit/editor-common/code-block';
|
|
2
3
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
3
4
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
4
5
|
// Based on platform/packages/design-system/icon/svgs/utility/add.svg
|
|
@@ -29,9 +30,25 @@ const chevronRight = ['http://www.w3.org/2000/svg svg', {
|
|
|
29
30
|
style: 'pointer-events: none;'
|
|
30
31
|
}]];
|
|
31
32
|
export function foldGutterExtension({
|
|
32
|
-
selectNode
|
|
33
|
+
selectNode,
|
|
34
|
+
getNode
|
|
33
35
|
}) {
|
|
34
36
|
return [foldGutter({
|
|
37
|
+
foldingChanged: update => {
|
|
38
|
+
const folds = update.state.field(foldState, false);
|
|
39
|
+
if (!folds) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const foldRanges = [];
|
|
43
|
+
folds.between(0, update.state.doc.length, (from, to) => {
|
|
44
|
+
foldRanges.push({
|
|
45
|
+
from,
|
|
46
|
+
to
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
setCodeBlockFoldState(getNode(), foldRanges);
|
|
50
|
+
return false;
|
|
51
|
+
},
|
|
35
52
|
domEventHandlers: {
|
|
36
53
|
click: (_view, _, event) => {
|
|
37
54
|
// If we're trying to click the button, don't select
|
|
@@ -94,4 +111,27 @@ export function foldGutterExtension({
|
|
|
94
111
|
return htmlElement;
|
|
95
112
|
}
|
|
96
113
|
})];
|
|
114
|
+
}
|
|
115
|
+
export function getCodeBlockFoldStateEffects({
|
|
116
|
+
node,
|
|
117
|
+
cm
|
|
118
|
+
}) {
|
|
119
|
+
const savedFolds = getCodeBlockFoldState(node);
|
|
120
|
+
if (savedFolds.length === 0) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Create fold effects for each saved fold range
|
|
125
|
+
const effects = [];
|
|
126
|
+
for (const foldRange of savedFolds) {
|
|
127
|
+
// Validate that the fold range is still valid for the current document
|
|
128
|
+
const docLength = cm.state.doc.length;
|
|
129
|
+
if (foldRange.from >= 0 && foldRange.to <= docLength && foldRange.from < foldRange.to) {
|
|
130
|
+
effects.push(foldEffect.of({
|
|
131
|
+
from: foldRange.from,
|
|
132
|
+
to: foldRange.to
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return effects;
|
|
97
137
|
}
|
|
@@ -17,7 +17,7 @@ import { cmTheme, codeFoldingTheme } from '../ui/theme';
|
|
|
17
17
|
import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
|
|
18
18
|
import { getCMSelectionChanges } from './codemirrorSync/updateCMSelection';
|
|
19
19
|
import { firstCodeBlockInDocument } from './extensions/firstCodeBlockInDocument';
|
|
20
|
-
import { foldGutterExtension } from './extensions/foldGutter';
|
|
20
|
+
import { foldGutterExtension, getCodeBlockFoldStateEffects } from './extensions/foldGutter';
|
|
21
21
|
import { keymapExtension } from './extensions/keymap';
|
|
22
22
|
import { manageSelectionMarker } from './extensions/manageSelectionMarker';
|
|
23
23
|
import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
|
|
@@ -99,7 +99,10 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
99
99
|
}), manageSelectionMarker(config.api), prosemirrorDecorationPlugin(this.pmFacet, view, getPos), tripleClickSelectAllExtension(), firstCodeBlockInDocument(getPos), CodeMirror.contentAttributes.of({
|
|
100
100
|
'aria-label': formattedAriaLabel
|
|
101
101
|
}), config.allowCodeFolding ? [foldGutterExtension({
|
|
102
|
-
selectNode: selectNode
|
|
102
|
+
selectNode: selectNode,
|
|
103
|
+
getNode: function getNode() {
|
|
104
|
+
return _this.node;
|
|
105
|
+
}
|
|
103
106
|
})] : []])
|
|
104
107
|
});
|
|
105
108
|
|
|
@@ -117,6 +120,11 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
117
120
|
this.updating = false;
|
|
118
121
|
this.updateLanguage();
|
|
119
122
|
this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
|
|
123
|
+
|
|
124
|
+
// Restore fold state after initialization
|
|
125
|
+
if (config.allowCodeFolding) {
|
|
126
|
+
this.restoreFoldState();
|
|
127
|
+
}
|
|
120
128
|
}
|
|
121
129
|
return _createClass(CodeBlockAdvancedNodeView, [{
|
|
122
130
|
key: "destroy",
|
|
@@ -194,6 +202,21 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
194
202
|
}
|
|
195
203
|
return undefined;
|
|
196
204
|
}
|
|
205
|
+
}, {
|
|
206
|
+
key: "restoreFoldState",
|
|
207
|
+
value: function restoreFoldState() {
|
|
208
|
+
this.updating = true;
|
|
209
|
+
var effects = getCodeBlockFoldStateEffects({
|
|
210
|
+
node: this.node,
|
|
211
|
+
cm: this.cm
|
|
212
|
+
});
|
|
213
|
+
if (effects) {
|
|
214
|
+
this.cm.dispatch({
|
|
215
|
+
effects: effects
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
this.updating = false;
|
|
219
|
+
}
|
|
197
220
|
}, {
|
|
198
221
|
key: "update",
|
|
199
222
|
value: function update(node, _, innerDecorations) {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
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
|
+
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
|
+
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
|
+
import { foldGutter, codeFolding, foldState, foldEffect } from '@codemirror/language';
|
|
5
|
+
import { setCodeBlockFoldState, getCodeBlockFoldState } from '@atlaskit/editor-common/code-block';
|
|
2
6
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
3
7
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
4
8
|
// Based on platform/packages/design-system/icon/svgs/utility/add.svg
|
|
@@ -29,8 +33,24 @@ var chevronRight = ['http://www.w3.org/2000/svg svg', {
|
|
|
29
33
|
style: 'pointer-events: none;'
|
|
30
34
|
}]];
|
|
31
35
|
export function foldGutterExtension(_ref) {
|
|
32
|
-
var selectNode = _ref.selectNode
|
|
36
|
+
var selectNode = _ref.selectNode,
|
|
37
|
+
getNode = _ref.getNode;
|
|
33
38
|
return [foldGutter({
|
|
39
|
+
foldingChanged: function foldingChanged(update) {
|
|
40
|
+
var folds = update.state.field(foldState, false);
|
|
41
|
+
if (!folds) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
var foldRanges = [];
|
|
45
|
+
folds.between(0, update.state.doc.length, function (from, to) {
|
|
46
|
+
foldRanges.push({
|
|
47
|
+
from: from,
|
|
48
|
+
to: to
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
setCodeBlockFoldState(getNode(), foldRanges);
|
|
52
|
+
return false;
|
|
53
|
+
},
|
|
34
54
|
domEventHandlers: {
|
|
35
55
|
click: function click(_view, _, event) {
|
|
36
56
|
// If we're trying to click the button, don't select
|
|
@@ -91,4 +111,35 @@ export function foldGutterExtension(_ref) {
|
|
|
91
111
|
return htmlElement;
|
|
92
112
|
}
|
|
93
113
|
})];
|
|
114
|
+
}
|
|
115
|
+
export function getCodeBlockFoldStateEffects(_ref2) {
|
|
116
|
+
var node = _ref2.node,
|
|
117
|
+
cm = _ref2.cm;
|
|
118
|
+
var savedFolds = getCodeBlockFoldState(node);
|
|
119
|
+
if (savedFolds.length === 0) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Create fold effects for each saved fold range
|
|
124
|
+
var effects = [];
|
|
125
|
+
var _iterator = _createForOfIteratorHelper(savedFolds),
|
|
126
|
+
_step;
|
|
127
|
+
try {
|
|
128
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
129
|
+
var foldRange = _step.value;
|
|
130
|
+
// Validate that the fold range is still valid for the current document
|
|
131
|
+
var docLength = cm.state.doc.length;
|
|
132
|
+
if (foldRange.from >= 0 && foldRange.to <= docLength && foldRange.from < foldRange.to) {
|
|
133
|
+
effects.push(foldEffect.of({
|
|
134
|
+
from: foldRange.from,
|
|
135
|
+
to: foldRange.to
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} catch (err) {
|
|
140
|
+
_iterator.e(err);
|
|
141
|
+
} finally {
|
|
142
|
+
_iterator.f();
|
|
143
|
+
}
|
|
144
|
+
return effects;
|
|
94
145
|
}
|
|
@@ -16,6 +16,6 @@ export type CodeBlockAdvancedPlugin = NextEditorPlugin<'codeBlockAdvanced', {
|
|
|
16
16
|
pluginConfiguration: CodeBlockAdvancedPluginOptions | undefined;
|
|
17
17
|
}>;
|
|
18
18
|
export type CodeBlockAdvancedPluginOptions = {
|
|
19
|
-
extensions?: Extension[];
|
|
20
19
|
allowCodeFolding?: boolean;
|
|
20
|
+
extensions?: Extension[];
|
|
21
21
|
};
|
|
@@ -6,10 +6,10 @@ import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
|
6
6
|
import type { Decoration, DecorationSource, EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
8
8
|
export interface ConfigProps {
|
|
9
|
+
allowCodeFolding: boolean;
|
|
9
10
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
10
11
|
extensions: Extension[];
|
|
11
12
|
getIntl: () => IntlShape;
|
|
12
|
-
allowCodeFolding: boolean;
|
|
13
13
|
}
|
|
14
14
|
declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
15
15
|
dom: Node;
|
|
@@ -36,6 +36,7 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
36
36
|
private selectCodeBlockNode;
|
|
37
37
|
private wordWrappingEnabled;
|
|
38
38
|
private getWordWrapEffects;
|
|
39
|
+
private restoreFoldState;
|
|
39
40
|
update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource): boolean;
|
|
40
41
|
/**
|
|
41
42
|
* Updates a facet which stores information on the prosemirror decorations
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { type StateEffect } from '@codemirror/state';
|
|
2
|
+
import type { EditorView as CodeMirror } from '@codemirror/view';
|
|
3
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
export declare function foldGutterExtension({ selectNode, getNode, }: {
|
|
5
|
+
getNode: () => PMNode;
|
|
2
6
|
selectNode: () => void;
|
|
3
7
|
}): import("@codemirror/state").Extension[];
|
|
8
|
+
export declare function getCodeBlockFoldStateEffects({ node, cm, }: {
|
|
9
|
+
cm: CodeMirror;
|
|
10
|
+
node: PMNode;
|
|
11
|
+
}): StateEffect<unknown>[] | undefined;
|
|
@@ -3,10 +3,10 @@ import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
|
3
3
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
4
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
5
|
interface BackspaceProps {
|
|
6
|
-
view: EditorView;
|
|
7
6
|
cm: CodeMirror;
|
|
8
|
-
getPos: getPosHandlerNode;
|
|
9
7
|
getNode: () => PMNode;
|
|
8
|
+
getPos: getPosHandlerNode;
|
|
9
|
+
view: EditorView;
|
|
10
10
|
}
|
|
11
11
|
export declare const backspaceKeymap: ({ cm, view, getPos, getNode }: BackspaceProps) => boolean;
|
|
12
12
|
export {};
|
|
@@ -4,12 +4,12 @@ import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
|
4
4
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
interface KeymapProps {
|
|
7
|
-
|
|
7
|
+
customFindReplace: boolean;
|
|
8
8
|
getNode: () => PMNode;
|
|
9
9
|
getPos: getPosHandlerNode;
|
|
10
|
-
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
11
10
|
onMaybeNodeSelection: () => void;
|
|
12
|
-
|
|
11
|
+
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
12
|
+
view: EditorView;
|
|
13
13
|
}
|
|
14
14
|
export declare const keymapExtension: ({ view, getNode, getPos, selectCodeBlockNode, onMaybeNodeSelection, customFindReplace, }: KeymapProps) => Extension;
|
|
15
15
|
export {};
|
|
@@ -4,14 +4,14 @@ import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
|
4
4
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
interface MaybeEscapeProps {
|
|
7
|
-
unit: 'line' | 'char';
|
|
8
|
-
dir: -1 | 1;
|
|
9
|
-
view: EditorView;
|
|
10
7
|
cm: CodeMirror;
|
|
11
|
-
|
|
8
|
+
dir: -1 | 1;
|
|
12
9
|
getNode: () => PMNode;
|
|
10
|
+
getPos: getPosHandlerNode;
|
|
13
11
|
onMaybeNodeSelection: () => void;
|
|
14
12
|
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
13
|
+
unit: 'line' | 'char';
|
|
14
|
+
view: EditorView;
|
|
15
15
|
}
|
|
16
16
|
export declare const maybeEscapeKeymap: ({ unit, dir, view, cm, getPos, getNode, onMaybeNodeSelection, selectCodeBlockNode, }: MaybeEscapeProps) => boolean;
|
|
17
17
|
export {};
|
|
@@ -3,10 +3,10 @@ import type { IntlShape } from 'react-intl-next';
|
|
|
3
3
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
4
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
5
5
|
interface Props {
|
|
6
|
+
allowCodeFolding: boolean;
|
|
6
7
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
7
8
|
extensions: Extension[];
|
|
8
9
|
getIntl: () => IntlShape;
|
|
9
|
-
allowCodeFolding: boolean;
|
|
10
10
|
}
|
|
11
11
|
export declare const lazyCodeBlockView: (props: Props) => import("@atlaskit/editor-common/lazy-node-view").NodeViewConstructor;
|
|
12
12
|
export {};
|
|
@@ -4,10 +4,10 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
|
4
4
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
5
5
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
6
6
|
interface Props {
|
|
7
|
+
allowCodeFolding: boolean;
|
|
7
8
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
8
9
|
extensions: Extension[];
|
|
9
10
|
getIntl: () => IntlShape;
|
|
10
|
-
allowCodeFolding: boolean;
|
|
11
11
|
}
|
|
12
12
|
export declare const createPlugin: (props: Props) => SafePlugin<any>;
|
|
13
13
|
export {};
|
|
@@ -16,6 +16,6 @@ export type CodeBlockAdvancedPlugin = NextEditorPlugin<'codeBlockAdvanced', {
|
|
|
16
16
|
pluginConfiguration: CodeBlockAdvancedPluginOptions | undefined;
|
|
17
17
|
}>;
|
|
18
18
|
export type CodeBlockAdvancedPluginOptions = {
|
|
19
|
-
extensions?: Extension[];
|
|
20
19
|
allowCodeFolding?: boolean;
|
|
20
|
+
extensions?: Extension[];
|
|
21
21
|
};
|
|
@@ -6,10 +6,10 @@ import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
|
6
6
|
import type { Decoration, DecorationSource, EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
8
8
|
export interface ConfigProps {
|
|
9
|
+
allowCodeFolding: boolean;
|
|
9
10
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
10
11
|
extensions: Extension[];
|
|
11
12
|
getIntl: () => IntlShape;
|
|
12
|
-
allowCodeFolding: boolean;
|
|
13
13
|
}
|
|
14
14
|
declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
15
15
|
dom: Node;
|
|
@@ -36,6 +36,7 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
36
36
|
private selectCodeBlockNode;
|
|
37
37
|
private wordWrappingEnabled;
|
|
38
38
|
private getWordWrapEffects;
|
|
39
|
+
private restoreFoldState;
|
|
39
40
|
update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource): boolean;
|
|
40
41
|
/**
|
|
41
42
|
* Updates a facet which stores information on the prosemirror decorations
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { type StateEffect } from '@codemirror/state';
|
|
2
|
+
import type { EditorView as CodeMirror } from '@codemirror/view';
|
|
3
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
export declare function foldGutterExtension({ selectNode, getNode, }: {
|
|
5
|
+
getNode: () => PMNode;
|
|
2
6
|
selectNode: () => void;
|
|
3
7
|
}): import("@codemirror/state").Extension[];
|
|
8
|
+
export declare function getCodeBlockFoldStateEffects({ node, cm, }: {
|
|
9
|
+
cm: CodeMirror;
|
|
10
|
+
node: PMNode;
|
|
11
|
+
}): StateEffect<unknown>[] | undefined;
|
|
@@ -3,10 +3,10 @@ import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
|
3
3
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
4
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
5
|
interface BackspaceProps {
|
|
6
|
-
view: EditorView;
|
|
7
6
|
cm: CodeMirror;
|
|
8
|
-
getPos: getPosHandlerNode;
|
|
9
7
|
getNode: () => PMNode;
|
|
8
|
+
getPos: getPosHandlerNode;
|
|
9
|
+
view: EditorView;
|
|
10
10
|
}
|
|
11
11
|
export declare const backspaceKeymap: ({ cm, view, getPos, getNode }: BackspaceProps) => boolean;
|
|
12
12
|
export {};
|
|
@@ -4,12 +4,12 @@ import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
|
4
4
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
interface KeymapProps {
|
|
7
|
-
|
|
7
|
+
customFindReplace: boolean;
|
|
8
8
|
getNode: () => PMNode;
|
|
9
9
|
getPos: getPosHandlerNode;
|
|
10
|
-
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
11
10
|
onMaybeNodeSelection: () => void;
|
|
12
|
-
|
|
11
|
+
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
12
|
+
view: EditorView;
|
|
13
13
|
}
|
|
14
14
|
export declare const keymapExtension: ({ view, getNode, getPos, selectCodeBlockNode, onMaybeNodeSelection, customFindReplace, }: KeymapProps) => Extension;
|
|
15
15
|
export {};
|
|
@@ -4,14 +4,14 @@ import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
|
4
4
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
interface MaybeEscapeProps {
|
|
7
|
-
unit: 'line' | 'char';
|
|
8
|
-
dir: -1 | 1;
|
|
9
|
-
view: EditorView;
|
|
10
7
|
cm: CodeMirror;
|
|
11
|
-
|
|
8
|
+
dir: -1 | 1;
|
|
12
9
|
getNode: () => PMNode;
|
|
10
|
+
getPos: getPosHandlerNode;
|
|
13
11
|
onMaybeNodeSelection: () => void;
|
|
14
12
|
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
13
|
+
unit: 'line' | 'char';
|
|
14
|
+
view: EditorView;
|
|
15
15
|
}
|
|
16
16
|
export declare const maybeEscapeKeymap: ({ unit, dir, view, cm, getPos, getNode, onMaybeNodeSelection, selectCodeBlockNode, }: MaybeEscapeProps) => boolean;
|
|
17
17
|
export {};
|
|
@@ -3,10 +3,10 @@ import type { IntlShape } from 'react-intl-next';
|
|
|
3
3
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
4
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
5
5
|
interface Props {
|
|
6
|
+
allowCodeFolding: boolean;
|
|
6
7
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
7
8
|
extensions: Extension[];
|
|
8
9
|
getIntl: () => IntlShape;
|
|
9
|
-
allowCodeFolding: boolean;
|
|
10
10
|
}
|
|
11
11
|
export declare const lazyCodeBlockView: (props: Props) => import("@atlaskit/editor-common/lazy-node-view").NodeViewConstructor;
|
|
12
12
|
export {};
|
|
@@ -4,10 +4,10 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
|
4
4
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
5
5
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
6
6
|
interface Props {
|
|
7
|
+
allowCodeFolding: boolean;
|
|
7
8
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
8
9
|
extensions: Extension[];
|
|
9
10
|
getIntl: () => IntlShape;
|
|
10
|
-
allowCodeFolding: boolean;
|
|
11
11
|
}
|
|
12
12
|
export declare const createPlugin: (props: Props) => SafePlugin<any>;
|
|
13
13
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-code-block-advanced",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"description": "CodeBlockAdvanced plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
".": "./src/index.ts"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@atlaskit/adf-schema": "^50.2.
|
|
34
|
+
"@atlaskit/adf-schema": "^50.2.2",
|
|
35
35
|
"@atlaskit/editor-plugin-code-block": "^5.0.0",
|
|
36
36
|
"@atlaskit/editor-plugin-editor-disabled": "^3.0.0",
|
|
37
37
|
"@atlaskit/editor-plugin-find-replace": "^3.2.0",
|
|
38
|
-
"@atlaskit/editor-plugin-selection": "^3.
|
|
38
|
+
"@atlaskit/editor-plugin-selection": "^3.2.0",
|
|
39
39
|
"@atlaskit/editor-plugin-selection-marker": "^3.0.0",
|
|
40
40
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
41
41
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
42
|
-
"@atlaskit/tmp-editor-statsig": "^11.
|
|
42
|
+
"@atlaskit/tmp-editor-statsig": "^11.6.0",
|
|
43
43
|
"@atlaskit/tokens": "^6.0.0",
|
|
44
44
|
"@babel/runtime": "^7.0.0",
|
|
45
45
|
"@codemirror/autocomplete": "6.18.4",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"codemirror-lang-elixir": "4.0.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@atlaskit/editor-common": "^107.
|
|
58
|
+
"@atlaskit/editor-common": "^107.30.0",
|
|
59
59
|
"react": "^18.2.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
@@ -38,7 +38,7 @@ import { cmTheme, codeFoldingTheme } from '../ui/theme';
|
|
|
38
38
|
import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
|
|
39
39
|
import { getCMSelectionChanges } from './codemirrorSync/updateCMSelection';
|
|
40
40
|
import { firstCodeBlockInDocument } from './extensions/firstCodeBlockInDocument';
|
|
41
|
-
import { foldGutterExtension } from './extensions/foldGutter';
|
|
41
|
+
import { foldGutterExtension, getCodeBlockFoldStateEffects } from './extensions/foldGutter';
|
|
42
42
|
import { keymapExtension } from './extensions/keymap';
|
|
43
43
|
import { manageSelectionMarker } from './extensions/manageSelectionMarker';
|
|
44
44
|
import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
|
|
@@ -46,10 +46,10 @@ import { tripleClickSelectAllExtension } from './extensions/tripleClickExtension
|
|
|
46
46
|
import { LanguageLoader } from './languages/loader';
|
|
47
47
|
|
|
48
48
|
export interface ConfigProps {
|
|
49
|
+
allowCodeFolding: boolean;
|
|
49
50
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
50
51
|
extensions: Extension[];
|
|
51
52
|
getIntl: () => IntlShape;
|
|
52
|
-
allowCodeFolding: boolean;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// Based on: https://prosemirror.net/examples/codemirror/
|
|
@@ -146,7 +146,9 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
146
146
|
tripleClickSelectAllExtension(),
|
|
147
147
|
firstCodeBlockInDocument(getPos),
|
|
148
148
|
CodeMirror.contentAttributes.of({ 'aria-label': formattedAriaLabel }),
|
|
149
|
-
config.allowCodeFolding
|
|
149
|
+
config.allowCodeFolding
|
|
150
|
+
? [foldGutterExtension({ selectNode, getNode: () => this.node })]
|
|
151
|
+
: [],
|
|
150
152
|
],
|
|
151
153
|
});
|
|
152
154
|
|
|
@@ -164,6 +166,11 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
164
166
|
this.updating = false;
|
|
165
167
|
this.updateLanguage();
|
|
166
168
|
this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
|
|
169
|
+
|
|
170
|
+
// Restore fold state after initialization
|
|
171
|
+
if (config.allowCodeFolding) {
|
|
172
|
+
this.restoreFoldState();
|
|
173
|
+
}
|
|
167
174
|
}
|
|
168
175
|
|
|
169
176
|
destroy() {
|
|
@@ -233,6 +240,15 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
233
240
|
return undefined;
|
|
234
241
|
}
|
|
235
242
|
|
|
243
|
+
private restoreFoldState() {
|
|
244
|
+
this.updating = true;
|
|
245
|
+
const effects = getCodeBlockFoldStateEffects({ node: this.node, cm: this.cm });
|
|
246
|
+
if (effects) {
|
|
247
|
+
this.cm.dispatch({ effects });
|
|
248
|
+
}
|
|
249
|
+
this.updating = false;
|
|
250
|
+
}
|
|
251
|
+
|
|
236
252
|
update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource) {
|
|
237
253
|
this.maybeTryingToReachNodeSelection = false;
|
|
238
254
|
|
|
@@ -4,9 +4,9 @@ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
|
4
4
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
-
view: EditorView;
|
|
8
|
-
update: ViewUpdate;
|
|
9
7
|
offset: number;
|
|
8
|
+
update: ViewUpdate;
|
|
9
|
+
view: EditorView;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import { foldGutter, codeFolding } from '@codemirror/language';
|
|
1
|
+
import { foldGutter, codeFolding, foldState, foldEffect } from '@codemirror/language';
|
|
2
|
+
import { type StateEffect } from '@codemirror/state';
|
|
3
|
+
import type { EditorView as CodeMirror } from '@codemirror/view';
|
|
2
4
|
|
|
5
|
+
import {
|
|
6
|
+
setCodeBlockFoldState,
|
|
7
|
+
type FoldRange,
|
|
8
|
+
getCodeBlockFoldState,
|
|
9
|
+
} from '@atlaskit/editor-common/code-block';
|
|
3
10
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
4
|
-
import type { DOMOutputSpec } from '@atlaskit/editor-prosemirror/model';
|
|
11
|
+
import type { DOMOutputSpec, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
5
12
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
6
13
|
import { token } from '@atlaskit/tokens';
|
|
7
14
|
|
|
@@ -48,9 +55,29 @@ const chevronRight: DOMOutputSpec = [
|
|
|
48
55
|
],
|
|
49
56
|
];
|
|
50
57
|
|
|
51
|
-
export function foldGutterExtension({
|
|
58
|
+
export function foldGutterExtension({
|
|
59
|
+
selectNode,
|
|
60
|
+
getNode,
|
|
61
|
+
}: {
|
|
62
|
+
getNode: () => PMNode;
|
|
63
|
+
selectNode: () => void;
|
|
64
|
+
}) {
|
|
52
65
|
return [
|
|
53
66
|
foldGutter({
|
|
67
|
+
foldingChanged: (update) => {
|
|
68
|
+
const folds = update.state.field(foldState, false);
|
|
69
|
+
if (!folds) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const foldRanges: FoldRange[] = [];
|
|
73
|
+
|
|
74
|
+
folds.between(0, update.state.doc.length, (from, to) => {
|
|
75
|
+
foldRanges.push({ from, to });
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
setCodeBlockFoldState(getNode(), foldRanges);
|
|
79
|
+
return false;
|
|
80
|
+
},
|
|
54
81
|
domEventHandlers: {
|
|
55
82
|
click: (_view, _, event) => {
|
|
56
83
|
// If we're trying to click the button, don't select
|
|
@@ -126,3 +153,27 @@ export function foldGutterExtension({ selectNode }: { selectNode: () => void })
|
|
|
126
153
|
}),
|
|
127
154
|
];
|
|
128
155
|
}
|
|
156
|
+
|
|
157
|
+
export function getCodeBlockFoldStateEffects({
|
|
158
|
+
node,
|
|
159
|
+
cm,
|
|
160
|
+
}: {
|
|
161
|
+
cm: CodeMirror;
|
|
162
|
+
node: PMNode;
|
|
163
|
+
}): StateEffect<unknown>[] | undefined {
|
|
164
|
+
const savedFolds = getCodeBlockFoldState(node);
|
|
165
|
+
if (savedFolds.length === 0) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Create fold effects for each saved fold range
|
|
170
|
+
const effects = [];
|
|
171
|
+
for (const foldRange of savedFolds) {
|
|
172
|
+
// Validate that the fold range is still valid for the current document
|
|
173
|
+
const docLength = cm.state.doc.length;
|
|
174
|
+
if (foldRange.from >= 0 && foldRange.to <= docLength && foldRange.from < foldRange.to) {
|
|
175
|
+
effects.push(foldEffect.of({ from: foldRange.from, to: foldRange.to }));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return effects;
|
|
179
|
+
}
|
|
@@ -6,10 +6,10 @@ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
|
6
6
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
|
|
8
8
|
interface BackspaceProps {
|
|
9
|
-
view: EditorView;
|
|
10
9
|
cm: CodeMirror;
|
|
11
|
-
getPos: getPosHandlerNode;
|
|
12
10
|
getNode: () => PMNode;
|
|
11
|
+
getPos: getPosHandlerNode;
|
|
12
|
+
view: EditorView;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const backspaceKeymap = ({ cm, view, getPos, getNode }: BackspaceProps) => {
|
|
@@ -16,12 +16,12 @@ import { backspaceKeymap } from './backspace';
|
|
|
16
16
|
import { maybeEscapeKeymap } from './maybeEscape';
|
|
17
17
|
|
|
18
18
|
interface KeymapProps {
|
|
19
|
-
|
|
19
|
+
customFindReplace: boolean;
|
|
20
20
|
getNode: () => PMNode;
|
|
21
21
|
getPos: getPosHandlerNode;
|
|
22
|
-
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
23
22
|
onMaybeNodeSelection: () => void;
|
|
24
|
-
|
|
23
|
+
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
24
|
+
view: EditorView;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const keymapExtension = ({
|
|
@@ -7,14 +7,14 @@ import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
7
7
|
import { type EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
|
|
9
9
|
interface MaybeEscapeProps {
|
|
10
|
-
unit: 'line' | 'char';
|
|
11
|
-
dir: -1 | 1;
|
|
12
|
-
view: EditorView;
|
|
13
10
|
cm: CodeMirror;
|
|
14
|
-
|
|
11
|
+
dir: -1 | 1;
|
|
15
12
|
getNode: () => PMNode;
|
|
13
|
+
getPos: getPosHandlerNode;
|
|
16
14
|
onMaybeNodeSelection: () => void;
|
|
17
15
|
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
16
|
+
unit: 'line' | 'char';
|
|
17
|
+
view: EditorView;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export const maybeEscapeKeymap = ({
|
|
@@ -32,7 +32,7 @@ export const maybeEscapeKeymap = ({
|
|
|
32
32
|
}
|
|
33
33
|
const node = getNode();
|
|
34
34
|
const { state } = cm;
|
|
35
|
-
let main: {
|
|
35
|
+
let main: { empty: boolean; from: number; head: number; to: number } = state.selection.main;
|
|
36
36
|
if (!main.empty) {
|
|
37
37
|
return false;
|
|
38
38
|
}
|
|
@@ -30,12 +30,12 @@ type WidgetConstructor = ((view: EditorView, getPos: () => number | undefined) =
|
|
|
30
30
|
// See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
|
|
31
31
|
interface ExtendedProseMirrorDecoration extends Decoration {
|
|
32
32
|
inline: boolean;
|
|
33
|
-
widget: boolean;
|
|
34
33
|
type: {
|
|
35
34
|
attrs?: Record<string, string>;
|
|
36
|
-
toDOM?: WidgetConstructor;
|
|
37
35
|
side?: number;
|
|
36
|
+
toDOM?: WidgetConstructor;
|
|
38
37
|
};
|
|
38
|
+
widget: boolean;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
|
|
@@ -9,10 +9,10 @@ import type { EditorView, DecorationSource, Decoration } from '@atlaskit/editor-
|
|
|
9
9
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
10
10
|
|
|
11
11
|
interface Props {
|
|
12
|
+
allowCodeFolding: boolean;
|
|
12
13
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
13
14
|
extensions: Extension[];
|
|
14
15
|
getIntl: () => IntlShape;
|
|
15
|
-
allowCodeFolding: boolean;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export const lazyCodeBlockView = (props: Props) => {
|
package/src/pm-plugins/main.ts
CHANGED
|
@@ -11,10 +11,10 @@ import { lazyCodeBlockView } from '../nodeviews/lazyCodeBlockAdvanced';
|
|
|
11
11
|
import { shiftArrowDownWorkaround, shiftArrowUpWorkaround } from './shiftArrowKeyWorkaround';
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
14
|
+
allowCodeFolding: boolean;
|
|
14
15
|
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined;
|
|
15
16
|
extensions: Extension[];
|
|
16
17
|
getIntl: () => IntlShape;
|
|
17
|
-
allowCodeFolding: boolean;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export const createPlugin = (props: Props) => {
|