@atlaskit/editor-plugin-code-block-advanced 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +21 -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 +29 -26
  6. package/dist/cjs/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
  7. package/dist/cjs/nodeviews/extensions/keymap/index.js +23 -3
  8. package/dist/cjs/nodeviews/extensions/manageSelectionMarker.js +28 -0
  9. package/dist/cjs/nodeviews/extensions/prosemirrorDecorations.js +134 -0
  10. package/dist/cjs/ui/theme.js +20 -2
  11. package/dist/es2019/nodeviews/codeBlockAdvanced.js +27 -27
  12. package/dist/es2019/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
  13. package/dist/es2019/nodeviews/extensions/keymap/index.js +23 -3
  14. package/dist/es2019/nodeviews/extensions/manageSelectionMarker.js +22 -0
  15. package/dist/es2019/nodeviews/extensions/prosemirrorDecorations.js +99 -0
  16. package/dist/es2019/ui/theme.js +62 -2
  17. package/dist/esm/nodeviews/codeBlockAdvanced.js +30 -27
  18. package/dist/esm/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
  19. package/dist/esm/nodeviews/extensions/keymap/index.js +23 -3
  20. package/dist/esm/nodeviews/extensions/manageSelectionMarker.js +22 -0
  21. package/dist/esm/nodeviews/extensions/prosemirrorDecorations.js +127 -0
  22. package/dist/esm/ui/theme.js +20 -2
  23. package/dist/types/codeBlockAdvancedPluginType.d.ts +9 -1
  24. package/dist/types/nodeviews/codeBlockAdvanced.d.ts +10 -5
  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 -5
  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 +10 -8
  34. package/src/codeBlockAdvancedPluginType.ts +9 -1
  35. package/src/nodeviews/codeBlockAdvanced.ts +31 -30
  36. package/src/nodeviews/codemirrorSync/syncCMWithPM.ts +0 -1
  37. package/src/nodeviews/extensions/keymap/index.ts +31 -1
  38. package/src/nodeviews/extensions/manageSelectionMarker.ts +28 -0
  39. package/src/nodeviews/extensions/prosemirrorDecorations.ts +148 -0
  40. package/src/ui/theme.ts +64 -0
  41. package/tsconfig.app.json +6 -0
  42. package/dist/cjs/nodeviews/extensions/bidiCharWarning.js +0 -83
  43. package/dist/cjs/nodeviews/extensions/copyButtonDecorations.js +0 -22
  44. package/dist/es2019/nodeviews/extensions/bidiCharWarning.js +0 -53
  45. package/dist/es2019/nodeviews/extensions/copyButtonDecorations.js +0 -16
  46. package/dist/esm/nodeviews/extensions/bidiCharWarning.js +0 -77
  47. package/dist/esm/nodeviews/extensions/copyButtonDecorations.js +0 -16
  48. package/dist/types/nodeviews/extensions/bidiCharWarning.d.ts +0 -8
  49. package/dist/types/nodeviews/extensions/copyButtonDecorations.d.ts +0 -1
  50. package/dist/types-ts4.5/nodeviews/extensions/bidiCharWarning.d.ts +0 -8
  51. package/dist/types-ts4.5/nodeviews/extensions/copyButtonDecorations.d.ts +0 -1
  52. package/src/nodeviews/extensions/bidiCharWarning.ts +0 -72
  53. package/src/nodeviews/extensions/copyButtonDecorations.ts +0 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-plugin-code-block-advanced
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#105322](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/105322)
8
+ [`8876083532adc`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/8876083532adc) -
9
+ Bumped editor-prosemirror version to 7.0.0
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 1.0.3
16
+
17
+ ### Patch Changes
18
+
19
+ - [#107185](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/107185)
20
+ [`f0dd5f5bd4d4e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f0dd5f5bd4d4e) -
21
+ [ux] Sync all prosemirror decorations with codemirror decorations.
22
+ - Updated dependencies
23
+
3
24
  ## 1.0.2
4
25
 
5
26
  ### 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,13 +19,12 @@ 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
- var _copyButtonDecorations = require("./extensions/copyButtonDecorations");
24
22
  var _keymap = require("./extensions/keymap");
23
+ var _manageSelectionMarker = require("./extensions/manageSelectionMarker");
24
+ var _prosemirrorDecorations = require("./extensions/prosemirrorDecorations");
25
25
  var _loader = require("./languages/loader");
26
26
  // Based on: https://prosemirror.net/examples/codemirror/
27
27
  var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
28
- // eslint-disable-next-line @typescript-eslint/max-params
29
28
  function CodeBlockAdvancedNodeView(node, view, getPos, config) {
30
29
  var _config$api,
31
30
  _this = this,
@@ -35,8 +34,9 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
35
34
  (0, _defineProperty2.default)(this, "lineWrappingCompartment", new _state.Compartment());
36
35
  (0, _defineProperty2.default)(this, "languageCompartment", new _state.Compartment());
37
36
  (0, _defineProperty2.default)(this, "readOnlyCompartment", new _state.Compartment());
38
- (0, _defineProperty2.default)(this, "copyDecoCompartment", new _state.Compartment());
37
+ (0, _defineProperty2.default)(this, "pmDecorationsCompartment", new _state.Compartment());
39
38
  (0, _defineProperty2.default)(this, "maybeTryingToReachNodeSelection", false);
39
+ (0, _defineProperty2.default)(this, "pmFacet", _state.Facet.define());
40
40
  (0, _defineProperty2.default)(this, "wordWrappingEnabled", false);
41
41
  this.node = node;
42
42
  this.view = view;
@@ -51,13 +51,6 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
51
51
  this.cleanupDisabledState = (_config$api2 = config.api) === null || _config$api2 === void 0 || (_config$api2 = _config$api2.editorDisabled) === null || _config$api2 === void 0 ? void 0 : _config$api2.sharedState.onChange(function () {
52
52
  _this.updateReadonlyState();
53
53
  });
54
- this.cleanupCopyButtonDecoration = (_config$api3 = config.api) === null || _config$api3 === void 0 || (_config$api3 = _config$api3.codeBlock) === null || _config$api3 === void 0 ? void 0 : _config$api3.sharedState.onChange(function (_ref) {
55
- var nextSharedState = _ref.nextSharedState,
56
- prevSharedState = _ref.prevSharedState;
57
- if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode) !== (prevSharedState === null || prevSharedState === void 0 ? void 0 : prevSharedState.copyButtonHoverNode)) {
58
- _this.addCopyButtonDecoration(nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode);
59
- }
60
- });
61
54
  this.languageLoader = new _loader.LanguageLoader(function (lang) {
62
55
  _this.updating = true;
63
56
  _this.cm.dispatch({
@@ -67,12 +60,13 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
67
60
  });
68
61
  this.cm = new _view.EditorView({
69
62
  doc: this.node.textContent,
70
- extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.copyDecoCompartment.of([]), (0, _keymap.keymapExtension)({
63
+ extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), (0, _keymap.keymapExtension)({
71
64
  view: view,
72
65
  getPos: getPos,
73
66
  getNode: getNode,
74
67
  selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
75
- onMaybeNodeSelection: onMaybeNodeSelection
68
+ onMaybeNodeSelection: onMaybeNodeSelection,
69
+ customFindReplace: Boolean((_config$api3 = config.api) === null || _config$api3 === void 0 ? void 0 : _config$api3.findReplace)
76
70
  }), _theme.cmTheme, (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0, _language.bracketMatching)(), (0, _view.lineNumbers)(),
77
71
  // Explicitly disable "sticky" positioning on line numbers to match
78
72
  // Renderer behaviour
@@ -82,7 +76,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
82
76
  return _this.forwardUpdate(update);
83
77
  }), this.readOnlyCompartment.of(_view.EditorView.editable.of(this.view.editable)), (0, _autocomplete.closeBrackets)(), _view.EditorView.editorAttributes.of({
84
78
  class: 'code-block'
85
- }), _bidiCharWarning.bidiCharWarningExtension])
79
+ }), (0, _manageSelectionMarker.manageSelectionMarker)(config.api), (0, _prosemirrorDecorations.prosemirrorDecorationPlugin)(this.pmFacet, view, getPos)])
86
80
  });
87
81
 
88
82
  // The editor's outer node is our DOM representation
@@ -96,9 +90,8 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
96
90
  return (0, _createClass2.default)(CodeBlockAdvancedNodeView, [{
97
91
  key: "destroy",
98
92
  value: function destroy() {
99
- var _this$cleanupDisabled, _this$cleanupCopyButt;
93
+ var _this$cleanupDisabled;
100
94
  (_this$cleanupDisabled = this.cleanupDisabledState) === null || _this$cleanupDisabled === void 0 || _this$cleanupDisabled.call(this);
101
- (_this$cleanupCopyButt = this.cleanupCopyButtonDecoration) === null || _this$cleanupCopyButt === void 0 || _this$cleanupCopyButt.call(this);
102
95
  }
103
96
  }, {
104
97
  key: "forwardUpdate",
@@ -155,15 +148,6 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
155
148
  this.view.dispatch(tr);
156
149
  }
157
150
  }
158
- }, {
159
- key: "addCopyButtonDecoration",
160
- value: function addCopyButtonDecoration(node) {
161
- this.updating = true;
162
- this.cm.dispatch({
163
- effects: [this.copyDecoCompartment.reconfigure(node && node === this.node ? _copyButtonDecorations.copyButtonDecorations : [])]
164
- });
165
- this.updating = false;
166
- }
167
151
  }, {
168
152
  key: "updateWordWrap",
169
153
  value: function updateWordWrap(node) {
@@ -178,7 +162,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
178
162
  }
179
163
  }, {
180
164
  key: "update",
181
- value: function update(node) {
165
+ value: function update(node, _, innerDecorations) {
182
166
  var _this2 = this;
183
167
  this.maybeTryingToReachNodeSelection = false;
184
168
  if (node.type !== this.node.type) {
@@ -197,8 +181,27 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
197
181
  _this2.cm.dispatch(tr);
198
182
  _this2.updating = false;
199
183
  });
184
+ this.updateProseMirrorDecorations(innerDecorations);
200
185
  return true;
201
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
+ }
202
205
  }, {
203
206
  key: "stopEvent",
204
207
  value: function stopEvent(e) {
@@ -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,134 @@
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
+ source === null || source === void 0 || source.forEachSet(function (set) {
108
+ var decorations = set.find(from, to)
109
+ // Do not render the code block line decorations
110
+ .filter(function (dec) {
111
+ return dec.spec.type !== 'decorationWidgetType';
112
+ });
113
+ allDecorations.push.apply(allDecorations, (0, _toConsumableArray2.default)(decorations));
114
+ });
115
+ });
116
+ var cmDecorations = allDecorations.sort(function (a, b) {
117
+ return a.from < b.from ? -1 : 1;
118
+ }).map(function (decoration) {
119
+ return mapPMDecorationToCMDecoration(decoration, editorView, getPos);
120
+ }).filter(isDefined);
121
+ return _view.Decoration.set(cmDecorations);
122
+ }
123
+ }, {
124
+ key: "update",
125
+ value: function update(_update) {
126
+ this.decorations = this.updateDecorations(_update.view);
127
+ }
128
+ }]);
129
+ }(), {
130
+ decorations: function decorations(v) {
131
+ return v.decorations;
132
+ }
133
+ });
134
+ };
@@ -11,6 +11,7 @@ var cmTheme = exports.cmTheme = _view.EditorView.theme({
11
11
  padding: '0',
12
12
  marginTop: "var(--ds-space-100, 8px)",
13
13
  marginBottom: "var(--ds-space-100, 8px)",
14
+ // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
14
15
  fontSize: '0.875rem',
15
16
  // Custom syntax styling to match existing styling
16
17
  // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
@@ -37,7 +38,11 @@ var cmTheme = exports.cmTheme = _view.EditorView.theme({
37
38
  // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
38
39
  lineHeight: 'unset',
39
40
  fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
40
- borderRadius: "var(--ds-border-radius, 4px)"
41
+ borderRadius: "var(--ds-border-radius, 4px)",
42
+ backgroundImage: overflowShadow({
43
+ leftCoverWidth: "var(--ds-space-300, 24px)"
44
+ }),
45
+ backgroundAttachment: 'local, local, local, local, scroll, scroll, scroll, scroll'
41
46
  },
42
47
  '&.cm-focused .cm-cursor': {
43
48
  borderLeftColor: "var(--ds-text, #172B4D)"
@@ -53,4 +58,17 @@ var cmTheme = exports.cmTheme = _view.EditorView.theme({
53
58
  paddingRight: "var(--ds-space-0, 0px)",
54
59
  minWidth: 'unset'
55
60
  }
56
- });
61
+ });
62
+
63
+ /**
64
+ * Copied directly from `packages/editor/editor-shared-styles/src/overflow-shadow/overflow-shadow.ts`
65
+ * `CodeMirror` does not support emotion styling so this has been re-created.
66
+ */
67
+ function overflowShadow(_ref) {
68
+ var leftCoverWidth = _ref.leftCoverWidth,
69
+ rightCoverWidth = _ref.rightCoverWidth;
70
+ var width = "var(--ds-space-100, 8px)";
71
+ var leftCoverWidthResolved = leftCoverWidth || width;
72
+ var rightCoverWidthResolved = rightCoverWidth || width;
73
+ return "\n linear-gradient(\n to right,\n ".concat("var(--ds-background-neutral, #091E420F)", " ", leftCoverWidthResolved, ",\n transparent ").concat(leftCoverWidthResolved, "\n ),\n linear-gradient(\n to right,\n ", "var(--ds-surface-raised, #FFFFFF)", " ").concat(leftCoverWidthResolved, ",\n transparent ").concat(leftCoverWidthResolved, "\n ),\n linear-gradient(\n to left,\n ", "var(--ds-background-neutral, #091E420F)", " ").concat(rightCoverWidthResolved, ",\n transparent ").concat(rightCoverWidthResolved, "\n ),\n linear-gradient(\n to left,\n ", "var(--ds-surface-raised, #FFFFFF)", " ").concat(rightCoverWidthResolved, ",\n transparent ").concat(rightCoverWidthResolved, "\n ),\n linear-gradient(\n to left,\n ", "var(--ds-shadow-overflow-spread, #091e4229)", " 0,\n ", "var(--ds-UNSAFE-transparent, transparent)", " ").concat(width, "\n ),\n linear-gradient(\n to left,\n ", "var(--ds-shadow-overflow-perimeter, #091e421f)", " 0,\n ", "var(--ds-UNSAFE-transparent, transparent)", " ").concat(width, "\n ),\n linear-gradient(\n to right,\n ", "var(--ds-shadow-overflow-spread, #091e4229)", " 0,\n ", "var(--ds-UNSAFE-transparent, transparent)", " ").concat(width, "\n ),\n linear-gradient(\n to right,\n ", "var(--ds-shadow-overflow-perimeter, #091e421f)", " 0,\n ", "var(--ds-UNSAFE-transparent, transparent)", " ").concat(width, "\n )\n");
74
+ }
@@ -1,7 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { closeBrackets } from '@codemirror/autocomplete';
3
3
  import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
4
- import { Compartment, EditorSelection } from '@codemirror/state';
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,20 +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
- import { copyButtonDecorations } from './extensions/copyButtonDecorations';
14
12
  import { keymapExtension } from './extensions/keymap';
13
+ import { manageSelectionMarker } from './extensions/manageSelectionMarker';
14
+ import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
15
15
  import { LanguageLoader } from './languages/loader';
16
16
  // Based on: https://prosemirror.net/examples/codemirror/
17
17
  class CodeBlockAdvancedNodeView {
18
- // eslint-disable-next-line @typescript-eslint/max-params
19
18
  constructor(node, view, getPos, config) {
20
- var _config$api, _config$api$selection, _config$api2, _config$api2$editorDi, _config$api3, _config$api3$codeBloc;
19
+ var _config$api, _config$api$selection, _config$api2, _config$api2$editorDi, _config$api3;
21
20
  _defineProperty(this, "lineWrappingCompartment", new Compartment());
22
21
  _defineProperty(this, "languageCompartment", new Compartment());
23
22
  _defineProperty(this, "readOnlyCompartment", new Compartment());
24
- _defineProperty(this, "copyDecoCompartment", new Compartment());
23
+ _defineProperty(this, "pmDecorationsCompartment", new Compartment());
25
24
  _defineProperty(this, "maybeTryingToReachNodeSelection", false);
25
+ _defineProperty(this, "pmFacet", Facet.define());
26
26
  _defineProperty(this, "wordWrappingEnabled", false);
27
27
  this.node = node;
28
28
  this.view = view;
@@ -33,14 +33,6 @@ class CodeBlockAdvancedNodeView {
33
33
  this.cleanupDisabledState = (_config$api2 = config.api) === null || _config$api2 === void 0 ? void 0 : (_config$api2$editorDi = _config$api2.editorDisabled) === null || _config$api2$editorDi === void 0 ? void 0 : _config$api2$editorDi.sharedState.onChange(() => {
34
34
  this.updateReadonlyState();
35
35
  });
36
- this.cleanupCopyButtonDecoration = (_config$api3 = config.api) === null || _config$api3 === void 0 ? void 0 : (_config$api3$codeBloc = _config$api3.codeBlock) === null || _config$api3$codeBloc === void 0 ? void 0 : _config$api3$codeBloc.sharedState.onChange(({
37
- nextSharedState,
38
- prevSharedState
39
- }) => {
40
- if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode) !== (prevSharedState === null || prevSharedState === void 0 ? void 0 : prevSharedState.copyButtonHoverNode)) {
41
- this.addCopyButtonDecoration(nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode);
42
- }
43
- });
44
36
  this.languageLoader = new LanguageLoader(lang => {
45
37
  this.updating = true;
46
38
  this.cm.dispatch({
@@ -50,12 +42,13 @@ class CodeBlockAdvancedNodeView {
50
42
  });
51
43
  this.cm = new CodeMirror({
52
44
  doc: this.node.textContent,
53
- extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.copyDecoCompartment.of([]), keymapExtension({
45
+ extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.pmDecorationsCompartment.of([]), keymapExtension({
54
46
  view,
55
47
  getPos,
56
48
  getNode,
57
49
  selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
58
- onMaybeNodeSelection
50
+ onMaybeNodeSelection,
51
+ customFindReplace: Boolean((_config$api3 = config.api) === null || _config$api3 === void 0 ? void 0 : _config$api3.findReplace)
59
52
  }), cmTheme, syntaxHighlighting(highlightStyle), bracketMatching(), lineNumbers(),
60
53
  // Explicitly disable "sticky" positioning on line numbers to match
61
54
  // Renderer behaviour
@@ -63,7 +56,7 @@ class CodeBlockAdvancedNodeView {
63
56
  fixed: false
64
57
  }), CodeMirror.updateListener.of(update => this.forwardUpdate(update)), this.readOnlyCompartment.of(CodeMirror.editable.of(this.view.editable)), closeBrackets(), CodeMirror.editorAttributes.of({
65
58
  class: 'code-block'
66
- }), bidiCharWarningExtension]
59
+ }), manageSelectionMarker(config.api), prosemirrorDecorationPlugin(this.pmFacet, view, getPos)]
67
60
  });
68
61
 
69
62
  // The editor's outer node is our DOM representation
@@ -75,9 +68,8 @@ class CodeBlockAdvancedNodeView {
75
68
  this.updateLanguage();
76
69
  }
77
70
  destroy() {
78
- var _this$cleanupDisabled, _this$cleanupCopyButt;
71
+ var _this$cleanupDisabled;
79
72
  (_this$cleanupDisabled = this.cleanupDisabledState) === null || _this$cleanupDisabled === void 0 ? void 0 : _this$cleanupDisabled.call(this);
80
- (_this$cleanupCopyButt = this.cleanupCopyButtonDecoration) === null || _this$cleanupCopyButt === void 0 ? void 0 : _this$cleanupCopyButt.call(this);
81
73
  }
82
74
  forwardUpdate(update) {
83
75
  var _this$getPos, _this$getPos2;
@@ -124,13 +116,6 @@ class CodeBlockAdvancedNodeView {
124
116
  this.view.dispatch(tr);
125
117
  }
126
118
  }
127
- addCopyButtonDecoration(node) {
128
- this.updating = true;
129
- this.cm.dispatch({
130
- effects: [this.copyDecoCompartment.reconfigure(node && node === this.node ? copyButtonDecorations : [])]
131
- });
132
- this.updating = false;
133
- }
134
119
  updateWordWrap(node) {
135
120
  if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
136
121
  this.updating = true;
@@ -141,7 +126,7 @@ class CodeBlockAdvancedNodeView {
141
126
  this.wordWrappingEnabled = !this.wordWrappingEnabled;
142
127
  }
143
128
  }
144
- update(node) {
129
+ update(node, _, innerDecorations) {
145
130
  this.maybeTryingToReachNodeSelection = false;
146
131
  if (node.type !== this.node.type) {
147
132
  return false;
@@ -159,8 +144,23 @@ class CodeBlockAdvancedNodeView {
159
144
  this.cm.dispatch(tr);
160
145
  this.updating = false;
161
146
  });
147
+ this.updateProseMirrorDecorations(innerDecorations);
162
148
  return true;
163
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
+ }
164
164
  stopEvent(e) {
165
165
  var _this$getPos5;
166
166
  if (e instanceof MouseEvent && e.type === 'mousedown') {
@@ -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()));