@atlaskit/editor-plugin-code-block-advanced 2.2.8 → 2.2.9

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/nodeviews/codeBlockAdvanced.js +34 -31
  3. package/dist/cjs/nodeviews/codemirrorSync/updateCMSelection.js +8 -10
  4. package/dist/cjs/nodeviews/extensions/manageSelectionMarker.js +1 -0
  5. package/dist/cjs/nodeviews/languages/loader.js +61 -29
  6. package/dist/es2019/nodeviews/codeBlockAdvanced.js +21 -21
  7. package/dist/es2019/nodeviews/codemirrorSync/updateCMSelection.js +7 -9
  8. package/dist/es2019/nodeviews/extensions/manageSelectionMarker.js +1 -0
  9. package/dist/es2019/nodeviews/languages/loader.js +8 -5
  10. package/dist/esm/nodeviews/codeBlockAdvanced.js +35 -32
  11. package/dist/esm/nodeviews/codemirrorSync/updateCMSelection.js +7 -9
  12. package/dist/esm/nodeviews/extensions/manageSelectionMarker.js +1 -0
  13. package/dist/esm/nodeviews/languages/loader.js +61 -29
  14. package/dist/types/nodeviews/codeBlockAdvanced.d.ts +5 -3
  15. package/dist/types/nodeviews/codemirrorSync/updateCMSelection.d.ts +3 -3
  16. package/dist/types/nodeviews/extensions/keymap/index.d.ts +1 -1
  17. package/dist/types/nodeviews/extensions/manageSelectionMarker.d.ts +3 -2
  18. package/dist/types/nodeviews/languages/loader.d.ts +1 -1
  19. package/dist/types/nodeviews/lazyCodeBlockAdvanced.d.ts +1 -1
  20. package/dist/types-ts4.5/nodeviews/codeBlockAdvanced.d.ts +5 -3
  21. package/dist/types-ts4.5/nodeviews/codemirrorSync/updateCMSelection.d.ts +3 -3
  22. package/dist/types-ts4.5/nodeviews/extensions/keymap/index.d.ts +1 -1
  23. package/dist/types-ts4.5/nodeviews/extensions/manageSelectionMarker.d.ts +3 -2
  24. package/dist/types-ts4.5/nodeviews/languages/loader.d.ts +1 -1
  25. package/dist/types-ts4.5/nodeviews/lazyCodeBlockAdvanced.d.ts +1 -1
  26. package/package.json +3 -3
  27. package/src/nodeviews/codeBlockAdvanced.ts +31 -28
  28. package/src/nodeviews/codemirrorSync/updateCMSelection.ts +8 -14
  29. package/src/nodeviews/extensions/keymap/index.ts +2 -2
  30. package/src/nodeviews/extensions/manageSelectionMarker.ts +3 -2
  31. package/src/nodeviews/languages/loader.ts +18 -17
  32. package/src/nodeviews/lazyCodeBlockAdvanced.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @atlaskit/editor-plugin-code-block-advanced
2
2
 
3
+ ## 2.2.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [#156363](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/156363)
8
+ [`fa74bacdec758`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fa74bacdec758) -
9
+ Reduce number of codemirror transactions fired for performance.
10
+ - Updated dependencies
11
+
3
12
  ## 2.2.8
4
13
 
5
14
  ### Patch Changes
@@ -62,7 +62,9 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
62
62
  });
63
63
  this.cm = new _view.EditorView({
64
64
  doc: this.node.textContent,
65
- extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), (0, _keymap.keymapExtension)({
65
+ extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of((0, _codeBlock.isCodeBlockWordWrapEnabled)(node) ? _view.EditorView.lineWrapping : []), this.languageCompartment.of([]), this.pmDecorationsCompartment.of(this.pmFacet.compute([], function () {
66
+ return innerDecorations;
67
+ })), (0, _keymap.keymapExtension)({
66
68
  view: view,
67
69
  getPos: getPos,
68
70
  getNode: getNode,
@@ -96,8 +98,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
96
98
  // inner editor
97
99
  this.updating = false;
98
100
  this.updateLanguage();
99
- this.updateWordWrap(node);
100
- this.updateProseMirrorDecorations(innerDecorations);
101
+ this.wordWrappingEnabled = (0, _codeBlock.isCodeBlockWordWrapEnabled)(node);
101
102
  }
102
103
  return (0, _createClass2.default)(CodeBlockAdvancedNodeView, [{
103
104
  key: "destroy",
@@ -167,26 +168,21 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
167
168
  }
168
169
  }
169
170
  }, {
170
- key: "updateWordWrap",
171
- value: function updateWordWrap(node) {
171
+ key: "getWordWrapEffects",
172
+ value: function getWordWrapEffects(node) {
172
173
  if (this.wordWrappingEnabled !== (0, _codeBlock.isCodeBlockWordWrapEnabled)(node)) {
173
- this.updating = true;
174
- this.cm.dispatch({
175
- effects: [this.lineWrappingCompartment.reconfigure((0, _codeBlock.isCodeBlockWordWrapEnabled)(node) ? _view.EditorView.lineWrapping : [])]
176
- });
177
- this.updating = false;
178
174
  this.wordWrappingEnabled = !this.wordWrappingEnabled;
175
+ return this.lineWrappingCompartment.reconfigure((0, _codeBlock.isCodeBlockWordWrapEnabled)(node) ? _view.EditorView.lineWrapping : []);
179
176
  }
177
+ return undefined;
180
178
  }
181
179
  }, {
182
180
  key: "update",
183
181
  value: function update(node, _, innerDecorations) {
184
- var _this2 = this;
185
182
  this.maybeTryingToReachNodeSelection = false;
186
183
  if (node.type !== this.node.type) {
187
184
  return false;
188
185
  }
189
- this.updateWordWrap(node);
190
186
  this.node = node;
191
187
  if (this.updating) {
192
188
  return true;
@@ -194,12 +190,21 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
194
190
  this.updateLanguage();
195
191
  var newText = node.textContent,
196
192
  curText = this.cm.state.doc.toString();
197
- (0, _updateCMSelection.updateCMSelection)(curText, newText, function (tr) {
198
- _this2.updating = true;
199
- _this2.cm.dispatch(tr);
200
- _this2.updating = false;
201
- });
202
- this.updateProseMirrorDecorations(innerDecorations);
193
+
194
+ // Updates bundled for performance (to avoid multiple-dispatches)
195
+ var changes = (0, _updateCMSelection.getCMSelectionChanges)(curText, newText);
196
+ var wordWrapEffect = this.getWordWrapEffects(node);
197
+ var prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
198
+ if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
199
+ this.updating = true;
200
+ this.cm.dispatch({
201
+ effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(function (effect) {
202
+ return !!effect;
203
+ }),
204
+ changes: changes
205
+ });
206
+ this.updating = false;
207
+ }
203
208
  return true;
204
209
  }
205
210
 
@@ -207,18 +212,16 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
207
212
  * Updates a facet which stores information on the prosemirror decorations
208
213
  *
209
214
  * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
215
+ * @param decorationSource
216
+ * @example
210
217
  */
211
218
  }, {
212
- key: "updateProseMirrorDecorations",
213
- value: function updateProseMirrorDecorations(decorationSource) {
214
- this.updating = true;
219
+ key: "getProseMirrorDecorationEffects",
220
+ value: function getProseMirrorDecorationEffects(decorationSource) {
215
221
  var computedFacet = this.pmFacet.compute([], function () {
216
222
  return decorationSource;
217
223
  });
218
- this.cm.dispatch({
219
- effects: this.pmDecorationsCompartment.reconfigure(computedFacet)
220
- });
221
- this.updating = false;
224
+ return this.pmDecorationsCompartment.reconfigure(computedFacet);
222
225
  }
223
226
  }, {
224
227
  key: "clearProseMirrorDecorations",
@@ -235,7 +238,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
235
238
  }, {
236
239
  key: "stopEvent",
237
240
  value: function stopEvent(e) {
238
- var _this3 = this,
241
+ var _this2 = this,
239
242
  _this$getPos5;
240
243
  if (e instanceof MouseEvent && e.type === 'mousedown') {
241
244
  // !Warning: Side effect!
@@ -246,13 +249,13 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
246
249
  setTimeout(function () {
247
250
  // Ensure the CM selection is reset - if we have a ranged selection when we do node selection can
248
251
  // cause funky behaviour
249
- _this3.updating = true;
250
- _this3.cm.dispatch({
252
+ _this2.updating = true;
253
+ _this2.cm.dispatch({
251
254
  selection: _state.EditorSelection.create([_state.EditorSelection.cursor(0)], 0)
252
255
  });
253
- _this3.updating = false;
254
- _this3.selectCodeBlockNode(undefined);
255
- _this3.view.focus();
256
+ _this2.updating = false;
257
+ _this2.selectCodeBlockNode(undefined);
258
+ _this2.view.focus();
256
259
  }, 20);
257
260
  }
258
261
  // If we have selected the node we should not stop these events
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.updateCMSelection = void 0;
6
+ exports.getCMSelectionChanges = void 0;
7
7
  /**
8
8
  *
9
9
  * Compares the updated text with the current to determine the transaction to fire
@@ -11,9 +11,9 @@ exports.updateCMSelection = void 0;
11
11
  *
12
12
  * @param curText string - the current CodeMirror text
13
13
  * @param newText string - the new CodeMirror text
14
- * @param updateCallback Callback to process the CodeMirror transaction
14
+ * @returns The changes or undefined if no change
15
15
  */
16
- var updateCMSelection = exports.updateCMSelection = function updateCMSelection(curText, newText, updateCallback) {
16
+ var getCMSelectionChanges = exports.getCMSelectionChanges = function getCMSelectionChanges(curText, newText) {
17
17
  if (newText !== curText) {
18
18
  var start = 0,
19
19
  curEnd = curText.length,
@@ -25,12 +25,10 @@ var updateCMSelection = exports.updateCMSelection = function updateCMSelection(c
25
25
  curEnd--;
26
26
  newEnd--;
27
27
  }
28
- updateCallback({
29
- changes: {
30
- from: start,
31
- to: curEnd,
32
- insert: newText.slice(start, newEnd)
33
- }
34
- });
28
+ return {
29
+ from: start,
30
+ to: curEnd,
31
+ insert: newText.slice(start, newEnd)
32
+ };
35
33
  }
36
34
  };
@@ -10,6 +10,7 @@ var _view = require("@codemirror/view");
10
10
  *
11
11
  * @param api
12
12
  * @returns CodeMirror Extension
13
+ * @example
13
14
  */
14
15
  var manageSelectionMarker = exports.manageSelectionMarker = function manageSelectionMarker(api) {
15
16
  var decoHide;
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.LanguageLoader = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
@@ -23,35 +25,65 @@ var LanguageLoader = exports.LanguageLoader = /*#__PURE__*/function () {
23
25
  }
24
26
  return (0, _createClass2.default)(LanguageLoader, [{
25
27
  key: "updateLanguage",
26
- value: function updateLanguage(languageName) {
27
- var _this = this;
28
- if (languageName === this.languageName) {
29
- return;
30
- }
31
- var language = (0, _languageMap.mapLanguageToCodeMirror)(languageName);
32
- var configureEmpty = function configureEmpty() {
33
- _this.updateLanguageCompartment([]);
34
- _this.languageName = '';
35
- };
36
- if (!language) {
37
- configureEmpty();
38
- return;
39
- }
40
- language.load().then(function (lang) {
41
- if (lang) {
42
- var styling = (0, _syntaxHighlightingTheme.languageStyling)(lang.language);
43
- if (styling) {
44
- _this.updateLanguageCompartment([lang, (0, _language.syntaxHighlighting)(styling)]);
45
- } else {
46
- _this.updateLanguageCompartment(lang);
28
+ value: function () {
29
+ var _updateLanguage = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(languageName) {
30
+ var _this = this;
31
+ var language, configureEmpty, lang, styling;
32
+ return _regenerator.default.wrap(function _callee$(_context) {
33
+ while (1) switch (_context.prev = _context.next) {
34
+ case 0:
35
+ if (!(languageName === this.languageName)) {
36
+ _context.next = 2;
37
+ break;
38
+ }
39
+ return _context.abrupt("return");
40
+ case 2:
41
+ language = (0, _languageMap.mapLanguageToCodeMirror)(languageName);
42
+ configureEmpty = function configureEmpty() {
43
+ if (_this.languageName) {
44
+ _this.updateLanguageCompartment([]);
45
+ }
46
+ _this.languageName = '';
47
+ };
48
+ if (language) {
49
+ _context.next = 7;
50
+ break;
51
+ }
52
+ configureEmpty();
53
+ return _context.abrupt("return");
54
+ case 7:
55
+ _context.prev = 7;
56
+ _context.next = 10;
57
+ return language.load();
58
+ case 10:
59
+ lang = _context.sent;
60
+ if (lang) {
61
+ styling = (0, _syntaxHighlightingTheme.languageStyling)(lang.language);
62
+ if (styling) {
63
+ this.updateLanguageCompartment([lang, (0, _language.syntaxHighlighting)(styling)]);
64
+ } else {
65
+ this.updateLanguageCompartment(lang);
66
+ }
67
+ this.languageName = languageName;
68
+ } else {
69
+ configureEmpty();
70
+ }
71
+ _context.next = 17;
72
+ break;
73
+ case 14:
74
+ _context.prev = 14;
75
+ _context.t0 = _context["catch"](7);
76
+ configureEmpty();
77
+ case 17:
78
+ case "end":
79
+ return _context.stop();
47
80
  }
48
- _this.languageName = languageName;
49
- } else {
50
- configureEmpty();
51
- }
52
- }).catch(function () {
53
- configureEmpty();
54
- });
55
- }
81
+ }, _callee, this, [[7, 14]]);
82
+ }));
83
+ function updateLanguage(_x) {
84
+ return _updateLanguage.apply(this, arguments);
85
+ }
86
+ return updateLanguage;
87
+ }()
56
88
  }]);
57
89
  }();
@@ -10,7 +10,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
10
10
  import { highlightStyle } from '../ui/syntaxHighlightingTheme';
11
11
  import { cmTheme } from '../ui/theme';
12
12
  import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
13
- import { updateCMSelection } from './codemirrorSync/updateCMSelection';
13
+ import { getCMSelectionChanges } from './codemirrorSync/updateCMSelection';
14
14
  import { keymapExtension } from './extensions/keymap';
15
15
  import { manageSelectionMarker } from './extensions/manageSelectionMarker';
16
16
  import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
@@ -44,7 +44,7 @@ class CodeBlockAdvancedNodeView {
44
44
  });
45
45
  this.cm = new CodeMirror({
46
46
  doc: this.node.textContent,
47
- extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), keymapExtension({
47
+ extensions: [...config.extensions, this.lineWrappingCompartment.of(isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : []), this.languageCompartment.of([]), this.pmDecorationsCompartment.of(this.pmFacet.compute([], () => innerDecorations)), keymapExtension({
48
48
  view,
49
49
  getPos,
50
50
  getNode,
@@ -76,8 +76,7 @@ class CodeBlockAdvancedNodeView {
76
76
  // inner editor
77
77
  this.updating = false;
78
78
  this.updateLanguage();
79
- this.updateWordWrap(node);
80
- this.updateProseMirrorDecorations(innerDecorations);
79
+ this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
81
80
  }
82
81
  destroy() {
83
82
  var _this$cleanupDisabled;
@@ -134,22 +133,18 @@ class CodeBlockAdvancedNodeView {
134
133
  this.view.dispatch(tr);
135
134
  }
136
135
  }
137
- updateWordWrap(node) {
136
+ getWordWrapEffects(node) {
138
137
  if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
139
- this.updating = true;
140
- this.cm.dispatch({
141
- effects: [this.lineWrappingCompartment.reconfigure(isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : [])]
142
- });
143
- this.updating = false;
144
138
  this.wordWrappingEnabled = !this.wordWrappingEnabled;
139
+ return this.lineWrappingCompartment.reconfigure(isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : []);
145
140
  }
141
+ return undefined;
146
142
  }
147
143
  update(node, _, innerDecorations) {
148
144
  this.maybeTryingToReachNodeSelection = false;
149
145
  if (node.type !== this.node.type) {
150
146
  return false;
151
147
  }
152
- this.updateWordWrap(node);
153
148
  this.node = node;
154
149
  if (this.updating) {
155
150
  return true;
@@ -157,12 +152,19 @@ class CodeBlockAdvancedNodeView {
157
152
  this.updateLanguage();
158
153
  const newText = node.textContent,
159
154
  curText = this.cm.state.doc.toString();
160
- updateCMSelection(curText, newText, tr => {
155
+
156
+ // Updates bundled for performance (to avoid multiple-dispatches)
157
+ const changes = getCMSelectionChanges(curText, newText);
158
+ const wordWrapEffect = this.getWordWrapEffects(node);
159
+ const prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
160
+ if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
161
161
  this.updating = true;
162
- this.cm.dispatch(tr);
162
+ this.cm.dispatch({
163
+ effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(effect => !!effect),
164
+ changes
165
+ });
163
166
  this.updating = false;
164
- });
165
- this.updateProseMirrorDecorations(innerDecorations);
167
+ }
166
168
  return true;
167
169
  }
168
170
 
@@ -170,14 +172,12 @@ class CodeBlockAdvancedNodeView {
170
172
  * Updates a facet which stores information on the prosemirror decorations
171
173
  *
172
174
  * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
175
+ * @param decorationSource
176
+ * @example
173
177
  */
174
- updateProseMirrorDecorations(decorationSource) {
175
- this.updating = true;
178
+ getProseMirrorDecorationEffects(decorationSource) {
176
179
  const computedFacet = this.pmFacet.compute([], () => decorationSource);
177
- this.cm.dispatch({
178
- effects: this.pmDecorationsCompartment.reconfigure(computedFacet)
179
- });
180
- this.updating = false;
180
+ return this.pmDecorationsCompartment.reconfigure(computedFacet);
181
181
  }
182
182
  clearProseMirrorDecorations() {
183
183
  this.updating = true;
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * @param curText string - the current CodeMirror text
7
7
  * @param newText string - the new CodeMirror text
8
- * @param updateCallback Callback to process the CodeMirror transaction
8
+ * @returns The changes or undefined if no change
9
9
  */
10
- export const updateCMSelection = (curText, newText, updateCallback) => {
10
+ export const getCMSelectionChanges = (curText, newText) => {
11
11
  if (newText !== curText) {
12
12
  let start = 0,
13
13
  curEnd = curText.length,
@@ -19,12 +19,10 @@ export const updateCMSelection = (curText, newText, updateCallback) => {
19
19
  curEnd--;
20
20
  newEnd--;
21
21
  }
22
- updateCallback({
23
- changes: {
24
- from: start,
25
- to: curEnd,
26
- insert: newText.slice(start, newEnd)
27
- }
28
- });
22
+ return {
23
+ from: start,
24
+ to: curEnd,
25
+ insert: newText.slice(start, newEnd)
26
+ };
29
27
  }
30
28
  };
@@ -4,6 +4,7 @@ import { EditorView as CodeMirror } from '@codemirror/view';
4
4
  *
5
5
  * @param api
6
6
  * @returns CodeMirror Extension
7
+ * @example
7
8
  */
8
9
  export const manageSelectionMarker = api => {
9
10
  let decoHide;
@@ -12,20 +12,23 @@ export class LanguageLoader {
12
12
  _defineProperty(this, "languageName", '');
13
13
  this.updateLanguageCompartment = updateLanguageCompartment;
14
14
  }
15
- updateLanguage(languageName) {
15
+ async updateLanguage(languageName) {
16
16
  if (languageName === this.languageName) {
17
17
  return;
18
18
  }
19
19
  const language = mapLanguageToCodeMirror(languageName);
20
20
  const configureEmpty = () => {
21
- this.updateLanguageCompartment([]);
21
+ if (this.languageName) {
22
+ this.updateLanguageCompartment([]);
23
+ }
22
24
  this.languageName = '';
23
25
  };
24
26
  if (!language) {
25
27
  configureEmpty();
26
28
  return;
27
29
  }
28
- language.load().then(lang => {
30
+ try {
31
+ const lang = await language.load();
29
32
  if (lang) {
30
33
  const styling = languageStyling(lang.language);
31
34
  if (styling) {
@@ -37,8 +40,8 @@ export class LanguageLoader {
37
40
  } else {
38
41
  configureEmpty();
39
42
  }
40
- }).catch(() => {
43
+ } catch (e) {
41
44
  configureEmpty();
42
- });
45
+ }
43
46
  }
44
47
  }
@@ -13,7 +13,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
13
13
  import { highlightStyle } from '../ui/syntaxHighlightingTheme';
14
14
  import { cmTheme } from '../ui/theme';
15
15
  import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
16
- import { updateCMSelection } from './codemirrorSync/updateCMSelection';
16
+ import { getCMSelectionChanges } from './codemirrorSync/updateCMSelection';
17
17
  import { keymapExtension } from './extensions/keymap';
18
18
  import { manageSelectionMarker } from './extensions/manageSelectionMarker';
19
19
  import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
@@ -55,7 +55,9 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
55
55
  });
56
56
  this.cm = new CodeMirror({
57
57
  doc: this.node.textContent,
58
- extensions: [].concat(_toConsumableArray(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), keymapExtension({
58
+ extensions: [].concat(_toConsumableArray(config.extensions), [this.lineWrappingCompartment.of(isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : []), this.languageCompartment.of([]), this.pmDecorationsCompartment.of(this.pmFacet.compute([], function () {
59
+ return innerDecorations;
60
+ })), keymapExtension({
59
61
  view: view,
60
62
  getPos: getPos,
61
63
  getNode: getNode,
@@ -89,8 +91,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
89
91
  // inner editor
90
92
  this.updating = false;
91
93
  this.updateLanguage();
92
- this.updateWordWrap(node);
93
- this.updateProseMirrorDecorations(innerDecorations);
94
+ this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
94
95
  }
95
96
  return _createClass(CodeBlockAdvancedNodeView, [{
96
97
  key: "destroy",
@@ -160,26 +161,21 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
160
161
  }
161
162
  }
162
163
  }, {
163
- key: "updateWordWrap",
164
- value: function updateWordWrap(node) {
164
+ key: "getWordWrapEffects",
165
+ value: function getWordWrapEffects(node) {
165
166
  if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
166
- this.updating = true;
167
- this.cm.dispatch({
168
- effects: [this.lineWrappingCompartment.reconfigure(isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : [])]
169
- });
170
- this.updating = false;
171
167
  this.wordWrappingEnabled = !this.wordWrappingEnabled;
168
+ return this.lineWrappingCompartment.reconfigure(isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : []);
172
169
  }
170
+ return undefined;
173
171
  }
174
172
  }, {
175
173
  key: "update",
176
174
  value: function update(node, _, innerDecorations) {
177
- var _this2 = this;
178
175
  this.maybeTryingToReachNodeSelection = false;
179
176
  if (node.type !== this.node.type) {
180
177
  return false;
181
178
  }
182
- this.updateWordWrap(node);
183
179
  this.node = node;
184
180
  if (this.updating) {
185
181
  return true;
@@ -187,12 +183,21 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
187
183
  this.updateLanguage();
188
184
  var newText = node.textContent,
189
185
  curText = this.cm.state.doc.toString();
190
- updateCMSelection(curText, newText, function (tr) {
191
- _this2.updating = true;
192
- _this2.cm.dispatch(tr);
193
- _this2.updating = false;
194
- });
195
- this.updateProseMirrorDecorations(innerDecorations);
186
+
187
+ // Updates bundled for performance (to avoid multiple-dispatches)
188
+ var changes = getCMSelectionChanges(curText, newText);
189
+ var wordWrapEffect = this.getWordWrapEffects(node);
190
+ var prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
191
+ if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
192
+ this.updating = true;
193
+ this.cm.dispatch({
194
+ effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(function (effect) {
195
+ return !!effect;
196
+ }),
197
+ changes: changes
198
+ });
199
+ this.updating = false;
200
+ }
196
201
  return true;
197
202
  }
198
203
 
@@ -200,18 +205,16 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
200
205
  * Updates a facet which stores information on the prosemirror decorations
201
206
  *
202
207
  * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
208
+ * @param decorationSource
209
+ * @example
203
210
  */
204
211
  }, {
205
- key: "updateProseMirrorDecorations",
206
- value: function updateProseMirrorDecorations(decorationSource) {
207
- this.updating = true;
212
+ key: "getProseMirrorDecorationEffects",
213
+ value: function getProseMirrorDecorationEffects(decorationSource) {
208
214
  var computedFacet = this.pmFacet.compute([], function () {
209
215
  return decorationSource;
210
216
  });
211
- this.cm.dispatch({
212
- effects: this.pmDecorationsCompartment.reconfigure(computedFacet)
213
- });
214
- this.updating = false;
217
+ return this.pmDecorationsCompartment.reconfigure(computedFacet);
215
218
  }
216
219
  }, {
217
220
  key: "clearProseMirrorDecorations",
@@ -228,7 +231,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
228
231
  }, {
229
232
  key: "stopEvent",
230
233
  value: function stopEvent(e) {
231
- var _this3 = this,
234
+ var _this2 = this,
232
235
  _this$getPos5;
233
236
  if (e instanceof MouseEvent && e.type === 'mousedown') {
234
237
  // !Warning: Side effect!
@@ -239,13 +242,13 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
239
242
  setTimeout(function () {
240
243
  // Ensure the CM selection is reset - if we have a ranged selection when we do node selection can
241
244
  // cause funky behaviour
242
- _this3.updating = true;
243
- _this3.cm.dispatch({
245
+ _this2.updating = true;
246
+ _this2.cm.dispatch({
244
247
  selection: EditorSelection.create([EditorSelection.cursor(0)], 0)
245
248
  });
246
- _this3.updating = false;
247
- _this3.selectCodeBlockNode(undefined);
248
- _this3.view.focus();
249
+ _this2.updating = false;
250
+ _this2.selectCodeBlockNode(undefined);
251
+ _this2.view.focus();
249
252
  }, 20);
250
253
  }
251
254
  // If we have selected the node we should not stop these events
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * @param curText string - the current CodeMirror text
7
7
  * @param newText string - the new CodeMirror text
8
- * @param updateCallback Callback to process the CodeMirror transaction
8
+ * @returns The changes or undefined if no change
9
9
  */
10
- export var updateCMSelection = function updateCMSelection(curText, newText, updateCallback) {
10
+ export var getCMSelectionChanges = function getCMSelectionChanges(curText, newText) {
11
11
  if (newText !== curText) {
12
12
  var start = 0,
13
13
  curEnd = curText.length,
@@ -19,12 +19,10 @@ export var updateCMSelection = function updateCMSelection(curText, newText, upda
19
19
  curEnd--;
20
20
  newEnd--;
21
21
  }
22
- updateCallback({
23
- changes: {
24
- from: start,
25
- to: curEnd,
26
- insert: newText.slice(start, newEnd)
27
- }
28
- });
22
+ return {
23
+ from: start,
24
+ to: curEnd,
25
+ insert: newText.slice(start, newEnd)
26
+ };
29
27
  }
30
28
  };
@@ -4,6 +4,7 @@ import { EditorView as CodeMirror } from '@codemirror/view';
4
4
  *
5
5
  * @param api
6
6
  * @returns CodeMirror Extension
7
+ * @example
7
8
  */
8
9
  export var manageSelectionMarker = function manageSelectionMarker(api) {
9
10
  var decoHide;
@@ -1,6 +1,8 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
1
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
3
  import _createClass from "@babel/runtime/helpers/createClass";
3
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
6
  import { syntaxHighlighting } from '@codemirror/language';
5
7
  import { languageStyling } from '../../ui/syntaxHighlightingTheme';
6
8
  import { mapLanguageToCodeMirror } from './languageMap';
@@ -17,35 +19,65 @@ export var LanguageLoader = /*#__PURE__*/function () {
17
19
  }
18
20
  return _createClass(LanguageLoader, [{
19
21
  key: "updateLanguage",
20
- value: function updateLanguage(languageName) {
21
- var _this = this;
22
- if (languageName === this.languageName) {
23
- return;
24
- }
25
- var language = mapLanguageToCodeMirror(languageName);
26
- var configureEmpty = function configureEmpty() {
27
- _this.updateLanguageCompartment([]);
28
- _this.languageName = '';
29
- };
30
- if (!language) {
31
- configureEmpty();
32
- return;
33
- }
34
- language.load().then(function (lang) {
35
- if (lang) {
36
- var styling = languageStyling(lang.language);
37
- if (styling) {
38
- _this.updateLanguageCompartment([lang, syntaxHighlighting(styling)]);
39
- } else {
40
- _this.updateLanguageCompartment(lang);
22
+ value: function () {
23
+ var _updateLanguage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(languageName) {
24
+ var _this = this;
25
+ var language, configureEmpty, lang, styling;
26
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
27
+ while (1) switch (_context.prev = _context.next) {
28
+ case 0:
29
+ if (!(languageName === this.languageName)) {
30
+ _context.next = 2;
31
+ break;
32
+ }
33
+ return _context.abrupt("return");
34
+ case 2:
35
+ language = mapLanguageToCodeMirror(languageName);
36
+ configureEmpty = function configureEmpty() {
37
+ if (_this.languageName) {
38
+ _this.updateLanguageCompartment([]);
39
+ }
40
+ _this.languageName = '';
41
+ };
42
+ if (language) {
43
+ _context.next = 7;
44
+ break;
45
+ }
46
+ configureEmpty();
47
+ return _context.abrupt("return");
48
+ case 7:
49
+ _context.prev = 7;
50
+ _context.next = 10;
51
+ return language.load();
52
+ case 10:
53
+ lang = _context.sent;
54
+ if (lang) {
55
+ styling = languageStyling(lang.language);
56
+ if (styling) {
57
+ this.updateLanguageCompartment([lang, syntaxHighlighting(styling)]);
58
+ } else {
59
+ this.updateLanguageCompartment(lang);
60
+ }
61
+ this.languageName = languageName;
62
+ } else {
63
+ configureEmpty();
64
+ }
65
+ _context.next = 17;
66
+ break;
67
+ case 14:
68
+ _context.prev = 14;
69
+ _context.t0 = _context["catch"](7);
70
+ configureEmpty();
71
+ case 17:
72
+ case "end":
73
+ return _context.stop();
41
74
  }
42
- _this.languageName = languageName;
43
- } else {
44
- configureEmpty();
45
- }
46
- }).catch(function () {
47
- configureEmpty();
48
- });
49
- }
75
+ }, _callee, this, [[7, 14]]);
76
+ }));
77
+ function updateLanguage(_x) {
78
+ return _updateLanguage.apply(this, arguments);
79
+ }
80
+ return updateLanguage;
81
+ }()
50
82
  }]);
51
83
  }();
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { ViewUpdate } from '@codemirror/view';
3
3
  import type { getPosHandler, getPosHandlerNode, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
@@ -32,14 +32,16 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
32
32
  private updateLanguage;
33
33
  private selectCodeBlockNode;
34
34
  private wordWrappingEnabled;
35
- private updateWordWrap;
35
+ private getWordWrapEffects;
36
36
  update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource): boolean;
37
37
  /**
38
38
  * Updates a facet which stores information on the prosemirror decorations
39
39
  *
40
40
  * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
41
+ * @param decorationSource
42
+ * @example
41
43
  */
42
- private updateProseMirrorDecorations;
44
+ private getProseMirrorDecorationEffects;
43
45
  private clearProseMirrorDecorations;
44
46
  stopEvent(e: Event): boolean;
45
47
  }
@@ -1,4 +1,4 @@
1
- import { TransactionSpec as CMTransactionSpec } from '@codemirror/state';
1
+ import { ChangeSpec } from '@codemirror/state';
2
2
  /**
3
3
  *
4
4
  * Compares the updated text with the current to determine the transaction to fire
@@ -6,6 +6,6 @@ import { TransactionSpec as CMTransactionSpec } from '@codemirror/state';
6
6
  *
7
7
  * @param curText string - the current CodeMirror text
8
8
  * @param newText string - the new CodeMirror text
9
- * @param updateCallback Callback to process the CodeMirror transaction
9
+ * @returns The changes or undefined if no change
10
10
  */
11
- export declare const updateCMSelection: (curText: string, newText: string, updateCallback: (value: CMTransactionSpec) => void) => void;
11
+ export declare const getCMSelectionChanges: (curText: string, newText: string) => ChangeSpec | undefined;
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { RelativeSelectionPos } from '@atlaskit/editor-common/selection';
3
3
  import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
4
4
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
@@ -1,10 +1,11 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
- import { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
3
+ import type { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
4
4
  /**
5
5
  * Hides selection marker decoration when focused on codemirror editor and re-enables on blur
6
6
  *
7
7
  * @param api
8
8
  * @returns CodeMirror Extension
9
+ * @example
9
10
  */
10
11
  export declare const manageSelectionMarker: (api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined) => Extension;
@@ -8,5 +8,5 @@ export declare class LanguageLoader {
8
8
  private updateLanguageCompartment;
9
9
  private languageName;
10
10
  constructor(updateLanguageCompartment: (value: LanguageSupport | [LanguageSupport, Extension] | []) => void);
11
- updateLanguage(languageName: string): void;
11
+ updateLanguage(languageName: string): Promise<void>;
12
12
  }
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
4
4
  interface Props {
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { ViewUpdate } from '@codemirror/view';
3
3
  import type { getPosHandler, getPosHandlerNode, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
@@ -32,14 +32,16 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
32
32
  private updateLanguage;
33
33
  private selectCodeBlockNode;
34
34
  private wordWrappingEnabled;
35
- private updateWordWrap;
35
+ private getWordWrapEffects;
36
36
  update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource): boolean;
37
37
  /**
38
38
  * Updates a facet which stores information on the prosemirror decorations
39
39
  *
40
40
  * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
41
+ * @param decorationSource
42
+ * @example
41
43
  */
42
- private updateProseMirrorDecorations;
44
+ private getProseMirrorDecorationEffects;
43
45
  private clearProseMirrorDecorations;
44
46
  stopEvent(e: Event): boolean;
45
47
  }
@@ -1,4 +1,4 @@
1
- import { TransactionSpec as CMTransactionSpec } from '@codemirror/state';
1
+ import { ChangeSpec } from '@codemirror/state';
2
2
  /**
3
3
  *
4
4
  * Compares the updated text with the current to determine the transaction to fire
@@ -6,6 +6,6 @@ import { TransactionSpec as CMTransactionSpec } from '@codemirror/state';
6
6
  *
7
7
  * @param curText string - the current CodeMirror text
8
8
  * @param newText string - the new CodeMirror text
9
- * @param updateCallback Callback to process the CodeMirror transaction
9
+ * @returns The changes or undefined if no change
10
10
  */
11
- export declare const updateCMSelection: (curText: string, newText: string, updateCallback: (value: CMTransactionSpec) => void) => void;
11
+ export declare const getCMSelectionChanges: (curText: string, newText: string) => ChangeSpec | undefined;
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { RelativeSelectionPos } from '@atlaskit/editor-common/selection';
3
3
  import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
4
4
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
@@ -1,10 +1,11 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
- import { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
3
+ import type { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
4
4
  /**
5
5
  * Hides selection marker decoration when focused on codemirror editor and re-enables on blur
6
6
  *
7
7
  * @param api
8
8
  * @returns CodeMirror Extension
9
+ * @example
9
10
  */
10
11
  export declare const manageSelectionMarker: (api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined) => Extension;
@@ -12,5 +12,5 @@ export declare class LanguageLoader {
12
12
  Extension
13
13
  ] | [
14
14
  ]) => void);
15
- updateLanguage(languageName: string): void;
15
+ updateLanguage(languageName: string): Promise<void>;
16
16
  }
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
4
4
  interface Props {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-code-block-advanced",
3
- "version": "2.2.8",
3
+ "version": "2.2.9",
4
4
  "description": "CodeBlockAdvanced plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@atlaskit/adf-schema": "^47.6.0",
36
- "@atlaskit/editor-common": "^105.0.0",
36
+ "@atlaskit/editor-common": "^105.5.0",
37
37
  "@atlaskit/editor-plugin-code-block": "^4.4.0",
38
38
  "@atlaskit/editor-plugin-editor-disabled": "^2.0.0",
39
39
  "@atlaskit/editor-plugin-find-replace": "^2.2.0",
@@ -57,7 +57,7 @@
57
57
  "react": "^18.2.0"
58
58
  },
59
59
  "devDependencies": {
60
- "@atlaskit/code": "^17.1.0",
60
+ "@atlaskit/code": "^17.2.0",
61
61
  "typescript": "~5.4.2"
62
62
  },
63
63
  "techstack": {
@@ -2,10 +2,11 @@ import { closeBrackets } from '@codemirror/autocomplete';
2
2
  import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
3
3
  import {
4
4
  Compartment,
5
- Extension,
5
+ type Extension,
6
6
  EditorSelection,
7
7
  Facet,
8
8
  EditorState as CodeMirrorState,
9
+ StateEffect,
9
10
  } from '@codemirror/state';
10
11
  import { EditorView as CodeMirror, lineNumbers, ViewUpdate, gutters } from '@codemirror/view';
11
12
 
@@ -17,7 +18,7 @@ import type {
17
18
  ExtractInjectionAPI,
18
19
  } from '@atlaskit/editor-common/types';
19
20
  import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
20
- import { EditorSelectionAPI } from '@atlaskit/editor-plugin-selection';
21
+ import { type EditorSelectionAPI } from '@atlaskit/editor-plugin-selection';
21
22
  import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
22
23
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
23
24
  import type {
@@ -33,7 +34,7 @@ import { highlightStyle } from '../ui/syntaxHighlightingTheme';
33
34
  import { cmTheme } from '../ui/theme';
34
35
 
35
36
  import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
36
- import { updateCMSelection } from './codemirrorSync/updateCMSelection';
37
+ import { getCMSelectionChanges } from './codemirrorSync/updateCMSelection';
37
38
  import { keymapExtension } from './extensions/keymap';
38
39
  import { manageSelectionMarker } from './extensions/manageSelectionMarker';
39
40
  import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
@@ -90,9 +91,11 @@ class CodeBlockAdvancedNodeView implements NodeView {
90
91
  doc: this.node.textContent,
91
92
  extensions: [
92
93
  ...config.extensions,
93
- this.lineWrappingCompartment.of([]),
94
+ this.lineWrappingCompartment.of(
95
+ isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : [],
96
+ ),
94
97
  this.languageCompartment.of([]),
95
- this.pmDecorationsCompartment.of([]),
98
+ this.pmDecorationsCompartment.of(this.pmFacet.compute([], () => innerDecorations)),
96
99
  keymapExtension({
97
100
  view,
98
101
  getPos,
@@ -133,8 +136,7 @@ class CodeBlockAdvancedNodeView implements NodeView {
133
136
  // inner editor
134
137
  this.updating = false;
135
138
  this.updateLanguage();
136
- this.updateWordWrap(node);
137
- this.updateProseMirrorDecorations(innerDecorations);
139
+ this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
138
140
  }
139
141
 
140
142
  destroy() {
@@ -194,19 +196,14 @@ class CodeBlockAdvancedNodeView implements NodeView {
194
196
 
195
197
  private wordWrappingEnabled = false;
196
198
 
197
- private updateWordWrap(node: PMNode) {
199
+ private getWordWrapEffects(node: PMNode) {
198
200
  if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
199
- this.updating = true;
200
- this.cm.dispatch({
201
- effects: [
202
- this.lineWrappingCompartment.reconfigure(
203
- isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : [],
204
- ),
205
- ],
206
- });
207
- this.updating = false;
208
201
  this.wordWrappingEnabled = !this.wordWrappingEnabled;
202
+ return this.lineWrappingCompartment.reconfigure(
203
+ isCodeBlockWordWrapEnabled(node) ? CodeMirror.lineWrapping : [],
204
+ );
209
205
  }
206
+ return undefined;
210
207
  }
211
208
 
212
209
  update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource) {
@@ -215,7 +212,6 @@ class CodeBlockAdvancedNodeView implements NodeView {
215
212
  if (node.type !== this.node.type) {
216
213
  return false;
217
214
  }
218
- this.updateWordWrap(node);
219
215
  this.node = node;
220
216
  if (this.updating) {
221
217
  return true;
@@ -223,12 +219,21 @@ class CodeBlockAdvancedNodeView implements NodeView {
223
219
  this.updateLanguage();
224
220
  const newText = node.textContent,
225
221
  curText = this.cm.state.doc.toString();
226
- updateCMSelection(curText, newText, (tr) => {
222
+
223
+ // Updates bundled for performance (to avoid multiple-dispatches)
224
+ const changes = getCMSelectionChanges(curText, newText);
225
+ const wordWrapEffect = this.getWordWrapEffects(node);
226
+ const prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
227
+ if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
227
228
  this.updating = true;
228
- this.cm.dispatch(tr);
229
+ this.cm.dispatch({
230
+ effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(
231
+ (effect): effect is StateEffect<unknown> => !!effect,
232
+ ),
233
+ changes,
234
+ });
229
235
  this.updating = false;
230
- });
231
- this.updateProseMirrorDecorations(innerDecorations);
236
+ }
232
237
  return true;
233
238
  }
234
239
 
@@ -236,14 +241,12 @@ class CodeBlockAdvancedNodeView implements NodeView {
236
241
  * Updates a facet which stores information on the prosemirror decorations
237
242
  *
238
243
  * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
244
+ * @param decorationSource
245
+ * @example
239
246
  */
240
- private updateProseMirrorDecorations(decorationSource: DecorationSource) {
241
- this.updating = true;
247
+ private getProseMirrorDecorationEffects(decorationSource: DecorationSource) {
242
248
  const computedFacet = this.pmFacet.compute([], () => decorationSource);
243
- this.cm.dispatch({
244
- effects: this.pmDecorationsCompartment.reconfigure(computedFacet),
245
- });
246
- this.updating = false;
249
+ return this.pmDecorationsCompartment.reconfigure(computedFacet);
247
250
  }
248
251
 
249
252
  private clearProseMirrorDecorations() {
@@ -1,4 +1,4 @@
1
- import { TransactionSpec as CMTransactionSpec } from '@codemirror/state';
1
+ import { ChangeSpec } from '@codemirror/state';
2
2
 
3
3
  /**
4
4
  *
@@ -7,13 +7,9 @@ import { TransactionSpec as CMTransactionSpec } from '@codemirror/state';
7
7
  *
8
8
  * @param curText string - the current CodeMirror text
9
9
  * @param newText string - the new CodeMirror text
10
- * @param updateCallback Callback to process the CodeMirror transaction
10
+ * @returns The changes or undefined if no change
11
11
  */
12
- export const updateCMSelection = (
13
- curText: string,
14
- newText: string,
15
- updateCallback: (value: CMTransactionSpec) => void,
16
- ) => {
12
+ export const getCMSelectionChanges = (curText: string, newText: string): ChangeSpec | undefined => {
17
13
  if (newText !== curText) {
18
14
  let start = 0,
19
15
  curEnd = curText.length,
@@ -29,12 +25,10 @@ export const updateCMSelection = (
29
25
  curEnd--;
30
26
  newEnd--;
31
27
  }
32
- updateCallback({
33
- changes: {
34
- from: start,
35
- to: curEnd,
36
- insert: newText.slice(start, newEnd),
37
- },
38
- });
28
+ return {
29
+ from: start,
30
+ to: curEnd,
31
+ insert: newText.slice(start, newEnd),
32
+ };
39
33
  }
40
34
  };
@@ -1,6 +1,6 @@
1
1
  import { defaultKeymap, indentWithTab } from '@codemirror/commands';
2
- import { Extension } from '@codemirror/state';
3
- import { KeyBinding, keymap as cmKeymap } from '@codemirror/view';
2
+ import { type Extension } from '@codemirror/state';
3
+ import { type KeyBinding, keymap as cmKeymap } from '@codemirror/view';
4
4
 
5
5
  import { browser } from '@atlaskit/editor-common/browser';
6
6
  import { RelativeSelectionPos } from '@atlaskit/editor-common/selection';
@@ -1,15 +1,16 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
  import { EditorView as CodeMirror } from '@codemirror/view';
3
3
 
4
4
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
5
5
 
6
- import { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
6
+ import type { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
7
7
 
8
8
  /**
9
9
  * Hides selection marker decoration when focused on codemirror editor and re-enables on blur
10
10
  *
11
11
  * @param api
12
12
  * @returns CodeMirror Extension
13
+ * @example
13
14
  */
14
15
  export const manageSelectionMarker = (
15
16
  api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined,
@@ -18,14 +18,16 @@ export class LanguageLoader {
18
18
  ) => void,
19
19
  ) {}
20
20
 
21
- updateLanguage(languageName: string) {
21
+ async updateLanguage(languageName: string) {
22
22
  if (languageName === this.languageName) {
23
23
  return;
24
24
  }
25
25
  const language = mapLanguageToCodeMirror(languageName);
26
26
 
27
27
  const configureEmpty = () => {
28
- this.updateLanguageCompartment([]);
28
+ if (this.languageName) {
29
+ this.updateLanguageCompartment([]);
30
+ }
29
31
  this.languageName = '';
30
32
  };
31
33
 
@@ -34,23 +36,22 @@ export class LanguageLoader {
34
36
  return;
35
37
  }
36
38
 
37
- language
38
- .load()
39
- .then((lang) => {
40
- if (lang) {
41
- const styling = languageStyling(lang.language);
42
- if (styling) {
43
- this.updateLanguageCompartment([lang, syntaxHighlighting(styling)]);
44
- } else {
45
- this.updateLanguageCompartment(lang);
46
- }
47
- this.languageName = languageName;
39
+ try {
40
+ const lang = await language.load();
41
+
42
+ if (lang) {
43
+ const styling = languageStyling(lang.language);
44
+ if (styling) {
45
+ this.updateLanguageCompartment([lang, syntaxHighlighting(styling)]);
48
46
  } else {
49
- configureEmpty();
47
+ this.updateLanguageCompartment(lang);
50
48
  }
51
- })
52
- .catch(() => {
49
+ this.languageName = languageName;
50
+ } else {
53
51
  configureEmpty();
54
- });
52
+ }
53
+ } catch (e) {
54
+ configureEmpty();
55
+ }
55
56
  }
56
57
  }
@@ -1,4 +1,4 @@
1
- import { Extension } from '@codemirror/state';
1
+ import { type Extension } from '@codemirror/state';
2
2
 
3
3
  import { withLazyLoading } from '@atlaskit/editor-common/lazy-node-view';
4
4
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';