@atlaskit/editor-plugin-code-block 3.3.0 → 3.3.2

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 (41) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/actions.js +8 -10
  3. package/dist/cjs/index.js +1 -14
  4. package/dist/cjs/nodeviews/code-block.js +4 -4
  5. package/dist/cjs/pm-plugins/actions.js +2 -1
  6. package/dist/cjs/pm-plugins/decorators.js +28 -16
  7. package/dist/cjs/pm-plugins/keymaps.js +1 -7
  8. package/dist/cjs/pm-plugins/main.js +66 -15
  9. package/dist/cjs/toolbar.js +5 -2
  10. package/dist/cjs/ui/class-names.js +6 -3
  11. package/dist/es2019/actions.js +8 -10
  12. package/dist/es2019/index.js +1 -2
  13. package/dist/es2019/nodeviews/code-block.js +4 -4
  14. package/dist/es2019/pm-plugins/actions.js +2 -1
  15. package/dist/es2019/pm-plugins/decorators.js +27 -15
  16. package/dist/es2019/pm-plugins/keymaps.js +1 -7
  17. package/dist/es2019/pm-plugins/main.js +67 -12
  18. package/dist/es2019/toolbar.js +5 -2
  19. package/dist/es2019/ui/class-names.js +6 -3
  20. package/dist/esm/actions.js +8 -10
  21. package/dist/esm/index.js +1 -2
  22. package/dist/esm/nodeviews/code-block.js +4 -4
  23. package/dist/esm/pm-plugins/actions.js +2 -1
  24. package/dist/esm/pm-plugins/decorators.js +27 -15
  25. package/dist/esm/pm-plugins/keymaps.js +1 -7
  26. package/dist/esm/pm-plugins/main.js +65 -14
  27. package/dist/esm/toolbar.js +5 -2
  28. package/dist/esm/ui/class-names.js +6 -3
  29. package/dist/types/index.d.ts +0 -1
  30. package/dist/types/pm-plugins/actions.d.ts +1 -0
  31. package/dist/types/pm-plugins/decorators.d.ts +3 -3
  32. package/dist/types/pm-plugins/main.d.ts +1 -2
  33. package/dist/types/types.d.ts +2 -2
  34. package/dist/types/ui/class-names.d.ts +5 -3
  35. package/dist/types-ts4.5/index.d.ts +0 -1
  36. package/dist/types-ts4.5/pm-plugins/actions.d.ts +1 -0
  37. package/dist/types-ts4.5/pm-plugins/decorators.d.ts +3 -3
  38. package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -2
  39. package/dist/types-ts4.5/types.d.ts +2 -2
  40. package/dist/types-ts4.5/ui/class-names.d.ts +5 -3
  41. package/package.json +4 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/editor-plugin-code-block
2
2
 
3
+ ## 3.3.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#128111](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/128111)
8
+ [`9863ffeb3e73e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/9863ffeb3e73e) -
9
+ remove codeblock preserve newlines ff
10
+ - [#129049](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/129049)
11
+ [`6b1533d389c9d`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/6b1533d389c9d) -
12
+ [ux] ED-24511 - Convert code block line numbers inline decorations to widget decorations. The line
13
+ number gutter on editor code blocks should now reflect the number of lines of code, including when
14
+ the code block has word wrap enabled. Minor for editor-common as new analytics attribute added.
15
+ - Updated dependencies
16
+
17
+ ## 3.3.1
18
+
19
+ ### Patch Changes
20
+
21
+ - [#127940](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/127940)
22
+ [`7f340ec35b8a4`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7f340ec35b8a4) -
23
+ [ux] ED-24320 Hook up decorators for toggled on and toggled off wrapping states in floating
24
+ toolbar
25
+
3
26
  ## 3.3.0
4
27
 
5
28
  ### Minor Changes
@@ -219,24 +219,22 @@ var toggleWordWrapStateForCodeBlockNode = exports.toggleWordWrapStateForCodeBloc
219
219
  }
220
220
  var updatedToggleState = !(0, _codeBlock.isCodeBlockWordWrapEnabled)(codeBlockNode);
221
221
  _codeBlock.codeBlockWrappedStates.set(codeBlockNode, updatedToggleState);
222
-
223
- // TODO: Remove in ED-24222. Leaving here for demo purposes.
224
- // eslint-disable-next-line no-console
225
- console.log("Code Block Word Wrap: Updating codeBlockWrappedStates with: ".concat(updatedToggleState));
222
+ tr.setMeta(_pluginKey.pluginKey, {
223
+ type: _actions.ACTIONS.SET_IS_WRAPPED,
224
+ data: updatedToggleState
225
+ });
226
226
  if (dispatch) {
227
- var payload = {
227
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
228
228
  action: _analytics.ACTION.TOGGLE_CODE_BLOCK_WRAP,
229
229
  actionSubject: _analytics.ACTION_SUBJECT.CODE_BLOCK,
230
230
  attributes: {
231
231
  platform: _analytics.PLATFORMS.WEB,
232
232
  mode: _analytics.MODE.EDITOR,
233
- wordWrapEnabled: updatedToggleState
233
+ wordWrapEnabled: updatedToggleState,
234
+ codeBlockNodeSize: codeBlockNode.nodeSize
234
235
  },
235
236
  eventType: _analytics.EVENT_TYPE.TRACK
236
- };
237
-
238
- // TODO: ED-24320 should convert this to attachAnalyticsEvent if it is dispatching a transaction here.
239
- editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.fireAnalyticsEvent(payload);
237
+ })(tr);
240
238
  dispatch(tr);
241
239
  }
242
240
  return true;
package/dist/cjs/index.js CHANGED
@@ -10,17 +10,4 @@ Object.defineProperty(exports, "codeBlockPlugin", {
10
10
  return _plugin.default;
11
11
  }
12
12
  });
13
- Object.defineProperty(exports, "createDecorationSetFromTextPositions", {
14
- enumerable: true,
15
- get: function get() {
16
- return _decorators.createDecorationSetFromTextPositions;
17
- }
18
- });
19
- Object.defineProperty(exports, "generateTextPositionsFromNode", {
20
- enumerable: true,
21
- get: function get() {
22
- return _decorators.generateTextPositionsFromNode;
23
- }
24
- });
25
- var _plugin = _interopRequireDefault(require("./plugin"));
26
- var _decorators = require("./pm-plugins/decorators");
13
+ var _plugin = _interopRequireDefault(require("./plugin"));
@@ -24,12 +24,12 @@ var toDOM = function toDOM(node, contentEditable) {
24
24
  class: _classNames.codeBlockClassNames.start,
25
25
  contenteditable: 'false'
26
26
  }], ['div', {
27
- class: _classNames.codeBlockClassNames.contentWrapper
27
+ class: "".concat(_classNames.codeBlockClassNames.contentWrapper, " ").concat((0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') && _classNames.codeBlockClassNames.contentWrapperFg)
28
28
  }, ['div', {
29
- class: (0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? _classNames.codeBlockClassNames.gutterFgWrap : _classNames.codeBlockClassNames.gutter,
29
+ class: (0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? _classNames.codeBlockClassNames.gutterFg : _classNames.codeBlockClassNames.gutter,
30
30
  contenteditable: 'false'
31
31
  }], ['div', {
32
- class: _classNames.codeBlockClassNames.content
32
+ class: (0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? "".concat(_classNames.codeBlockClassNames.contentFg) : _classNames.codeBlockClassNames.content
33
33
  }, ['code', {
34
34
  'data-language': node.attrs.language || '',
35
35
  spellcheck: 'false',
@@ -69,7 +69,7 @@ var CodeBlockView = exports.CodeBlockView = /*#__PURE__*/function () {
69
69
  this.node = _node;
70
70
  this.dom = dom;
71
71
  this.contentDOM = contentDOM;
72
- this.lineNumberGutter = this.dom.querySelector(".".concat((0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? _classNames.codeBlockClassNames.gutterFgWrap : _classNames.codeBlockClassNames.gutter));
72
+ this.lineNumberGutter = this.dom.querySelector(".".concat((0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? _classNames.codeBlockClassNames.gutterFg : _classNames.codeBlockClassNames.gutter));
73
73
  this.api = api;
74
74
  if (!(0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping')) {
75
75
  this.ensureLineNumbers();
@@ -6,5 +6,6 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.ACTIONS = void 0;
7
7
  var ACTIONS = exports.ACTIONS = {
8
8
  SET_COPIED_TO_CLIPBOARD: 'SET_COPIED_TO_CLIPBOARD',
9
- SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS: 'SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS'
9
+ SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS: 'SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS',
10
+ SET_IS_WRAPPED: 'SET_IS_WRAPPED'
10
11
  };
@@ -4,46 +4,58 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.generateTextPositionsFromNode = exports.createLineNumbersDecorations = exports.createDecorationSetFromTextPositions = void 0;
7
+ exports.generateLineAttributesFromNode = exports.createLineNumbersDecorations = exports.createDecorationSetFromLineAttributes = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _view = require("@atlaskit/editor-prosemirror/view");
10
10
  var _classNames = require("../ui/class-names");
11
- var generateTextPositionsFromNode = exports.generateTextPositionsFromNode = function generateTextPositionsFromNode(pos, node) {
11
+ var DECORATION_WIDGET_TYPE = 'decorationWidgetType';
12
+ var generateLineAttributesFromNode = exports.generateLineAttributesFromNode = function generateLineAttributesFromNode(pos, node) {
12
13
  // Get content node
13
14
  var contentNode = node.content;
14
15
 
15
16
  // Get node text content
16
- var textPositions = [];
17
+ var lineAttributes = [];
17
18
  contentNode.forEach(function (child) {
18
19
  var nodeTextContent = child.textContent;
19
20
  var nodeStartPos = pos;
20
21
  var lineStartIndex = nodeStartPos;
21
- var newLinePositions = nodeTextContent.split('\n').map(function (line) {
22
+ var newLineAttributes = nodeTextContent.split('\n').map(function (line, index) {
22
23
  var lineLength = line.length;
23
24
  var lineStart = lineStartIndex + 1;
24
- var lineEnd = lineStart + lineLength;
25
+ var lineNumber = index + 1;
25
26
 
26
27
  // Include the newline character and increment to keep tabs on line position
27
28
  lineStartIndex += lineLength + 1;
28
29
  return {
29
30
  lineStart: lineStart,
30
- lineEnd: lineEnd
31
+ lineNumber: lineNumber
31
32
  };
32
33
  });
33
- textPositions = [].concat((0, _toConsumableArray2.default)(textPositions), (0, _toConsumableArray2.default)(newLinePositions));
34
+ lineAttributes = [].concat((0, _toConsumableArray2.default)(lineAttributes), (0, _toConsumableArray2.default)(newLineAttributes));
34
35
  });
35
- return textPositions;
36
+ return lineAttributes;
36
37
  };
37
- var createDecorationSetFromTextPositions = exports.createDecorationSetFromTextPositions = function createDecorationSetFromTextPositions(textPositions) {
38
- var decorations = textPositions.map(function (textPosition) {
39
- var lineStart = textPosition.lineStart,
40
- lineEnd = textPosition.lineEnd;
41
- return _view.Decoration.inline(lineStart, lineEnd, {
42
- class: _classNames.codeBlockClassNames.lineNumberWrapped
38
+ var createDecorationSetFromLineAttributes = exports.createDecorationSetFromLineAttributes = function createDecorationSetFromLineAttributes(lineAttributes) {
39
+ var widgetDecorations = lineAttributes.map(function (lineAttribute) {
40
+ var lineStart = lineAttribute.lineStart,
41
+ lineNumber = lineAttribute.lineNumber;
42
+
43
+ // Passing a function to create the widget rather than directly passing a widget, as per ProseMirror docs.
44
+ var createLineNumberWidget = function createLineNumberWidget() {
45
+ var widget = document.createElement('span');
46
+ widget.textContent = "".concat(lineNumber);
47
+ widget.classList.add(_classNames.codeBlockClassNames.lineNumberWidget);
48
+ return widget;
49
+ };
50
+
51
+ // side -1 is used so the line numbers are the first thing to the left of the lines of code.
52
+ return _view.Decoration.widget(lineStart, createLineNumberWidget, {
53
+ type: DECORATION_WIDGET_TYPE,
54
+ side: -1
43
55
  });
44
56
  });
45
- return decorations;
57
+ return widgetDecorations;
46
58
  };
47
59
  var createLineNumbersDecorations = exports.createLineNumbersDecorations = function createLineNumbersDecorations(pos, node) {
48
- return createDecorationSetFromTextPositions(generateTextPositionsFromNode(pos, node));
60
+ return createDecorationSetFromLineAttributes(generateLineAttributesFromNode(pos, node));
49
61
  };
@@ -9,7 +9,6 @@ var _utils = require("@atlaskit/editor-common/utils");
9
9
  var _keymap = require("@atlaskit/editor-prosemirror/keymap");
10
10
  var _state = require("@atlaskit/editor-prosemirror/state");
11
11
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
12
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
12
  var _utils3 = require("../utils");
14
13
  var deleteCurrentItem = function deleteCurrentItem($from) {
15
14
  return function (tr) {
@@ -58,7 +57,6 @@ function keymapPlugin(schema) {
58
57
  var _state$schema$nodes2 = state.schema.nodes,
59
58
  codeBlock = _state$schema$nodes2.codeBlock,
60
59
  listItem = _state$schema$nodes2.listItem,
61
- paragraph = _state$schema$nodes2.paragraph,
62
60
  table = _state$schema$nodes2.table,
63
61
  layoutColumn = _state$schema$nodes2.layoutColumn;
64
62
  if (!$cursor || $cursor.parent.type !== codeBlock || !dispatch) {
@@ -69,11 +67,7 @@ function keymapPlugin(schema) {
69
67
  if (!node) {
70
68
  return false;
71
69
  }
72
- if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.codeblock-preserve-newlines_54r3m')) {
73
- replaceWithParagraph(node.node, node.pos, $cursor, state, dispatch);
74
- } else {
75
- dispatch(state.tr.setNodeMarkup(node.pos, node.node.type, node.node.attrs, []).setBlockType($cursor.pos, $cursor.pos, paragraph));
76
- }
70
+ replaceWithParagraph(node.node, node.pos, $cursor, state, dispatch);
77
71
  return true;
78
72
  }
79
73
  if ($cursor.node && (0, _utils.isEmptyNode)(schema)($cursor.node()) && ((0, _utils2.hasParentNodeOfType)(layoutColumn)(state.selection) || (0, _utils2.hasParentNodeOfType)(table)(state.selection))) {
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.createPlugin = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _codeBlock = require("@atlaskit/editor-common/code-block");
9
11
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
10
12
  var _selection = require("@atlaskit/editor-common/selection");
11
13
  var _utils = require("@atlaskit/editor-common/utils");
@@ -13,7 +15,7 @@ var _state = require("@atlaskit/editor-prosemirror/state");
13
15
  var _view = require("@atlaskit/editor-prosemirror/view");
14
16
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
17
  var _actions = require("../actions");
16
- var _codeBlock = require("../nodeviews/code-block");
18
+ var _codeBlock2 = require("../nodeviews/code-block");
17
19
  var _pluginKey = require("../plugin-key");
18
20
  var _classNames = require("../ui/class-names");
19
21
  var _utils2 = require("../utils");
@@ -21,16 +23,57 @@ var _actions2 = require("./actions");
21
23
  var _decorators = require("./decorators");
22
24
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
23
25
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26
+ var DECORATION_WRAPPED_BLOCK_NODE_TYPE = 'decorationNodeType';
24
27
  var createPlugin = exports.createPlugin = function createPlugin(_ref) {
25
28
  var _ref$useLongPressSele = _ref.useLongPressSelection,
26
29
  useLongPressSelection = _ref$useLongPressSele === void 0 ? false : _ref$useLongPressSele,
27
30
  getIntl = _ref.getIntl,
28
31
  _ref$allowComposition = _ref.allowCompositionInputOverride,
29
32
  allowCompositionInputOverride = _ref$allowComposition === void 0 ? false : _ref$allowComposition,
30
- api = _ref.api,
31
- _ref$isWrapped = _ref.isWrapped,
32
- isWrapped = _ref$isWrapped === void 0 ? false : _ref$isWrapped;
33
+ api = _ref.api;
33
34
  var handleDOMEvents = {};
35
+ var createWordWrappedDecoratorPluginState = function createWordWrappedDecoratorPluginState(pluginState, tr, node) {
36
+ var decorationSetFromState = pluginState.decorations;
37
+ if (node) {
38
+ var pos = node.pos,
39
+ innerNode = node.node;
40
+ if (pos !== undefined) {
41
+ var isNodeWrapped = (0, _codeBlock.isCodeBlockWordWrapEnabled)(innerNode);
42
+ if (!isNodeWrapped) {
43
+ // Restricts the range of decorators to the current node while not including the previous nodes position in range
44
+ var codeBlockNodePosition = pos + 1;
45
+ var currentWrappedBlockDecorationSet = decorationSetFromState.find(codeBlockNodePosition, codeBlockNodePosition, function (spec) {
46
+ return spec.type === DECORATION_WRAPPED_BLOCK_NODE_TYPE;
47
+ });
48
+ decorationSetFromState = decorationSetFromState.remove(currentWrappedBlockDecorationSet);
49
+ } else {
50
+ var wrappedBlock = _view.Decoration.node(pos, pos + innerNode.nodeSize, {
51
+ class: _classNames.codeBlockClassNames.contentFgWrapped
52
+ }, {
53
+ type: DECORATION_WRAPPED_BLOCK_NODE_TYPE
54
+ } // Allows for quick filtering of decorations while using `find`
55
+ );
56
+ decorationSetFromState = decorationSetFromState.add(tr.doc, [wrappedBlock]);
57
+ }
58
+ }
59
+ }
60
+ return decorationSetFromState;
61
+ };
62
+ var createLineDecoratorPluginState = function createLineDecoratorPluginState(pluginState, tr, node) {
63
+ var decorationSetFromState = pluginState.decorations;
64
+ if (node) {
65
+ var pos = node.pos,
66
+ innerNode = node.node;
67
+ if (pos !== undefined) {
68
+ // Reset the decorations for the children of the code block node. Wipes all line number decorations.
69
+ // @ts-ignore
70
+ decorationSetFromState.children = [];
71
+ var lineDecorators = (0, _decorators.createLineNumbersDecorations)(pos, innerNode);
72
+ decorationSetFromState = decorationSetFromState.add(tr.doc, (0, _toConsumableArray2.default)(lineDecorators));
73
+ }
74
+ }
75
+ return decorationSetFromState;
76
+ };
34
77
 
35
78
  // ME-1599: Composition on mobile was causing the DOM observer to mutate the code block
36
79
  // incorrecly and lose content when pressing enter in the middle of a code block line.
@@ -83,22 +126,30 @@ var createPlugin = exports.createPlugin = function createPlugin(_ref) {
83
126
  };
84
127
  },
85
128
  apply: function apply(tr, pluginState, _oldState, newState) {
86
- if (tr.docChanged || tr.selectionSet) {
129
+ var meta = tr.getMeta(_pluginKey.pluginKey);
130
+ if ((meta === null || meta === void 0 ? void 0 : meta.type) === _actions2.ACTIONS.SET_IS_WRAPPED && (0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping')) {
87
131
  var node = (0, _utils2.findCodeBlock)(newState, tr.selection);
88
- var lineNumberDecorators = [];
89
- if ((0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping')) {
90
- if (node && node.pos !== undefined) {
91
- lineNumberDecorators = (0, _decorators.createLineNumbersDecorations)(node.pos, node.node);
92
- }
93
- }
132
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
133
+ decorations: createWordWrappedDecoratorPluginState(pluginState, tr, node)
134
+ });
135
+ }
136
+ if (tr.docChanged) {
137
+ var _node = (0, _utils2.findCodeBlock)(newState, tr.selection);
94
138
  var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
95
- pos: node ? node.pos : null,
139
+ pos: _node ? _node.pos : null,
96
140
  isNodeSelected: tr.selection instanceof _state.NodeSelection,
97
- decorations: (0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? _view.DecorationSet.create(tr.doc, lineNumberDecorators) : _view.DecorationSet.empty
141
+ decorations: (0, _platformFeatureFlags.fg)('editor_support_code_block_wrapping') ? createLineDecoratorPluginState(pluginState, tr, _node) : _view.DecorationSet.empty
98
142
  });
99
143
  return newPluginState;
100
144
  }
101
- var meta = tr.getMeta(_pluginKey.pluginKey);
145
+ if (tr.selectionSet) {
146
+ var _node2 = (0, _utils2.findCodeBlock)(newState, tr.selection);
147
+ var _newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
148
+ pos: _node2 ? _node2.pos : null,
149
+ isNodeSelected: tr.selection instanceof _state.NodeSelection
150
+ });
151
+ return _newPluginState;
152
+ }
102
153
  if ((meta === null || meta === void 0 ? void 0 : meta.type) === _actions2.ACTIONS.SET_COPIED_TO_CLIPBOARD) {
103
154
  return _objectSpread(_objectSpread({}, pluginState), {}, {
104
155
  contentCopied: meta.data
@@ -121,7 +172,7 @@ var createPlugin = exports.createPlugin = function createPlugin(_ref) {
121
172
  },
122
173
  nodeViews: {
123
174
  codeBlock: function codeBlock(node, view, getPos) {
124
- return (0, _codeBlock.codeBlockNodeView)(node, view, getPos, api);
175
+ return (0, _codeBlock2.codeBlockNodeView)(node, view, getPos, api);
125
176
  }
126
177
  },
127
178
  handleClickOn: (0, _selection.createSelectionClickHandler)(['codeBlock'], function (target) {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.languageListFilter = exports.getToolbarConfig = void 0;
9
+ var _codeBlock = require("@atlaskit/editor-common/code-block");
9
10
  var _messages = _interopRequireWildcard(require("@atlaskit/editor-common/messages"));
10
11
  var _utils = require("@atlaskit/editor-prosemirror/utils");
11
12
  var _copy = _interopRequireDefault(require("@atlaskit/icon/glyph/copy"));
@@ -38,6 +39,7 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig() {
38
39
  if ((node === null || node === void 0 ? void 0 : node.type) !== nodeType) {
39
40
  return;
40
41
  }
42
+ var isWrapped = (0, _codeBlock.isCodeBlockWordWrapEnabled)(node);
41
43
  var language = node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.language;
42
44
  var options = languageList.map(function (lang) {
43
45
  return {
@@ -107,8 +109,9 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig() {
107
109
  icon: _WrapIcon.WrapIcon,
108
110
  onClick: (0, _actions.toggleWordWrapStateForCodeBlockNode)(editorAnalyticsAPI),
109
111
  // Hooking up here for demo purposes. To be revisited with ED-24222.
110
- title: formatMessage(_messages.codeBlockButtonMessages.wrapCode),
111
- tabIndex: null
112
+ title: isWrapped ? formatMessage(_messages.codeBlockButtonMessages.unwrapCode) : formatMessage(_messages.codeBlockButtonMessages.wrapCode),
113
+ tabIndex: null,
114
+ selected: isWrapped
112
115
  };
113
116
  return {
114
117
  title: 'CodeBlock floating controls',
@@ -11,8 +11,11 @@ var codeBlockClassNames = exports.codeBlockClassNames = {
11
11
  end: _styles.CodeBlockSharedCssClassName.CODEBLOCK_END,
12
12
  contentWrapper: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER,
13
13
  gutter: _styles.CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER,
14
- gutterFgWrap: _styles.CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER_FG_WRAP,
15
14
  content: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT,
16
- contentWrapped: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPED,
17
- lineNumberWrapped: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WRAPPED
15
+ // Feature Gate editor_support_code_block_wrapping:
16
+ contentWrapperFg: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER_FG,
17
+ contentFg: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_FG,
18
+ contentFgWrapped: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_FG_WRAPPED,
19
+ lineNumberWidget: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WIDGET,
20
+ gutterFg: _styles.CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER_FG
18
21
  };
@@ -230,24 +230,22 @@ export const toggleWordWrapStateForCodeBlockNode = editorAnalyticsAPI => (state,
230
230
  }
231
231
  const updatedToggleState = !isCodeBlockWordWrapEnabled(codeBlockNode);
232
232
  codeBlockWrappedStates.set(codeBlockNode, updatedToggleState);
233
-
234
- // TODO: Remove in ED-24222. Leaving here for demo purposes.
235
- // eslint-disable-next-line no-console
236
- console.log(`Code Block Word Wrap: Updating codeBlockWrappedStates with: ${updatedToggleState}`);
233
+ tr.setMeta(pluginKey, {
234
+ type: ACTIONS.SET_IS_WRAPPED,
235
+ data: updatedToggleState
236
+ });
237
237
  if (dispatch) {
238
- const payload = {
238
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
239
239
  action: ACTION.TOGGLE_CODE_BLOCK_WRAP,
240
240
  actionSubject: ACTION_SUBJECT.CODE_BLOCK,
241
241
  attributes: {
242
242
  platform: PLATFORMS.WEB,
243
243
  mode: MODE.EDITOR,
244
- wordWrapEnabled: updatedToggleState
244
+ wordWrapEnabled: updatedToggleState,
245
+ codeBlockNodeSize: codeBlockNode.nodeSize
245
246
  },
246
247
  eventType: EVENT_TYPE.TRACK
247
- };
248
-
249
- // TODO: ED-24320 should convert this to attachAnalyticsEvent if it is dispatching a transaction here.
250
- editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent(payload);
248
+ })(tr);
251
249
  dispatch(tr);
252
250
  }
253
251
  return true;
@@ -1,2 +1 @@
1
- export { default as codeBlockPlugin } from './plugin';
2
- export { createDecorationSetFromTextPositions, generateTextPositionsFromNode } from './pm-plugins/decorators';
1
+ export { default as codeBlockPlugin } from './plugin';
@@ -14,12 +14,12 @@ const toDOM = (node, contentEditable) => ['div', {
14
14
  class: codeBlockClassNames.start,
15
15
  contenteditable: 'false'
16
16
  }], ['div', {
17
- class: codeBlockClassNames.contentWrapper
17
+ class: `${codeBlockClassNames.contentWrapper} ${fg('editor_support_code_block_wrapping') && codeBlockClassNames.contentWrapperFg}`
18
18
  }, ['div', {
19
- class: fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFgWrap : codeBlockClassNames.gutter,
19
+ class: fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFg : codeBlockClassNames.gutter,
20
20
  contenteditable: 'false'
21
21
  }], ['div', {
22
- class: codeBlockClassNames.content
22
+ class: fg('editor_support_code_block_wrapping') ? `${codeBlockClassNames.contentFg}` : codeBlockClassNames.content
23
23
  }, ['code', {
24
24
  'data-language': node.attrs.language || '',
25
25
  spellcheck: 'false',
@@ -57,7 +57,7 @@ export class CodeBlockView {
57
57
  this.node = _node;
58
58
  this.dom = dom;
59
59
  this.contentDOM = contentDOM;
60
- this.lineNumberGutter = this.dom.querySelector(`.${fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFgWrap : codeBlockClassNames.gutter}`);
60
+ this.lineNumberGutter = this.dom.querySelector(`.${fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFg : codeBlockClassNames.gutter}`);
61
61
  this.api = api;
62
62
  if (!fg('editor_support_code_block_wrapping')) {
63
63
  this.ensureLineNumbers();
@@ -1,4 +1,5 @@
1
1
  export const ACTIONS = {
2
2
  SET_COPIED_TO_CLIPBOARD: 'SET_COPIED_TO_CLIPBOARD',
3
- SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS: 'SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS'
3
+ SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS: 'SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS',
4
+ SET_IS_WRAPPED: 'SET_IS_WRAPPED'
4
5
  };
@@ -1,41 +1,53 @@
1
1
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
2
2
  import { codeBlockClassNames } from '../ui/class-names';
3
- export const generateTextPositionsFromNode = (pos, node) => {
3
+ const DECORATION_WIDGET_TYPE = 'decorationWidgetType';
4
+ export const generateLineAttributesFromNode = (pos, node) => {
4
5
  // Get content node
5
6
  const contentNode = node.content;
6
7
 
7
8
  // Get node text content
8
- let textPositions = [];
9
+ let lineAttributes = [];
9
10
  contentNode.forEach(child => {
10
11
  const nodeTextContent = child.textContent;
11
12
  const nodeStartPos = pos;
12
13
  let lineStartIndex = nodeStartPos;
13
- const newLinePositions = nodeTextContent.split('\n').map(line => {
14
+ const newLineAttributes = nodeTextContent.split('\n').map((line, index) => {
14
15
  const lineLength = line.length;
15
16
  const lineStart = lineStartIndex + 1;
16
- const lineEnd = lineStart + lineLength;
17
+ const lineNumber = index + 1;
17
18
 
18
19
  // Include the newline character and increment to keep tabs on line position
19
20
  lineStartIndex += lineLength + 1;
20
21
  return {
21
22
  lineStart,
22
- lineEnd
23
+ lineNumber
23
24
  };
24
25
  });
25
- textPositions = [...textPositions, ...newLinePositions];
26
+ lineAttributes = [...lineAttributes, ...newLineAttributes];
26
27
  });
27
- return textPositions;
28
+ return lineAttributes;
28
29
  };
29
- export const createDecorationSetFromTextPositions = textPositions => {
30
- const decorations = textPositions.map(textPosition => {
30
+ export const createDecorationSetFromLineAttributes = lineAttributes => {
31
+ const widgetDecorations = lineAttributes.map(lineAttribute => {
31
32
  const {
32
33
  lineStart,
33
- lineEnd
34
- } = textPosition;
35
- return Decoration.inline(lineStart, lineEnd, {
36
- class: codeBlockClassNames.lineNumberWrapped
34
+ lineNumber
35
+ } = lineAttribute;
36
+
37
+ // Passing a function to create the widget rather than directly passing a widget, as per ProseMirror docs.
38
+ const createLineNumberWidget = () => {
39
+ const widget = document.createElement('span');
40
+ widget.textContent = `${lineNumber}`;
41
+ widget.classList.add(codeBlockClassNames.lineNumberWidget);
42
+ return widget;
43
+ };
44
+
45
+ // side -1 is used so the line numbers are the first thing to the left of the lines of code.
46
+ return Decoration.widget(lineStart, createLineNumberWidget, {
47
+ type: DECORATION_WIDGET_TYPE,
48
+ side: -1
37
49
  });
38
50
  });
39
- return decorations;
51
+ return widgetDecorations;
40
52
  };
41
- export const createLineNumbersDecorations = (pos, node) => createDecorationSetFromTextPositions(generateTextPositionsFromNode(pos, node));
53
+ export const createLineNumbersDecorations = (pos, node) => createDecorationSetFromLineAttributes(generateLineAttributesFromNode(pos, node));
@@ -2,7 +2,6 @@ import { isEmptyNode } from '@atlaskit/editor-common/utils';
2
2
  import { keymap } from '@atlaskit/editor-prosemirror/keymap';
3
3
  import { Selection } from '@atlaskit/editor-prosemirror/state';
4
4
  import { findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
5
- import { getBooleanFF } from '@atlaskit/platform-feature-flags';
6
5
  import { getCursor } from '../utils';
7
6
  const deleteCurrentItem = $from => tr => {
8
7
  return tr.delete($from.before($from.depth), $from.after($from.depth));
@@ -50,7 +49,6 @@ export function keymapPlugin(schema) {
50
49
  const {
51
50
  codeBlock,
52
51
  listItem,
53
- paragraph,
54
52
  table,
55
53
  layoutColumn
56
54
  } = state.schema.nodes;
@@ -62,11 +60,7 @@ export function keymapPlugin(schema) {
62
60
  if (!node) {
63
61
  return false;
64
62
  }
65
- if (getBooleanFF('platform.editor.codeblock-preserve-newlines_54r3m')) {
66
- replaceWithParagraph(node.node, node.pos, $cursor, state, dispatch);
67
- } else {
68
- dispatch(state.tr.setNodeMarkup(node.pos, node.node.type, node.node.attrs, []).setBlockType($cursor.pos, $cursor.pos, paragraph));
69
- }
63
+ replaceWithParagraph(node.node, node.pos, $cursor, state, dispatch);
70
64
  return true;
71
65
  }
72
66
  if ($cursor.node && isEmptyNode(schema)($cursor.node()) && (hasParentNodeOfType(layoutColumn)(state.selection) || hasParentNodeOfType(table)(state.selection))) {