@atlaskit/editor-plugin-code-block-advanced 1.0.1 → 1.0.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/afm-cc/tsconfig.json +6 -0
  3. package/afm-jira/tsconfig.json +6 -0
  4. package/afm-post-office/tsconfig.json +6 -0
  5. package/dist/cjs/nodeviews/codeBlockAdvanced.js +31 -8
  6. package/dist/cjs/nodeviews/codeBlockNodeWithToDOMFixed.js +2 -1
  7. package/dist/cjs/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
  8. package/dist/cjs/nodeviews/extensions/keymap/index.js +23 -3
  9. package/dist/cjs/nodeviews/extensions/manageSelectionMarker.js +28 -0
  10. package/dist/cjs/nodeviews/extensions/prosemirrorDecorations.js +142 -0
  11. package/dist/es2019/nodeviews/codeBlockAdvanced.js +28 -10
  12. package/dist/es2019/nodeviews/codeBlockNodeWithToDOMFixed.js +2 -1
  13. package/dist/es2019/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
  14. package/dist/es2019/nodeviews/extensions/keymap/index.js +23 -3
  15. package/dist/es2019/nodeviews/extensions/manageSelectionMarker.js +22 -0
  16. package/dist/es2019/nodeviews/extensions/prosemirrorDecorations.js +107 -0
  17. package/dist/esm/nodeviews/codeBlockAdvanced.js +33 -10
  18. package/dist/esm/nodeviews/codeBlockNodeWithToDOMFixed.js +2 -1
  19. package/dist/esm/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
  20. package/dist/esm/nodeviews/extensions/keymap/index.js +23 -3
  21. package/dist/esm/nodeviews/extensions/manageSelectionMarker.js +22 -0
  22. package/dist/esm/nodeviews/extensions/prosemirrorDecorations.js +135 -0
  23. package/dist/types/codeBlockAdvancedPluginType.d.ts +9 -1
  24. package/dist/types/nodeviews/codeBlockAdvanced.d.ts +10 -2
  25. package/dist/types/nodeviews/extensions/keymap/index.d.ts +2 -1
  26. package/dist/types/nodeviews/extensions/manageSelectionMarker.d.ts +10 -0
  27. package/dist/types/nodeviews/extensions/prosemirrorDecorations.d.ts +20 -0
  28. package/dist/types-ts4.5/codeBlockAdvancedPluginType.d.ts +5 -1
  29. package/dist/types-ts4.5/nodeviews/codeBlockAdvanced.d.ts +10 -2
  30. package/dist/types-ts4.5/nodeviews/extensions/keymap/index.d.ts +2 -1
  31. package/dist/types-ts4.5/nodeviews/extensions/manageSelectionMarker.d.ts +10 -0
  32. package/dist/types-ts4.5/nodeviews/extensions/prosemirrorDecorations.d.ts +20 -0
  33. package/package.json +6 -4
  34. package/src/codeBlockAdvancedPluginType.ts +9 -1
  35. package/src/nodeviews/codeBlockAdvanced.ts +33 -7
  36. package/src/nodeviews/codeBlockNodeWithToDOMFixed.ts +1 -0
  37. package/src/nodeviews/codemirrorSync/syncCMWithPM.ts +0 -1
  38. package/src/nodeviews/extensions/keymap/index.ts +31 -1
  39. package/src/nodeviews/extensions/manageSelectionMarker.ts +28 -0
  40. package/src/nodeviews/extensions/prosemirrorDecorations.ts +156 -0
  41. package/tsconfig.app.json +6 -0
  42. package/dist/cjs/nodeviews/extensions/bidiCharWarning.js +0 -83
  43. package/dist/es2019/nodeviews/extensions/bidiCharWarning.js +0 -53
  44. package/dist/esm/nodeviews/extensions/bidiCharWarning.js +0 -77
  45. package/dist/types/nodeviews/extensions/bidiCharWarning.d.ts +0 -8
  46. package/dist/types-ts4.5/nodeviews/extensions/bidiCharWarning.d.ts +0 -8
  47. package/src/nodeviews/extensions/bidiCharWarning.ts +0 -72
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/editor-plugin-code-block-advanced
2
2
 
3
+ ## 1.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#107185](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/107185)
8
+ [`f0dd5f5bd4d4e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f0dd5f5bd4d4e) -
9
+ [ux] Sync all prosemirror decorations with codemirror decorations.
10
+ - Updated dependencies
11
+
12
+ ## 1.0.2
13
+
14
+ ### Patch Changes
15
+
16
+ - [#105726](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/105726)
17
+ [`2eb0f22c4b065`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2eb0f22c4b065) -
18
+ [ux] Fix toDOM implementation whitespace with 100+ lines of code
19
+ - [#103918](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/103918)
20
+ [`29844093c6ab4`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/29844093c6ab4) -
21
+ Expose new shared state for code block plugin which indicates the current node that the copy text
22
+ button is hovered for. Display highlight decorations for the copy text button in the advanced code
23
+ block plugin.
24
+ - Updated dependencies
25
+
3
26
  ## 1.0.1
4
27
 
5
28
  ### Patch Changes
@@ -26,9 +26,15 @@
26
26
  {
27
27
  "path": "../../editor-plugin-editor-disabled/afm-cc/tsconfig.json"
28
28
  },
29
+ {
30
+ "path": "../../editor-plugin-find-replace/afm-cc/tsconfig.json"
31
+ },
29
32
  {
30
33
  "path": "../../editor-plugin-selection/afm-cc/tsconfig.json"
31
34
  },
35
+ {
36
+ "path": "../../editor-plugin-selection-marker/afm-cc/tsconfig.json"
37
+ },
32
38
  {
33
39
  "path": "../../../design-system/tokens/afm-cc/tsconfig.json"
34
40
  }
@@ -26,9 +26,15 @@
26
26
  {
27
27
  "path": "../../editor-plugin-editor-disabled/afm-jira/tsconfig.json"
28
28
  },
29
+ {
30
+ "path": "../../editor-plugin-find-replace/afm-jira/tsconfig.json"
31
+ },
29
32
  {
30
33
  "path": "../../editor-plugin-selection/afm-jira/tsconfig.json"
31
34
  },
35
+ {
36
+ "path": "../../editor-plugin-selection-marker/afm-jira/tsconfig.json"
37
+ },
32
38
  {
33
39
  "path": "../../../design-system/tokens/afm-jira/tsconfig.json"
34
40
  }
@@ -26,9 +26,15 @@
26
26
  {
27
27
  "path": "../../editor-plugin-editor-disabled/afm-post-office/tsconfig.json"
28
28
  },
29
+ {
30
+ "path": "../../editor-plugin-find-replace/afm-post-office/tsconfig.json"
31
+ },
29
32
  {
30
33
  "path": "../../editor-plugin-selection/afm-post-office/tsconfig.json"
31
34
  },
35
+ {
36
+ "path": "../../editor-plugin-selection-marker/afm-post-office/tsconfig.json"
37
+ },
32
38
  {
33
39
  "path": "../../../design-system/tokens/afm-post-office/tsconfig.json"
34
40
  }
@@ -19,21 +19,24 @@ var _syntaxHighlightingTheme = require("../ui/syntaxHighlightingTheme");
19
19
  var _theme = require("../ui/theme");
20
20
  var _syncCMWithPM = require("./codemirrorSync/syncCMWithPM");
21
21
  var _updateCMSelection = require("./codemirrorSync/updateCMSelection");
22
- var _bidiCharWarning = require("./extensions/bidiCharWarning");
23
22
  var _keymap = require("./extensions/keymap");
23
+ var _manageSelectionMarker = require("./extensions/manageSelectionMarker");
24
+ var _prosemirrorDecorations = require("./extensions/prosemirrorDecorations");
24
25
  var _loader = require("./languages/loader");
25
26
  // Based on: https://prosemirror.net/examples/codemirror/
26
27
  var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
27
- // eslint-disable-next-line @typescript-eslint/max-params
28
28
  function CodeBlockAdvancedNodeView(node, view, getPos, config) {
29
29
  var _config$api,
30
30
  _this = this,
31
- _config$api2;
31
+ _config$api2,
32
+ _config$api3;
32
33
  (0, _classCallCheck2.default)(this, CodeBlockAdvancedNodeView);
33
34
  (0, _defineProperty2.default)(this, "lineWrappingCompartment", new _state.Compartment());
34
35
  (0, _defineProperty2.default)(this, "languageCompartment", new _state.Compartment());
35
36
  (0, _defineProperty2.default)(this, "readOnlyCompartment", new _state.Compartment());
37
+ (0, _defineProperty2.default)(this, "pmDecorationsCompartment", new _state.Compartment());
36
38
  (0, _defineProperty2.default)(this, "maybeTryingToReachNodeSelection", false);
39
+ (0, _defineProperty2.default)(this, "pmFacet", _state.Facet.define());
37
40
  (0, _defineProperty2.default)(this, "wordWrappingEnabled", false);
38
41
  this.node = node;
39
42
  this.view = view;
@@ -57,13 +60,14 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
57
60
  });
58
61
  this.cm = new _view.EditorView({
59
62
  doc: this.node.textContent,
60
- extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), (0, _keymap.keymapExtension)({
63
+ extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), (0, _keymap.keymapExtension)({
61
64
  view: view,
62
65
  getPos: getPos,
63
66
  getNode: getNode,
64
67
  selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
65
- onMaybeNodeSelection: onMaybeNodeSelection
66
- }), _theme.cmTheme, (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0, _view.lineNumbers)(),
68
+ onMaybeNodeSelection: onMaybeNodeSelection,
69
+ customFindReplace: Boolean((_config$api3 = config.api) === null || _config$api3 === void 0 ? void 0 : _config$api3.findReplace)
70
+ }), _theme.cmTheme, (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0, _language.bracketMatching)(), (0, _view.lineNumbers)(),
67
71
  // Explicitly disable "sticky" positioning on line numbers to match
68
72
  // Renderer behaviour
69
73
  (0, _view.gutters)({
@@ -72,7 +76,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
72
76
  return _this.forwardUpdate(update);
73
77
  }), this.readOnlyCompartment.of(_view.EditorView.editable.of(this.view.editable)), (0, _autocomplete.closeBrackets)(), _view.EditorView.editorAttributes.of({
74
78
  class: 'code-block'
75
- }), _bidiCharWarning.bidiCharWarningExtension])
79
+ }), (0, _manageSelectionMarker.manageSelectionMarker)(config.api), (0, _prosemirrorDecorations.prosemirrorDecorationPlugin)(this.pmFacet, view, getPos)])
76
80
  });
77
81
 
78
82
  // The editor's outer node is our DOM representation
@@ -158,7 +162,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
158
162
  }
159
163
  }, {
160
164
  key: "update",
161
- value: function update(node) {
165
+ value: function update(node, _, innerDecorations) {
162
166
  var _this2 = this;
163
167
  this.maybeTryingToReachNodeSelection = false;
164
168
  if (node.type !== this.node.type) {
@@ -177,8 +181,27 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
177
181
  _this2.cm.dispatch(tr);
178
182
  _this2.updating = false;
179
183
  });
184
+ this.updateProseMirrorDecorations(innerDecorations);
180
185
  return true;
181
186
  }
187
+
188
+ /**
189
+ * Updates a facet which stores information on the prosemirror decorations
190
+ *
191
+ * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
192
+ */
193
+ }, {
194
+ key: "updateProseMirrorDecorations",
195
+ value: function updateProseMirrorDecorations(decorationSource) {
196
+ this.updating = true;
197
+ var computedFacet = this.pmFacet.compute([], function () {
198
+ return decorationSource;
199
+ });
200
+ this.cm.dispatch({
201
+ effects: this.pmDecorationsCompartment.reconfigure(computedFacet)
202
+ });
203
+ this.updating = false;
204
+ }
182
205
  }, {
183
206
  key: "stopEvent",
184
207
  value: function stopEvent(e) {
@@ -60,7 +60,8 @@ var _toDOM = function toDOM(node, formattedAriaLabel) {
60
60
  style: (0, _lazyNodeView.convertToInlineCss)({
61
61
  textAlign: 'right',
62
62
  color: "var(--ds-text-subtlest, #626F86)",
63
- fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)"
63
+ fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
64
+ whiteSpace: 'pre-wrap'
64
65
  }),
65
66
  'data-label': content
66
67
  }]], ['div', {
@@ -23,7 +23,6 @@ var syncCMWithPM = exports.syncCMWithPM = function syncCMWithPM(_ref) {
23
23
  var pmSel = view.state.selection;
24
24
  if (update.docChanged || pmSel.from !== selFrom || pmSel.to !== selTo) {
25
25
  var tr = view.state.tr;
26
- // eslint-disable-next-line @typescript-eslint/max-params
27
26
  update.changes.iterChanges(function (fromA, toA, fromB, toB, text) {
28
27
  if (text.length) {
29
28
  tr.replaceWith(offset + fromA, offset + toA, view.state.schema.text(text.toString()));
@@ -8,6 +8,7 @@ exports.keymapExtension = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _commands = require("@codemirror/commands");
10
10
  var _view = require("@codemirror/view");
11
+ var _browser = require("@atlaskit/editor-common/browser");
11
12
  var _commands2 = require("@atlaskit/editor-prosemirror/commands");
12
13
  var _history = require("@atlaskit/editor-prosemirror/history");
13
14
  var _backspace = require("./backspace");
@@ -17,13 +18,15 @@ var keymapExtension = exports.keymapExtension = function keymapExtension(_ref) {
17
18
  getNode = _ref.getNode,
18
19
  getPos = _ref.getPos,
19
20
  selectCodeBlockNode = _ref.selectCodeBlockNode,
20
- onMaybeNodeSelection = _ref.onMaybeNodeSelection;
21
+ onMaybeNodeSelection = _ref.onMaybeNodeSelection,
22
+ customFindReplace = _ref.customFindReplace;
21
23
  return _view.keymap.of(codeBlockKeymap({
22
24
  view: view,
23
25
  getNode: getNode,
24
26
  getPos: getPos,
25
27
  selectCodeBlockNode: selectCodeBlockNode,
26
- onMaybeNodeSelection: onMaybeNodeSelection
28
+ onMaybeNodeSelection: onMaybeNodeSelection,
29
+ customFindReplace: customFindReplace
27
30
  }));
28
31
  };
29
32
  var codeBlockKeymap = function codeBlockKeymap(_ref2) {
@@ -31,7 +34,8 @@ var codeBlockKeymap = function codeBlockKeymap(_ref2) {
31
34
  getNode = _ref2.getNode,
32
35
  getPos = _ref2.getPos,
33
36
  selectCodeBlockNode = _ref2.selectCodeBlockNode,
34
- onMaybeNodeSelection = _ref2.onMaybeNodeSelection;
37
+ onMaybeNodeSelection = _ref2.onMaybeNodeSelection,
38
+ customFindReplace = _ref2.customFindReplace;
35
39
  return [{
36
40
  key: 'ArrowUp',
37
41
  run: function run(cm) {
@@ -88,6 +92,22 @@ var codeBlockKeymap = function codeBlockKeymap(_ref2) {
88
92
  onMaybeNodeSelection: onMaybeNodeSelection
89
93
  });
90
94
  }
95
+ }, {
96
+ key: 'Ctrl-f',
97
+ mac: 'Cmd-f',
98
+ run: function run() {
99
+ // Pass synthetic event to prosemirror
100
+ if (customFindReplace) {
101
+ view.dispatchEvent(new KeyboardEvent('keydown', {
102
+ key: 'f',
103
+ code: 'KeyF',
104
+ metaKey: _browser.browser.mac ? true : false,
105
+ ctrlKey: _browser.browser.mac ? false : true
106
+ }));
107
+ return true;
108
+ }
109
+ return false;
110
+ }
91
111
  }, {
92
112
  key: 'Ctrl-Enter',
93
113
  run: function run() {
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.manageSelectionMarker = void 0;
7
+ var _view = require("@codemirror/view");
8
+ /**
9
+ * Hides selection marker decoration when focused on codemirror editor and re-enables on blur
10
+ *
11
+ * @param api
12
+ * @returns CodeMirror Extension
13
+ */
14
+ var manageSelectionMarker = exports.manageSelectionMarker = function manageSelectionMarker(api) {
15
+ var decoHide;
16
+ return _view.EditorView.focusChangeEffect.of(function (_state, focusing) {
17
+ if (focusing) {
18
+ var _api$selectionMarker;
19
+ api === null || api === void 0 || (_api$selectionMarker = api.selectionMarker) === null || _api$selectionMarker === void 0 || _api$selectionMarker.actions.queueHideDecoration(function (hideDecoration) {
20
+ decoHide = hideDecoration;
21
+ });
22
+ } else {
23
+ var _decoHide;
24
+ (_decoHide = decoHide) === null || _decoHide === void 0 || _decoHide();
25
+ }
26
+ return null;
27
+ });
28
+ };
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.prosemirrorDecorationPlugin = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
12
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
13
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
14
+ var _view = require("@codemirror/view");
15
+ function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
16
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
17
+ var PMWidget = /*#__PURE__*/function (_WidgetType) {
18
+ function PMWidget(toDOMElement) {
19
+ var _this;
20
+ (0, _classCallCheck2.default)(this, PMWidget);
21
+ _this = _callSuper(this, PMWidget);
22
+ _this.toDOMElement = toDOMElement;
23
+ return _this;
24
+ }
25
+ (0, _inherits2.default)(PMWidget, _WidgetType);
26
+ return (0, _createClass2.default)(PMWidget, [{
27
+ key: "toDOM",
28
+ value: function toDOM() {
29
+ return this.toDOMElement;
30
+ }
31
+ }, {
32
+ key: "ignoreEvent",
33
+ value: function ignoreEvent() {
34
+ return false;
35
+ }
36
+ }]);
37
+ }(_view.WidgetType); // This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
38
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
39
+ // This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
40
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
41
+ // This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
42
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
43
+ function isExtendedDecoration(decoration) {
44
+ return decoration.inline !== undefined && decoration.widget !== undefined && decoration.type !== undefined;
45
+ }
46
+ var getHTMLElement = function getHTMLElement(toDOM, view, getPos) {
47
+ if (toDOM instanceof Function) {
48
+ var element = toDOM(view, getPos);
49
+ return element instanceof HTMLElement ? element : undefined;
50
+ } else if (toDOM instanceof HTMLElement) {
51
+ return toDOM;
52
+ }
53
+ };
54
+ var mapPMDecorationToCMDecoration = function mapPMDecorationToCMDecoration(decoration, view, getPos) {
55
+ if (!isExtendedDecoration(decoration)) {
56
+ return undefined;
57
+ }
58
+ if (decoration.inline) {
59
+ var markDecoration = _view.Decoration.mark({
60
+ attributes: decoration.type.attrs
61
+ });
62
+ return markDecoration.range(decoration.from, decoration.to);
63
+ } else if (decoration.widget) {
64
+ var _decoration$type;
65
+ var toDOM = getHTMLElement(decoration === null || decoration === void 0 || (_decoration$type = decoration.type) === null || _decoration$type === void 0 ? void 0 : _decoration$type.toDOM, view, getPos);
66
+ if (!toDOM) {
67
+ return undefined;
68
+ }
69
+ var widgetDecoration = _view.Decoration.widget({
70
+ widget: new PMWidget(toDOM),
71
+ side: decoration.type.side
72
+ });
73
+ return widgetDecoration.range(decoration.from, decoration.to);
74
+ }
75
+ };
76
+ function isDefined(value) {
77
+ return value !== undefined;
78
+ }
79
+
80
+ /**
81
+ * Creates CodeMirror versions of the decorations provided by ProseMirror.
82
+ *
83
+ * Inline ProseMirror decorations -> Mark CodeMirror decorations
84
+ * Widget ProseMirror decorations -> Widget CodeMirror decorations
85
+ *
86
+ * This way any decorations applied in ProseMirror land should automatically be supported
87
+ * by the CodeMirror editor
88
+ *
89
+ * @param updateDecorationsEffect Facet for the prosemirror decorations
90
+ * @returns CodeMirror extension
91
+ */
92
+ var prosemirrorDecorationPlugin = exports.prosemirrorDecorationPlugin = function prosemirrorDecorationPlugin(updateDecorationsEffect, editorView, getPos) {
93
+ return _view.ViewPlugin.fromClass( /*#__PURE__*/function () {
94
+ function _class(view) {
95
+ (0, _classCallCheck2.default)(this, _class);
96
+ this.decorations = this.updateDecorations(view);
97
+ }
98
+ return (0, _createClass2.default)(_class, [{
99
+ key: "updateDecorations",
100
+ value: function updateDecorations(view) {
101
+ var _view$viewport = view.viewport,
102
+ from = _view$viewport.from,
103
+ to = _view$viewport.to;
104
+ var innnerDecorations = view.state.facet(updateDecorationsEffect);
105
+ var allDecorations = [];
106
+ innnerDecorations === null || innnerDecorations === void 0 || innnerDecorations.map(function (source) {
107
+ // Temporary: this only exists on prosemirror-view@1.34.0. Since post-office is lower it causes an error.
108
+ // Once we do our prosemirror bump (very soon) we should remove this.
109
+ // https://product-fabric.atlassian.net/browse/ED-26398
110
+ // @ts-ignore
111
+ source === null || source === void 0 || source.forEachSet(function (set) {
112
+ var decorations = set.find(from, to)
113
+ // Do not render the code block line decorations
114
+ // Temporary: this only exists on prosemirror-view@1.34.0. Since post-office is lower it causes an error.
115
+ // Once we do our prosemirror bump (very soon) we should remove this.
116
+ // https://product-fabric.atlassian.net/browse/ED-26398
117
+ // @ts-ignore
118
+ .filter(function (dec) {
119
+ return dec.spec.type !== 'decorationWidgetType';
120
+ });
121
+ allDecorations.push.apply(allDecorations, (0, _toConsumableArray2.default)(decorations));
122
+ });
123
+ });
124
+ var cmDecorations = allDecorations.sort(function (a, b) {
125
+ return a.from < b.from ? -1 : 1;
126
+ }).map(function (decoration) {
127
+ return mapPMDecorationToCMDecoration(decoration, editorView, getPos);
128
+ }).filter(isDefined);
129
+ return _view.Decoration.set(cmDecorations);
130
+ }
131
+ }, {
132
+ key: "update",
133
+ value: function update(_update) {
134
+ this.decorations = this.updateDecorations(_update.view);
135
+ }
136
+ }]);
137
+ }(), {
138
+ decorations: function decorations(v) {
139
+ return v.decorations;
140
+ }
141
+ });
142
+ };
@@ -1,7 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { closeBrackets } from '@codemirror/autocomplete';
3
- import { syntaxHighlighting } from '@codemirror/language';
4
- import { Compartment, EditorSelection } from '@codemirror/state';
3
+ import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
4
+ import { Compartment, EditorSelection, Facet } from '@codemirror/state';
5
5
  import { EditorView as CodeMirror, lineNumbers, gutters } from '@codemirror/view';
6
6
  import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
7
7
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
@@ -9,18 +9,20 @@ import { highlightStyle } from '../ui/syntaxHighlightingTheme';
9
9
  import { cmTheme } from '../ui/theme';
10
10
  import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
11
11
  import { updateCMSelection } from './codemirrorSync/updateCMSelection';
12
- import { bidiCharWarningExtension } from './extensions/bidiCharWarning';
13
12
  import { keymapExtension } from './extensions/keymap';
13
+ import { manageSelectionMarker } from './extensions/manageSelectionMarker';
14
+ import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
14
15
  import { LanguageLoader } from './languages/loader';
15
16
  // Based on: https://prosemirror.net/examples/codemirror/
16
17
  class CodeBlockAdvancedNodeView {
17
- // eslint-disable-next-line @typescript-eslint/max-params
18
18
  constructor(node, view, getPos, config) {
19
- var _config$api, _config$api$selection, _config$api2, _config$api2$editorDi;
19
+ var _config$api, _config$api$selection, _config$api2, _config$api2$editorDi, _config$api3;
20
20
  _defineProperty(this, "lineWrappingCompartment", new Compartment());
21
21
  _defineProperty(this, "languageCompartment", new Compartment());
22
22
  _defineProperty(this, "readOnlyCompartment", new Compartment());
23
+ _defineProperty(this, "pmDecorationsCompartment", new Compartment());
23
24
  _defineProperty(this, "maybeTryingToReachNodeSelection", false);
25
+ _defineProperty(this, "pmFacet", Facet.define());
24
26
  _defineProperty(this, "wordWrappingEnabled", false);
25
27
  this.node = node;
26
28
  this.view = view;
@@ -40,20 +42,21 @@ class CodeBlockAdvancedNodeView {
40
42
  });
41
43
  this.cm = new CodeMirror({
42
44
  doc: this.node.textContent,
43
- extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), keymapExtension({
45
+ extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), keymapExtension({
44
46
  view,
45
47
  getPos,
46
48
  getNode,
47
49
  selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
48
- onMaybeNodeSelection
49
- }), cmTheme, syntaxHighlighting(highlightStyle), lineNumbers(),
50
+ onMaybeNodeSelection,
51
+ customFindReplace: Boolean((_config$api3 = config.api) === null || _config$api3 === void 0 ? void 0 : _config$api3.findReplace)
52
+ }), cmTheme, syntaxHighlighting(highlightStyle), bracketMatching(), lineNumbers(),
50
53
  // Explicitly disable "sticky" positioning on line numbers to match
51
54
  // Renderer behaviour
52
55
  gutters({
53
56
  fixed: false
54
57
  }), CodeMirror.updateListener.of(update => this.forwardUpdate(update)), this.readOnlyCompartment.of(CodeMirror.editable.of(this.view.editable)), closeBrackets(), CodeMirror.editorAttributes.of({
55
58
  class: 'code-block'
56
- }), bidiCharWarningExtension]
59
+ }), manageSelectionMarker(config.api), prosemirrorDecorationPlugin(this.pmFacet, view, getPos)]
57
60
  });
58
61
 
59
62
  // The editor's outer node is our DOM representation
@@ -123,7 +126,7 @@ class CodeBlockAdvancedNodeView {
123
126
  this.wordWrappingEnabled = !this.wordWrappingEnabled;
124
127
  }
125
128
  }
126
- update(node) {
129
+ update(node, _, innerDecorations) {
127
130
  this.maybeTryingToReachNodeSelection = false;
128
131
  if (node.type !== this.node.type) {
129
132
  return false;
@@ -141,8 +144,23 @@ class CodeBlockAdvancedNodeView {
141
144
  this.cm.dispatch(tr);
142
145
  this.updating = false;
143
146
  });
147
+ this.updateProseMirrorDecorations(innerDecorations);
144
148
  return true;
145
149
  }
150
+
151
+ /**
152
+ * Updates a facet which stores information on the prosemirror decorations
153
+ *
154
+ * This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
155
+ */
156
+ updateProseMirrorDecorations(decorationSource) {
157
+ this.updating = true;
158
+ const computedFacet = this.pmFacet.compute([], () => decorationSource);
159
+ this.cm.dispatch({
160
+ effects: this.pmDecorationsCompartment.reconfigure(computedFacet)
161
+ });
162
+ this.updating = false;
163
+ }
146
164
  stopEvent(e) {
147
165
  var _this$getPos5;
148
166
  if (e instanceof MouseEvent && e.type === 'mousedown') {
@@ -48,7 +48,8 @@ const toDOM = (node, formattedAriaLabel) => {
48
48
  style: convertToInlineCss({
49
49
  textAlign: 'right',
50
50
  color: "var(--ds-text-subtlest, #626F86)",
51
- fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)"
51
+ fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
52
+ whiteSpace: 'pre-wrap'
52
53
  }),
53
54
  'data-label': content
54
55
  }]], ['div', {
@@ -20,7 +20,6 @@ export const syncCMWithPM = ({
20
20
  const pmSel = view.state.selection;
21
21
  if (update.docChanged || pmSel.from !== selFrom || pmSel.to !== selTo) {
22
22
  const tr = view.state.tr;
23
- // eslint-disable-next-line @typescript-eslint/max-params
24
23
  update.changes.iterChanges((fromA, toA, fromB, toB, text) => {
25
24
  if (text.length) {
26
25
  tr.replaceWith(offset + fromA, offset + toA, view.state.schema.text(text.toString()));
@@ -1,5 +1,6 @@
1
1
  import { defaultKeymap, indentWithTab } from '@codemirror/commands';
2
2
  import { keymap as cmKeymap } from '@codemirror/view';
3
+ import { browser } from '@atlaskit/editor-common/browser';
3
4
  import { exitCode } from '@atlaskit/editor-prosemirror/commands';
4
5
  import { undo, redo } from '@atlaskit/editor-prosemirror/history';
5
6
  import { backspaceKeymap } from './backspace';
@@ -9,14 +10,16 @@ export const keymapExtension = ({
9
10
  getNode,
10
11
  getPos,
11
12
  selectCodeBlockNode,
12
- onMaybeNodeSelection
13
+ onMaybeNodeSelection,
14
+ customFindReplace
13
15
  }) => {
14
16
  return cmKeymap.of(codeBlockKeymap({
15
17
  view,
16
18
  getNode,
17
19
  getPos,
18
20
  selectCodeBlockNode,
19
- onMaybeNodeSelection
21
+ onMaybeNodeSelection,
22
+ customFindReplace
20
23
  }));
21
24
  };
22
25
  const codeBlockKeymap = ({
@@ -24,7 +27,8 @@ const codeBlockKeymap = ({
24
27
  getNode,
25
28
  getPos,
26
29
  selectCodeBlockNode,
27
- onMaybeNodeSelection
30
+ onMaybeNodeSelection,
31
+ customFindReplace
28
32
  }) => {
29
33
  return [{
30
34
  key: 'ArrowUp',
@@ -74,6 +78,22 @@ const codeBlockKeymap = ({
74
78
  selectCodeBlockNode,
75
79
  onMaybeNodeSelection
76
80
  })
81
+ }, {
82
+ key: 'Ctrl-f',
83
+ mac: 'Cmd-f',
84
+ run: () => {
85
+ // Pass synthetic event to prosemirror
86
+ if (customFindReplace) {
87
+ view.dispatchEvent(new KeyboardEvent('keydown', {
88
+ key: 'f',
89
+ code: 'KeyF',
90
+ metaKey: browser.mac ? true : false,
91
+ ctrlKey: browser.mac ? false : true
92
+ }));
93
+ return true;
94
+ }
95
+ return false;
96
+ }
77
97
  }, {
78
98
  key: 'Ctrl-Enter',
79
99
  run: () => {
@@ -0,0 +1,22 @@
1
+ import { EditorView as CodeMirror } from '@codemirror/view';
2
+ /**
3
+ * Hides selection marker decoration when focused on codemirror editor and re-enables on blur
4
+ *
5
+ * @param api
6
+ * @returns CodeMirror Extension
7
+ */
8
+ export const manageSelectionMarker = api => {
9
+ let decoHide;
10
+ return CodeMirror.focusChangeEffect.of((_state, focusing) => {
11
+ if (focusing) {
12
+ var _api$selectionMarker;
13
+ api === null || api === void 0 ? void 0 : (_api$selectionMarker = api.selectionMarker) === null || _api$selectionMarker === void 0 ? void 0 : _api$selectionMarker.actions.queueHideDecoration(hideDecoration => {
14
+ decoHide = hideDecoration;
15
+ });
16
+ } else {
17
+ var _decoHide;
18
+ (_decoHide = decoHide) === null || _decoHide === void 0 ? void 0 : _decoHide();
19
+ }
20
+ return null;
21
+ });
22
+ };