@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
@@ -1,8 +1,9 @@
1
+ import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
1
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
3
  import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
3
4
  import { browser } from '@atlaskit/editor-common/utils';
4
5
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
5
- import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
7
  import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { ignoreFollowingMutations, resetShouldIgnoreFollowingMutations } from '../actions';
8
9
  import { codeBlockNodeView } from '../nodeviews/code-block';
@@ -11,14 +12,58 @@ import { codeBlockClassNames } from '../ui/class-names';
11
12
  import { findCodeBlock } from '../utils';
12
13
  import { ACTIONS } from './actions';
13
14
  import { createLineNumbersDecorations } from './decorators';
15
+ const DECORATION_WRAPPED_BLOCK_NODE_TYPE = 'decorationNodeType';
14
16
  export const createPlugin = ({
15
17
  useLongPressSelection = false,
16
18
  getIntl,
17
19
  allowCompositionInputOverride = false,
18
- api,
19
- isWrapped = false
20
+ api
20
21
  }) => {
21
22
  const handleDOMEvents = {};
23
+ const createWordWrappedDecoratorPluginState = (pluginState, tr, node) => {
24
+ let decorationSetFromState = pluginState.decorations;
25
+ if (node) {
26
+ const {
27
+ pos,
28
+ node: innerNode
29
+ } = node;
30
+ if (pos !== undefined) {
31
+ const isNodeWrapped = isCodeBlockWordWrapEnabled(innerNode);
32
+ if (!isNodeWrapped) {
33
+ // Restricts the range of decorators to the current node while not including the previous nodes position in range
34
+ const codeBlockNodePosition = pos + 1;
35
+ const currentWrappedBlockDecorationSet = decorationSetFromState.find(codeBlockNodePosition, codeBlockNodePosition, spec => spec.type === DECORATION_WRAPPED_BLOCK_NODE_TYPE);
36
+ decorationSetFromState = decorationSetFromState.remove(currentWrappedBlockDecorationSet);
37
+ } else {
38
+ const wrappedBlock = Decoration.node(pos, pos + innerNode.nodeSize, {
39
+ class: codeBlockClassNames.contentFgWrapped
40
+ }, {
41
+ type: DECORATION_WRAPPED_BLOCK_NODE_TYPE
42
+ } // Allows for quick filtering of decorations while using `find`
43
+ );
44
+ decorationSetFromState = decorationSetFromState.add(tr.doc, [wrappedBlock]);
45
+ }
46
+ }
47
+ }
48
+ return decorationSetFromState;
49
+ };
50
+ const createLineDecoratorPluginState = (pluginState, tr, node) => {
51
+ let decorationSetFromState = pluginState.decorations;
52
+ if (node) {
53
+ const {
54
+ pos,
55
+ node: innerNode
56
+ } = node;
57
+ if (pos !== undefined) {
58
+ // Reset the decorations for the children of the code block node. Wipes all line number decorations.
59
+ // @ts-ignore
60
+ decorationSetFromState.children = [];
61
+ const lineDecorators = createLineNumbersDecorations(pos, innerNode);
62
+ decorationSetFromState = decorationSetFromState.add(tr.doc, [...lineDecorators]);
63
+ }
64
+ }
65
+ return decorationSetFromState;
66
+ };
22
67
 
23
68
  // ME-1599: Composition on mobile was causing the DOM observer to mutate the code block
24
69
  // incorrecly and lose content when pressing enter in the middle of a code block line.
@@ -69,23 +114,33 @@ export const createPlugin = ({
69
114
  };
70
115
  },
71
116
  apply(tr, pluginState, _oldState, newState) {
72
- if (tr.docChanged || tr.selectionSet) {
117
+ const meta = tr.getMeta(pluginKey);
118
+ if ((meta === null || meta === void 0 ? void 0 : meta.type) === ACTIONS.SET_IS_WRAPPED && fg('editor_support_code_block_wrapping')) {
119
+ const node = findCodeBlock(newState, tr.selection);
120
+ return {
121
+ ...pluginState,
122
+ decorations: createWordWrappedDecoratorPluginState(pluginState, tr, node)
123
+ };
124
+ }
125
+ if (tr.docChanged) {
73
126
  const node = findCodeBlock(newState, tr.selection);
74
- let lineNumberDecorators = [];
75
- if (fg('editor_support_code_block_wrapping')) {
76
- if (node && node.pos !== undefined) {
77
- lineNumberDecorators = createLineNumbersDecorations(node.pos, node.node);
78
- }
79
- }
80
127
  const newPluginState = {
81
128
  ...pluginState,
82
129
  pos: node ? node.pos : null,
83
130
  isNodeSelected: tr.selection instanceof NodeSelection,
84
- decorations: fg('editor_support_code_block_wrapping') ? DecorationSet.create(tr.doc, lineNumberDecorators) : DecorationSet.empty
131
+ decorations: fg('editor_support_code_block_wrapping') ? createLineDecoratorPluginState(pluginState, tr, node) : DecorationSet.empty
132
+ };
133
+ return newPluginState;
134
+ }
135
+ if (tr.selectionSet) {
136
+ const node = findCodeBlock(newState, tr.selection);
137
+ const newPluginState = {
138
+ ...pluginState,
139
+ pos: node ? node.pos : null,
140
+ isNodeSelected: tr.selection instanceof NodeSelection
85
141
  };
86
142
  return newPluginState;
87
143
  }
88
- const meta = tr.getMeta(pluginKey);
89
144
  if ((meta === null || meta === void 0 ? void 0 : meta.type) === ACTIONS.SET_COPIED_TO_CLIPBOARD) {
90
145
  return {
91
146
  ...pluginState,
@@ -1,3 +1,4 @@
1
+ import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
1
2
  import commonMessages, { codeBlockButtonMessages } from '@atlaskit/editor-common/messages';
2
3
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
3
4
  import CopyIcon from '@atlaskit/icon/glyph/copy';
@@ -27,6 +28,7 @@ export const getToolbarConfig = (allowCopyToClipboard = false, api) => (state, {
27
28
  if ((node === null || node === void 0 ? void 0 : node.type) !== nodeType) {
28
29
  return;
29
30
  }
31
+ const isWrapped = isCodeBlockWordWrapEnabled(node);
30
32
  const language = node === null || node === void 0 ? void 0 : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.language;
31
33
  const options = languageList.map(lang => ({
32
34
  label: lang.name,
@@ -88,8 +90,9 @@ export const getToolbarConfig = (allowCopyToClipboard = false, api) => (state, {
88
90
  icon: WrapIcon,
89
91
  onClick: toggleWordWrapStateForCodeBlockNode(editorAnalyticsAPI),
90
92
  // Hooking up here for demo purposes. To be revisited with ED-24222.
91
- title: formatMessage(codeBlockButtonMessages.wrapCode),
92
- tabIndex: null
93
+ title: isWrapped ? formatMessage(codeBlockButtonMessages.unwrapCode) : formatMessage(codeBlockButtonMessages.wrapCode),
94
+ tabIndex: null,
95
+ selected: isWrapped
93
96
  };
94
97
  return {
95
98
  title: 'CodeBlock floating controls',
@@ -5,8 +5,11 @@ export const codeBlockClassNames = {
5
5
  end: CodeBlockSharedCssClassName.CODEBLOCK_END,
6
6
  contentWrapper: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER,
7
7
  gutter: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER,
8
- gutterFgWrap: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER_FG_WRAP,
9
8
  content: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT,
10
- contentWrapped: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPED,
11
- lineNumberWrapped: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WRAPPED
9
+ // Feature Gate editor_support_code_block_wrapping:
10
+ contentWrapperFg: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER_FG,
11
+ contentFg: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_FG,
12
+ contentFgWrapped: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_FG_WRAPPED,
13
+ lineNumberWidget: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WIDGET,
14
+ gutterFg: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER_FG
12
15
  };
@@ -209,24 +209,22 @@ export var toggleWordWrapStateForCodeBlockNode = function toggleWordWrapStateFor
209
209
  }
210
210
  var updatedToggleState = !isCodeBlockWordWrapEnabled(codeBlockNode);
211
211
  codeBlockWrappedStates.set(codeBlockNode, updatedToggleState);
212
-
213
- // TODO: Remove in ED-24222. Leaving here for demo purposes.
214
- // eslint-disable-next-line no-console
215
- console.log("Code Block Word Wrap: Updating codeBlockWrappedStates with: ".concat(updatedToggleState));
212
+ tr.setMeta(pluginKey, {
213
+ type: ACTIONS.SET_IS_WRAPPED,
214
+ data: updatedToggleState
215
+ });
216
216
  if (dispatch) {
217
- var payload = {
217
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
218
218
  action: ACTION.TOGGLE_CODE_BLOCK_WRAP,
219
219
  actionSubject: ACTION_SUBJECT.CODE_BLOCK,
220
220
  attributes: {
221
221
  platform: PLATFORMS.WEB,
222
222
  mode: MODE.EDITOR,
223
- wordWrapEnabled: updatedToggleState
223
+ wordWrapEnabled: updatedToggleState,
224
+ codeBlockNodeSize: codeBlockNode.nodeSize
224
225
  },
225
226
  eventType: EVENT_TYPE.TRACK
226
- };
227
-
228
- // TODO: ED-24320 should convert this to attachAnalyticsEvent if it is dispatching a transaction here.
229
- editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.fireAnalyticsEvent(payload);
227
+ })(tr);
230
228
  dispatch(tr);
231
229
  }
232
230
  return true;
package/dist/esm/index.js CHANGED
@@ -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';
@@ -17,12 +17,12 @@ var toDOM = function toDOM(node, contentEditable) {
17
17
  class: codeBlockClassNames.start,
18
18
  contenteditable: 'false'
19
19
  }], ['div', {
20
- class: codeBlockClassNames.contentWrapper
20
+ class: "".concat(codeBlockClassNames.contentWrapper, " ").concat(fg('editor_support_code_block_wrapping') && codeBlockClassNames.contentWrapperFg)
21
21
  }, ['div', {
22
- class: fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFgWrap : codeBlockClassNames.gutter,
22
+ class: fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFg : codeBlockClassNames.gutter,
23
23
  contenteditable: 'false'
24
24
  }], ['div', {
25
- class: codeBlockClassNames.content
25
+ class: fg('editor_support_code_block_wrapping') ? "".concat(codeBlockClassNames.contentFg) : codeBlockClassNames.content
26
26
  }, ['code', {
27
27
  'data-language': node.attrs.language || '',
28
28
  spellcheck: 'false',
@@ -62,7 +62,7 @@ export var CodeBlockView = /*#__PURE__*/function () {
62
62
  this.node = _node;
63
63
  this.dom = dom;
64
64
  this.contentDOM = contentDOM;
65
- this.lineNumberGutter = this.dom.querySelector(".".concat(fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFgWrap : codeBlockClassNames.gutter));
65
+ this.lineNumberGutter = this.dom.querySelector(".".concat(fg('editor_support_code_block_wrapping') ? codeBlockClassNames.gutterFg : codeBlockClassNames.gutter));
66
66
  this.api = api;
67
67
  if (!fg('editor_support_code_block_wrapping')) {
68
68
  this.ensureLineNumbers();
@@ -1,4 +1,5 @@
1
1
  export var 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,42 +1,54 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
3
  import { codeBlockClassNames } from '../ui/class-names';
4
- export var generateTextPositionsFromNode = function generateTextPositionsFromNode(pos, node) {
4
+ var DECORATION_WIDGET_TYPE = 'decorationWidgetType';
5
+ export var generateLineAttributesFromNode = function generateLineAttributesFromNode(pos, node) {
5
6
  // Get content node
6
7
  var contentNode = node.content;
7
8
 
8
9
  // Get node text content
9
- var textPositions = [];
10
+ var lineAttributes = [];
10
11
  contentNode.forEach(function (child) {
11
12
  var nodeTextContent = child.textContent;
12
13
  var nodeStartPos = pos;
13
14
  var lineStartIndex = nodeStartPos;
14
- var newLinePositions = nodeTextContent.split('\n').map(function (line) {
15
+ var newLineAttributes = nodeTextContent.split('\n').map(function (line, index) {
15
16
  var lineLength = line.length;
16
17
  var lineStart = lineStartIndex + 1;
17
- var lineEnd = lineStart + lineLength;
18
+ var lineNumber = index + 1;
18
19
 
19
20
  // Include the newline character and increment to keep tabs on line position
20
21
  lineStartIndex += lineLength + 1;
21
22
  return {
22
23
  lineStart: lineStart,
23
- lineEnd: lineEnd
24
+ lineNumber: lineNumber
24
25
  };
25
26
  });
26
- textPositions = [].concat(_toConsumableArray(textPositions), _toConsumableArray(newLinePositions));
27
+ lineAttributes = [].concat(_toConsumableArray(lineAttributes), _toConsumableArray(newLineAttributes));
27
28
  });
28
- return textPositions;
29
+ return lineAttributes;
29
30
  };
30
- export var createDecorationSetFromTextPositions = function createDecorationSetFromTextPositions(textPositions) {
31
- var decorations = textPositions.map(function (textPosition) {
32
- var lineStart = textPosition.lineStart,
33
- lineEnd = textPosition.lineEnd;
34
- return Decoration.inline(lineStart, lineEnd, {
35
- class: codeBlockClassNames.lineNumberWrapped
31
+ export var createDecorationSetFromLineAttributes = function createDecorationSetFromLineAttributes(lineAttributes) {
32
+ var widgetDecorations = lineAttributes.map(function (lineAttribute) {
33
+ var lineStart = lineAttribute.lineStart,
34
+ lineNumber = lineAttribute.lineNumber;
35
+
36
+ // Passing a function to create the widget rather than directly passing a widget, as per ProseMirror docs.
37
+ var createLineNumberWidget = function createLineNumberWidget() {
38
+ var widget = document.createElement('span');
39
+ widget.textContent = "".concat(lineNumber);
40
+ widget.classList.add(codeBlockClassNames.lineNumberWidget);
41
+ return widget;
42
+ };
43
+
44
+ // side -1 is used so the line numbers are the first thing to the left of the lines of code.
45
+ return Decoration.widget(lineStart, createLineNumberWidget, {
46
+ type: DECORATION_WIDGET_TYPE,
47
+ side: -1
36
48
  });
37
49
  });
38
- return decorations;
50
+ return widgetDecorations;
39
51
  };
40
52
  export var createLineNumbersDecorations = function createLineNumbersDecorations(pos, node) {
41
- return createDecorationSetFromTextPositions(generateTextPositionsFromNode(pos, node));
53
+ return createDecorationSetFromLineAttributes(generateLineAttributesFromNode(pos, node));
42
54
  };
@@ -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
  var deleteCurrentItem = function deleteCurrentItem($from) {
8
7
  return function (tr) {
@@ -51,7 +50,6 @@ export function keymapPlugin(schema) {
51
50
  var _state$schema$nodes2 = state.schema.nodes,
52
51
  codeBlock = _state$schema$nodes2.codeBlock,
53
52
  listItem = _state$schema$nodes2.listItem,
54
- paragraph = _state$schema$nodes2.paragraph,
55
53
  table = _state$schema$nodes2.table,
56
54
  layoutColumn = _state$schema$nodes2.layoutColumn;
57
55
  if (!$cursor || $cursor.parent.type !== codeBlock || !dispatch) {
@@ -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))) {
@@ -1,11 +1,13 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
3
  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; }
3
4
  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) { _defineProperty(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; }
5
+ import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
4
6
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
7
  import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
6
8
  import { browser } from '@atlaskit/editor-common/utils';
7
9
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
8
- import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
10
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
9
11
  import { fg } from '@atlaskit/platform-feature-flags';
10
12
  import { ignoreFollowingMutations, resetShouldIgnoreFollowingMutations } from '../actions';
11
13
  import { codeBlockNodeView } from '../nodeviews/code-block';
@@ -14,16 +16,57 @@ import { codeBlockClassNames } from '../ui/class-names';
14
16
  import { findCodeBlock } from '../utils';
15
17
  import { ACTIONS } from './actions';
16
18
  import { createLineNumbersDecorations } from './decorators';
19
+ var DECORATION_WRAPPED_BLOCK_NODE_TYPE = 'decorationNodeType';
17
20
  export var createPlugin = function createPlugin(_ref) {
18
21
  var _ref$useLongPressSele = _ref.useLongPressSelection,
19
22
  useLongPressSelection = _ref$useLongPressSele === void 0 ? false : _ref$useLongPressSele,
20
23
  getIntl = _ref.getIntl,
21
24
  _ref$allowComposition = _ref.allowCompositionInputOverride,
22
25
  allowCompositionInputOverride = _ref$allowComposition === void 0 ? false : _ref$allowComposition,
23
- api = _ref.api,
24
- _ref$isWrapped = _ref.isWrapped,
25
- isWrapped = _ref$isWrapped === void 0 ? false : _ref$isWrapped;
26
+ api = _ref.api;
26
27
  var handleDOMEvents = {};
28
+ var createWordWrappedDecoratorPluginState = function createWordWrappedDecoratorPluginState(pluginState, tr, node) {
29
+ var decorationSetFromState = pluginState.decorations;
30
+ if (node) {
31
+ var pos = node.pos,
32
+ innerNode = node.node;
33
+ if (pos !== undefined) {
34
+ var isNodeWrapped = isCodeBlockWordWrapEnabled(innerNode);
35
+ if (!isNodeWrapped) {
36
+ // Restricts the range of decorators to the current node while not including the previous nodes position in range
37
+ var codeBlockNodePosition = pos + 1;
38
+ var currentWrappedBlockDecorationSet = decorationSetFromState.find(codeBlockNodePosition, codeBlockNodePosition, function (spec) {
39
+ return spec.type === DECORATION_WRAPPED_BLOCK_NODE_TYPE;
40
+ });
41
+ decorationSetFromState = decorationSetFromState.remove(currentWrappedBlockDecorationSet);
42
+ } else {
43
+ var wrappedBlock = Decoration.node(pos, pos + innerNode.nodeSize, {
44
+ class: codeBlockClassNames.contentFgWrapped
45
+ }, {
46
+ type: DECORATION_WRAPPED_BLOCK_NODE_TYPE
47
+ } // Allows for quick filtering of decorations while using `find`
48
+ );
49
+ decorationSetFromState = decorationSetFromState.add(tr.doc, [wrappedBlock]);
50
+ }
51
+ }
52
+ }
53
+ return decorationSetFromState;
54
+ };
55
+ var createLineDecoratorPluginState = function createLineDecoratorPluginState(pluginState, tr, node) {
56
+ var decorationSetFromState = pluginState.decorations;
57
+ if (node) {
58
+ var pos = node.pos,
59
+ innerNode = node.node;
60
+ if (pos !== undefined) {
61
+ // Reset the decorations for the children of the code block node. Wipes all line number decorations.
62
+ // @ts-ignore
63
+ decorationSetFromState.children = [];
64
+ var lineDecorators = createLineNumbersDecorations(pos, innerNode);
65
+ decorationSetFromState = decorationSetFromState.add(tr.doc, _toConsumableArray(lineDecorators));
66
+ }
67
+ }
68
+ return decorationSetFromState;
69
+ };
27
70
 
28
71
  // ME-1599: Composition on mobile was causing the DOM observer to mutate the code block
29
72
  // incorrecly and lose content when pressing enter in the middle of a code block line.
@@ -76,22 +119,30 @@ export var createPlugin = function createPlugin(_ref) {
76
119
  };
77
120
  },
78
121
  apply: function apply(tr, pluginState, _oldState, newState) {
79
- if (tr.docChanged || tr.selectionSet) {
122
+ var meta = tr.getMeta(pluginKey);
123
+ if ((meta === null || meta === void 0 ? void 0 : meta.type) === ACTIONS.SET_IS_WRAPPED && fg('editor_support_code_block_wrapping')) {
80
124
  var node = findCodeBlock(newState, tr.selection);
81
- var lineNumberDecorators = [];
82
- if (fg('editor_support_code_block_wrapping')) {
83
- if (node && node.pos !== undefined) {
84
- lineNumberDecorators = createLineNumbersDecorations(node.pos, node.node);
85
- }
86
- }
125
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
126
+ decorations: createWordWrappedDecoratorPluginState(pluginState, tr, node)
127
+ });
128
+ }
129
+ if (tr.docChanged) {
130
+ var _node = findCodeBlock(newState, tr.selection);
87
131
  var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
88
- pos: node ? node.pos : null,
132
+ pos: _node ? _node.pos : null,
89
133
  isNodeSelected: tr.selection instanceof NodeSelection,
90
- decorations: fg('editor_support_code_block_wrapping') ? DecorationSet.create(tr.doc, lineNumberDecorators) : DecorationSet.empty
134
+ decorations: fg('editor_support_code_block_wrapping') ? createLineDecoratorPluginState(pluginState, tr, _node) : DecorationSet.empty
91
135
  });
92
136
  return newPluginState;
93
137
  }
94
- var meta = tr.getMeta(pluginKey);
138
+ if (tr.selectionSet) {
139
+ var _node2 = findCodeBlock(newState, tr.selection);
140
+ var _newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
141
+ pos: _node2 ? _node2.pos : null,
142
+ isNodeSelected: tr.selection instanceof NodeSelection
143
+ });
144
+ return _newPluginState;
145
+ }
95
146
  if ((meta === null || meta === void 0 ? void 0 : meta.type) === ACTIONS.SET_COPIED_TO_CLIPBOARD) {
96
147
  return _objectSpread(_objectSpread({}, pluginState), {}, {
97
148
  contentCopied: meta.data
@@ -1,3 +1,4 @@
1
+ import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
1
2
  import commonMessages, { codeBlockButtonMessages } from '@atlaskit/editor-common/messages';
2
3
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
3
4
  import CopyIcon from '@atlaskit/icon/glyph/copy';
@@ -28,6 +29,7 @@ export var getToolbarConfig = function getToolbarConfig() {
28
29
  if ((node === null || node === void 0 ? void 0 : node.type) !== nodeType) {
29
30
  return;
30
31
  }
32
+ var isWrapped = isCodeBlockWordWrapEnabled(node);
31
33
  var language = node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.language;
32
34
  var options = languageList.map(function (lang) {
33
35
  return {
@@ -97,8 +99,9 @@ export var getToolbarConfig = function getToolbarConfig() {
97
99
  icon: WrapIcon,
98
100
  onClick: toggleWordWrapStateForCodeBlockNode(editorAnalyticsAPI),
99
101
  // Hooking up here for demo purposes. To be revisited with ED-24222.
100
- title: formatMessage(codeBlockButtonMessages.wrapCode),
101
- tabIndex: null
102
+ title: isWrapped ? formatMessage(codeBlockButtonMessages.unwrapCode) : formatMessage(codeBlockButtonMessages.wrapCode),
103
+ tabIndex: null,
104
+ selected: isWrapped
102
105
  };
103
106
  return {
104
107
  title: 'CodeBlock floating controls',
@@ -5,8 +5,11 @@ export var codeBlockClassNames = {
5
5
  end: CodeBlockSharedCssClassName.CODEBLOCK_END,
6
6
  contentWrapper: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER,
7
7
  gutter: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER,
8
- gutterFgWrap: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER_FG_WRAP,
9
8
  content: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT,
10
- contentWrapped: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPED,
11
- lineNumberWrapped: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WRAPPED
9
+ // Feature Gate editor_support_code_block_wrapping:
10
+ contentWrapperFg: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER_FG,
11
+ contentFg: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_FG,
12
+ contentFgWrapped: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_FG_WRAPPED,
13
+ lineNumberWidget: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WIDGET,
14
+ gutterFg: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER_FG
12
15
  };
@@ -1,4 +1,3 @@
1
1
  export { default as codeBlockPlugin } from './plugin';
2
2
  export type { CodeBlockPlugin } from './plugin';
3
3
  export type { CodeBlockOptions } from './types';
4
- export { createDecorationSetFromTextPositions, generateTextPositionsFromNode, } from './pm-plugins/decorators';
@@ -1,4 +1,5 @@
1
1
  export declare const ACTIONS: {
2
2
  SET_COPIED_TO_CLIPBOARD: string;
3
3
  SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS: string;
4
+ SET_IS_WRAPPED: string;
4
5
  };
@@ -1,6 +1,6 @@
1
1
  import type { Node } from '@atlaskit/editor-prosemirror/model';
2
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
- import type { CodeBlockTextPosition } from '../types';
4
- export declare const generateTextPositionsFromNode: (pos: number, node: Node) => CodeBlockTextPosition[];
5
- export declare const createDecorationSetFromTextPositions: (textPositions: CodeBlockTextPosition[]) => Decoration[];
3
+ import type { CodeBlockLineAttributes } from '../types';
4
+ export declare const generateLineAttributesFromNode: (pos: number, node: Node) => CodeBlockLineAttributes[];
5
+ export declare const createDecorationSetFromLineAttributes: (lineAttributes: CodeBlockLineAttributes[]) => Decoration[];
6
6
  export declare const createLineNumbersDecorations: (pos: number, node: Node) => Decoration[];
@@ -4,7 +4,7 @@ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { CodeBlockPlugin } from '../index';
6
6
  import { type CodeBlockState } from './main-state';
7
- export declare const createPlugin: ({ useLongPressSelection, getIntl, allowCompositionInputOverride, api, isWrapped, }: {
7
+ export declare const createPlugin: ({ useLongPressSelection, getIntl, allowCompositionInputOverride, api, }: {
8
8
  useLongPressSelection?: boolean | undefined;
9
9
  getIntl: () => IntlShape;
10
10
  allowCompositionInputOverride?: boolean | undefined;
@@ -37,6 +37,5 @@ export declare const createPlugin: ({ useLongPressSelection, getIntl, allowCompo
37
37
  insertCodeBlock: (inputMethod: import("@atlaskit/editor-common/analytics").INPUT_METHOD) => import("@atlaskit/editor-common/types").Command;
38
38
  };
39
39
  }> | undefined;
40
- isWrapped?: boolean | undefined;
41
40
  decorations?: DecorationSet | undefined;
42
41
  }) => SafePlugin<CodeBlockState>;
@@ -3,7 +3,7 @@ export interface CodeBlockOptions extends LongPressSelectionPluginOptions {
3
3
  allowCopyToClipboard?: boolean;
4
4
  allowCompositionInputOverride?: boolean;
5
5
  }
6
- export type CodeBlockTextPosition = {
6
+ export type CodeBlockLineAttributes = {
7
7
  lineStart: number;
8
- lineEnd: number;
8
+ lineNumber: number;
9
9
  };
@@ -4,8 +4,10 @@ export declare const codeBlockClassNames: {
4
4
  end: string;
5
5
  contentWrapper: string;
6
6
  gutter: string;
7
- gutterFgWrap: string;
8
7
  content: string;
9
- contentWrapped: string;
10
- lineNumberWrapped: string;
8
+ contentWrapperFg: string;
9
+ contentFg: string;
10
+ contentFgWrapped: string;
11
+ lineNumberWidget: string;
12
+ gutterFg: string;
11
13
  };
@@ -1,4 +1,3 @@
1
1
  export { default as codeBlockPlugin } from './plugin';
2
2
  export type { CodeBlockPlugin } from './plugin';
3
3
  export type { CodeBlockOptions } from './types';
4
- export { createDecorationSetFromTextPositions, generateTextPositionsFromNode, } from './pm-plugins/decorators';
@@ -1,4 +1,5 @@
1
1
  export declare const ACTIONS: {
2
2
  SET_COPIED_TO_CLIPBOARD: string;
3
3
  SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS: string;
4
+ SET_IS_WRAPPED: string;
4
5
  };
@@ -1,6 +1,6 @@
1
1
  import type { Node } from '@atlaskit/editor-prosemirror/model';
2
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
- import type { CodeBlockTextPosition } from '../types';
4
- export declare const generateTextPositionsFromNode: (pos: number, node: Node) => CodeBlockTextPosition[];
5
- export declare const createDecorationSetFromTextPositions: (textPositions: CodeBlockTextPosition[]) => Decoration[];
3
+ import type { CodeBlockLineAttributes } from '../types';
4
+ export declare const generateLineAttributesFromNode: (pos: number, node: Node) => CodeBlockLineAttributes[];
5
+ export declare const createDecorationSetFromLineAttributes: (lineAttributes: CodeBlockLineAttributes[]) => Decoration[];
6
6
  export declare const createLineNumbersDecorations: (pos: number, node: Node) => Decoration[];
@@ -4,7 +4,7 @@ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { CodeBlockPlugin } from '../index';
6
6
  import { type CodeBlockState } from './main-state';
7
- export declare const createPlugin: ({ useLongPressSelection, getIntl, allowCompositionInputOverride, api, isWrapped, }: {
7
+ export declare const createPlugin: ({ useLongPressSelection, getIntl, allowCompositionInputOverride, api, }: {
8
8
  useLongPressSelection?: boolean | undefined;
9
9
  getIntl: () => IntlShape;
10
10
  allowCompositionInputOverride?: boolean | undefined;
@@ -44,6 +44,5 @@ export declare const createPlugin: ({ useLongPressSelection, getIntl, allowCompo
44
44
  insertCodeBlock: (inputMethod: import("@atlaskit/editor-common/analytics").INPUT_METHOD) => import("@atlaskit/editor-common/types").Command;
45
45
  };
46
46
  }> | undefined;
47
- isWrapped?: boolean | undefined;
48
47
  decorations?: DecorationSet | undefined;
49
48
  }) => SafePlugin<CodeBlockState>;
@@ -3,7 +3,7 @@ export interface CodeBlockOptions extends LongPressSelectionPluginOptions {
3
3
  allowCopyToClipboard?: boolean;
4
4
  allowCompositionInputOverride?: boolean;
5
5
  }
6
- export type CodeBlockTextPosition = {
6
+ export type CodeBlockLineAttributes = {
7
7
  lineStart: number;
8
- lineEnd: number;
8
+ lineNumber: number;
9
9
  };
@@ -4,8 +4,10 @@ export declare const codeBlockClassNames: {
4
4
  end: string;
5
5
  contentWrapper: string;
6
6
  gutter: string;
7
- gutterFgWrap: string;
8
7
  content: string;
9
- contentWrapped: string;
10
- lineNumberWrapped: string;
8
+ contentWrapperFg: string;
9
+ contentFg: string;
10
+ contentFgWrapped: string;
11
+ lineNumberWidget: string;
12
+ gutterFg: string;
11
13
  };