@atlaskit/editor-plugin-code-block-advanced 10.1.0 → 10.1.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.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/nodeviews/codeBlockAdvanced.js +47 -19
- package/dist/cjs/nodeviews/codeBlockNodeWithToDOMFixed.js +61 -27
- package/dist/cjs/ui/theme.js +12 -2
- package/dist/es2019/nodeviews/codeBlockAdvanced.js +39 -18
- package/dist/es2019/nodeviews/codeBlockNodeWithToDOMFixed.js +53 -25
- package/dist/es2019/ui/theme.js +8 -1
- package/dist/esm/nodeviews/codeBlockAdvanced.js +48 -20
- package/dist/esm/nodeviews/codeBlockNodeWithToDOMFixed.js +61 -27
- package/dist/esm/ui/theme.js +11 -2
- package/dist/types/nodeviews/codeBlockAdvanced.d.ts +6 -0
- package/dist/types-ts4.5/nodeviews/codeBlockAdvanced.d.ts +6 -0
- package/docs/0-intro.tsx +1 -1
- package/package.json +3 -3
- package/src/nodeviews/codeBlockAdvanced.ts +64 -19
- package/src/nodeviews/codeBlockNodeWithToDOMFixed.ts +74 -33
- package/src/ui/theme.ts +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-code-block-advanced
|
|
2
2
|
|
|
3
|
+
## 10.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 10.1.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`7e8145e6a7ce6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7e8145e6a7ce6) -
|
|
14
|
+
Add ADF-backed code block line number visibility
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
3
17
|
## 10.1.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -46,14 +46,15 @@ var codeBlockHeights = new WeakMap();
|
|
|
46
46
|
// Based on: https://prosemirror.net/examples/codemirror/
|
|
47
47
|
var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
48
48
|
function CodeBlockAdvancedNodeView(node, view, getPos, innerDecorations, config) {
|
|
49
|
-
var
|
|
49
|
+
var _this = this,
|
|
50
|
+
_config$api,
|
|
50
51
|
_contentFormatSharedS,
|
|
51
52
|
_config$api2,
|
|
52
|
-
_this = this,
|
|
53
53
|
_config$api3,
|
|
54
54
|
_config$api4;
|
|
55
55
|
(0, _classCallCheck2.default)(this, CodeBlockAdvancedNodeView);
|
|
56
56
|
(0, _defineProperty2.default)(this, "lineWrappingCompartment", new _state.Compartment());
|
|
57
|
+
(0, _defineProperty2.default)(this, "lineNumbersCompartment", new _state.Compartment());
|
|
57
58
|
(0, _defineProperty2.default)(this, "languageCompartment", new _state.Compartment());
|
|
58
59
|
(0, _defineProperty2.default)(this, "readOnlyCompartment", new _state.Compartment());
|
|
59
60
|
(0, _defineProperty2.default)(this, "pmDecorationsCompartment", new _state.Compartment());
|
|
@@ -61,6 +62,11 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
61
62
|
(0, _defineProperty2.default)(this, "maybeTryingToReachNodeSelection", false);
|
|
62
63
|
(0, _defineProperty2.default)(this, "pmFacet", _state.Facet.define());
|
|
63
64
|
(0, _defineProperty2.default)(this, "wordWrappingEnabled", false);
|
|
65
|
+
(0, _defineProperty2.default)(this, "lineNumbersHidden", false);
|
|
66
|
+
(0, _defineProperty2.default)(this, "selectCodeBlockNodeAndFocus", function () {
|
|
67
|
+
_this.selectCodeBlockNode(undefined);
|
|
68
|
+
_this.view.focus();
|
|
69
|
+
});
|
|
64
70
|
this.config = config;
|
|
65
71
|
this.node = node;
|
|
66
72
|
this.view = view;
|
|
@@ -87,10 +93,6 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
87
93
|
var _config$getIntl = config.getIntl(),
|
|
88
94
|
formatMessage = _config$getIntl.formatMessage;
|
|
89
95
|
var formattedAriaLabel = formatMessage(_messages.blockTypeMessages.codeblock);
|
|
90
|
-
var selectNode = function selectNode() {
|
|
91
|
-
_this.selectCodeBlockNode(undefined);
|
|
92
|
-
_this.view.focus();
|
|
93
|
-
};
|
|
94
96
|
var isMacOS = (0, _browser.getBrowserInfo)().mac;
|
|
95
97
|
this.cm = new _view.EditorView({
|
|
96
98
|
doc: this.node.textContent,
|
|
@@ -107,16 +109,9 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
107
109
|
// Goes before cmTheme to override styles
|
|
108
110
|
config.allowCodeFolding ? [_theme.codeFoldingTheme] : [], this.themeCompartment.of((0, _theme.cmTheme)({
|
|
109
111
|
contentMode: (0, _expValEquals.expValEquals)('confluence_compact_text_format', 'isEnabled', true) ? this.contentMode : undefined
|
|
110
|
-
})), (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0, _language.bracketMatching)(), (0,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
selectNode();
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}),
|
|
118
|
-
// Explicitly disable "sticky" positioning on line numbers to match
|
|
119
|
-
// Renderer behaviour
|
|
112
|
+
})), (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0, _language.bracketMatching)(), (0, _expValEquals.expValEquals)('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? this.lineNumbersCompartment.of(this.getLineNumberVisibilityExtensions(node)) : this.getLineNumberExtensions(),
|
|
113
|
+
// Explicitly disable "sticky" positioning on all gutters to match
|
|
114
|
+
// Renderer behaviour.
|
|
120
115
|
(0, _view.gutters)({
|
|
121
116
|
fixed: false
|
|
122
117
|
}), _view.EditorView.updateListener.of(function (update) {
|
|
@@ -139,7 +134,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
139
134
|
'aria-label': formattedAriaLabel,
|
|
140
135
|
'aria-describedby': "codesnippet-".concat(this.node.attrs.localId)
|
|
141
136
|
})), config.allowCodeFolding ? [(0, _foldGutter.foldGutterExtension)({
|
|
142
|
-
selectNode:
|
|
137
|
+
selectNode: this.selectCodeBlockNodeAndFocus,
|
|
143
138
|
getNode: function getNode() {
|
|
144
139
|
return _this.node;
|
|
145
140
|
}
|
|
@@ -221,6 +216,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
221
216
|
this.updateLanguage();
|
|
222
217
|
this.updateLocalIdAttribute();
|
|
223
218
|
this.wordWrappingEnabled = (0, _codeBlock.isCodeBlockWordWrapEnabled)(node);
|
|
219
|
+
this.lineNumbersHidden = (0, _codeBlock.areCodeBlockLineNumbersHidden)(node);
|
|
224
220
|
|
|
225
221
|
// Restore fold state after initialization
|
|
226
222
|
if (config.allowCodeFolding) {
|
|
@@ -335,6 +331,37 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
335
331
|
this.view.dispatch(tr);
|
|
336
332
|
}
|
|
337
333
|
}
|
|
334
|
+
}, {
|
|
335
|
+
key: "getLineNumberExtensions",
|
|
336
|
+
value: function getLineNumberExtensions() {
|
|
337
|
+
var _this2 = this;
|
|
338
|
+
return [(0, _view.lineNumbers)({
|
|
339
|
+
domEventHandlers: {
|
|
340
|
+
click: function click() {
|
|
341
|
+
_this2.selectCodeBlockNodeAndFocus();
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
})];
|
|
346
|
+
}
|
|
347
|
+
}, {
|
|
348
|
+
key: "getLineNumberVisibilityExtensions",
|
|
349
|
+
value: function getLineNumberVisibilityExtensions(node) {
|
|
350
|
+
if ((0, _codeBlock.areCodeBlockLineNumbersHidden)(node)) {
|
|
351
|
+
return [];
|
|
352
|
+
}
|
|
353
|
+
return this.getLineNumberExtensions();
|
|
354
|
+
}
|
|
355
|
+
}, {
|
|
356
|
+
key: "getLineNumbersEffects",
|
|
357
|
+
value: function getLineNumbersEffects(node) {
|
|
358
|
+
var lineNumbersHidden = (0, _codeBlock.areCodeBlockLineNumbersHidden)(node);
|
|
359
|
+
if (this.lineNumbersHidden !== lineNumbersHidden) {
|
|
360
|
+
this.lineNumbersHidden = lineNumbersHidden;
|
|
361
|
+
return this.lineNumbersCompartment.reconfigure(this.getLineNumberVisibilityExtensions(node));
|
|
362
|
+
}
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
338
365
|
}, {
|
|
339
366
|
key: "getWordWrapEffects",
|
|
340
367
|
value: function getWordWrapEffects(node) {
|
|
@@ -393,11 +420,12 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
393
420
|
// Updates bundled for performance (to avoid multiple-dispatches)
|
|
394
421
|
var changes = (0, _updateCMSelection.getCMSelectionChanges)(curText, newText);
|
|
395
422
|
var wordWrapEffect = this.getWordWrapEffects(node);
|
|
423
|
+
var lineNumbersEffect = (0, _expValEquals.expValEquals)('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? this.getLineNumbersEffects(node) : undefined;
|
|
396
424
|
var prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
|
|
397
|
-
if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
|
|
425
|
+
if (changes || wordWrapEffect || lineNumbersEffect || prosemirrorDecorationsEffect) {
|
|
398
426
|
this.updating = true;
|
|
399
427
|
this.cm.dispatch({
|
|
400
|
-
effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(function (effect) {
|
|
428
|
+
effects: [wordWrapEffect, lineNumbersEffect, prosemirrorDecorationsEffect].filter(function (effect) {
|
|
401
429
|
return !!effect;
|
|
402
430
|
}),
|
|
403
431
|
changes: changes
|
|
@@ -5,8 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.codeBlockNodeWithFixedToDOM = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
8
9
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
10
|
var _adfSchema = require("@atlaskit/adf-schema");
|
|
11
|
+
var _codeBlock = require("@atlaskit/editor-common/code-block");
|
|
10
12
|
var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
|
|
11
13
|
var _styles = require("@atlaskit/editor-common/styles");
|
|
12
14
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
@@ -24,6 +26,57 @@ var MATCH_NEWLINES = new RegExp('\n', 'gu');
|
|
|
24
26
|
var getFontSize = function getFontSize() {
|
|
25
27
|
return (0, _expValEquals.expValEquals)('confluence_compact_text_format', 'isEnabled', true) || (0, _expValEquals.expValEquals)('cc_editor_ai_content_mode', 'variant', 'test') && (0, _platformFeatureFlags.fg)('platform_editor_content_mode_button_mvp') ? '0.875em' : '0.875rem';
|
|
26
28
|
};
|
|
29
|
+
var getGutterBaseStyle = function getGutterBaseStyle() {
|
|
30
|
+
return {
|
|
31
|
+
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
32
|
+
position: 'relative',
|
|
33
|
+
flexShrink: 0,
|
|
34
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
35
|
+
fontSize: getFontSize(),
|
|
36
|
+
boxSizing: 'content-box'
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
var getGutterPadding = function getGutterPadding(allowCodeFolding) {
|
|
40
|
+
return allowCodeFolding ? "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-250, 20px)", " ", "var(--ds-space-100, 8px)", " ", "var(--ds-space-075, 6px)") : "var(--ds-space-100, 8px)";
|
|
41
|
+
};
|
|
42
|
+
var getGuttersWithLineNumbers = function getGuttersWithLineNumbers(content, config) {
|
|
43
|
+
return ['div', {
|
|
44
|
+
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
45
|
+
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
46
|
+
style: (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({}, getGutterBaseStyle()), {}, {
|
|
47
|
+
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
48
|
+
/* top and bottom | left and right */
|
|
49
|
+
padding: getGutterPadding(config.allowCodeFolding)
|
|
50
|
+
})),
|
|
51
|
+
contenteditable: 'false'
|
|
52
|
+
}, ['div', {
|
|
53
|
+
class: 'code-block-gutter-pseudo-element',
|
|
54
|
+
style: (0, _lazyNodeView.convertToInlineCss)({
|
|
55
|
+
textAlign: 'right',
|
|
56
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
57
|
+
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
58
|
+
whiteSpace: 'pre-wrap'
|
|
59
|
+
}),
|
|
60
|
+
'data-label': content
|
|
61
|
+
}]];
|
|
62
|
+
};
|
|
63
|
+
var getFoldOnlyGutter = function getFoldOnlyGutter() {
|
|
64
|
+
return ['div', {
|
|
65
|
+
style: (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({}, getGutterBaseStyle()), {}, {
|
|
66
|
+
padding: "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-150, 12px)", " ", "var(--ds-space-100, 8px)", " ", "var(--ds-space-100, 8px)")
|
|
67
|
+
})),
|
|
68
|
+
contenteditable: 'false'
|
|
69
|
+
}];
|
|
70
|
+
};
|
|
71
|
+
var getGutters = function getGutters(content, config, hideLineNumbers) {
|
|
72
|
+
if (!hideLineNumbers) {
|
|
73
|
+
return [getGuttersWithLineNumbers(content, config)];
|
|
74
|
+
}
|
|
75
|
+
if (config.allowCodeFolding) {
|
|
76
|
+
return [getFoldOnlyGutter()];
|
|
77
|
+
}
|
|
78
|
+
return [];
|
|
79
|
+
};
|
|
27
80
|
|
|
28
81
|
// Based on: `packages/editor/editor-plugin-code-block/src/nodeviews/code-block.ts`
|
|
29
82
|
var _toDOM = function toDOM(node, formattedAriaLabel, config) {
|
|
@@ -34,45 +87,26 @@ var _toDOM = function toDOM(node, formattedAriaLabel, config) {
|
|
|
34
87
|
totalLineCount += (node.text.match(MATCH_NEWLINES) || []).length;
|
|
35
88
|
}
|
|
36
89
|
});
|
|
90
|
+
var hideLineNumbers = (0, _codeBlock.areCodeBlockLineNumbersHidden)(node);
|
|
37
91
|
var maxDigits = totalLineCount.toString().length;
|
|
38
92
|
var content = node.textContent.split('\n').map(function (_, i) {
|
|
39
93
|
return i + 1;
|
|
40
94
|
}).join('\n');
|
|
95
|
+
var gutters = getGutters(content, config, hideLineNumbers);
|
|
41
96
|
return ['pre', _objectSpread({
|
|
42
97
|
class: codeBlockClassNames.container,
|
|
43
98
|
style: "--lineNumberGutterWidth:".concat(maxDigits, "ch;"),
|
|
44
99
|
'data-language': node.attrs.language || ''
|
|
45
|
-
}, (0, _expValEquals.expValEquals)('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
100
|
+
}, (0, _expValEquals.expValEquals)('platform_editor_code_block_q4_lovability', 'isEnabled', true) && _objectSpread({
|
|
46
101
|
'data-wrap': node.attrs.wrap ? 'true' : 'false'
|
|
47
|
-
}
|
|
102
|
+
}, hideLineNumbers && {
|
|
103
|
+
'data-hide-line-numbers': 'true'
|
|
104
|
+
})), ['div', {
|
|
48
105
|
class: codeBlockClassNames.start,
|
|
49
106
|
contenteditable: 'false'
|
|
50
107
|
}], ['div', {
|
|
51
108
|
class: codeBlockClassNames.contentWrapper
|
|
52
|
-
}, ['div', {
|
|
53
|
-
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
54
|
-
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
55
|
-
style: (0, _lazyNodeView.convertToInlineCss)({
|
|
56
|
-
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
57
|
-
position: 'relative',
|
|
58
|
-
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
59
|
-
/* top and bottom | left and right */
|
|
60
|
-
padding: config.allowCodeFolding ? "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-250, 20px)", " ", "var(--ds-space-100, 8px)", " ", "var(--ds-space-075, 6px)") : "var(--ds-space-100, 8px)",
|
|
61
|
-
flexShrink: 0,
|
|
62
|
-
fontSize: getFontSize(),
|
|
63
|
-
boxSizing: 'content-box'
|
|
64
|
-
}),
|
|
65
|
-
contenteditable: 'false'
|
|
66
|
-
}, ['div', {
|
|
67
|
-
class: 'code-block-gutter-pseudo-element',
|
|
68
|
-
style: (0, _lazyNodeView.convertToInlineCss)({
|
|
69
|
-
textAlign: 'right',
|
|
70
|
-
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
71
|
-
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
72
|
-
whiteSpace: 'pre-wrap'
|
|
73
|
-
}),
|
|
74
|
-
'data-label': content
|
|
75
|
-
}]], ['div', {
|
|
109
|
+
}].concat((0, _toConsumableArray2.default)(gutters), [['div', {
|
|
76
110
|
class: codeBlockClassNames.content
|
|
77
111
|
}, ['code', _objectSpread({
|
|
78
112
|
'data-language': node.attrs.language || '',
|
|
@@ -81,7 +115,7 @@ var _toDOM = function toDOM(node, formattedAriaLabel, config) {
|
|
|
81
115
|
'aria-label': formattedAriaLabel
|
|
82
116
|
}, (0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid') && {
|
|
83
117
|
'data-local-id': node.attrs.localId
|
|
84
|
-
}), 0]]], ['div', {
|
|
118
|
+
}), 0]]]), ['div', {
|
|
85
119
|
class: codeBlockClassNames.end,
|
|
86
120
|
contenteditable: 'false'
|
|
87
121
|
}]];
|
package/dist/cjs/ui/theme.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.codeFoldingTheme = exports.cmTheme = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
7
9
|
var _view = require("@codemirror/view");
|
|
8
10
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
9
11
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
12
|
+
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; }
|
|
13
|
+
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; }
|
|
10
14
|
var shouldUseCompactTypography = function shouldUseCompactTypography(contentMode) {
|
|
11
15
|
return contentMode === 'compact' || (0, _expValEquals.expValEquals)('cc_editor_ai_content_mode', 'variant', 'test') && (0, _platformFeatureFlags.fg)('platform_editor_content_mode_button_mvp');
|
|
12
16
|
};
|
|
@@ -65,12 +69,18 @@ var cmTheme = exports.cmTheme = function cmTheme(options) {
|
|
|
65
69
|
'.cm-gutter': {
|
|
66
70
|
padding: "var(--ds-space-100, 8px)"
|
|
67
71
|
},
|
|
68
|
-
'.cm-gutters': {
|
|
72
|
+
'.cm-gutters': _objectSpread({
|
|
69
73
|
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
70
74
|
border: 'none',
|
|
71
75
|
padding: "var(--ds-space-0, 0px)",
|
|
72
76
|
color: "var(--ds-text-subtlest, #6B6E76)"
|
|
73
|
-
},
|
|
77
|
+
}, (0, _expValEquals.expValEquals)('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
78
|
+
// CodeMirror defaults this to height: 100%, which can resolve against an indefinite
|
|
79
|
+
// parent height in content-height editor and prevent flex stretching when gutter
|
|
80
|
+
// content is sparse, such as fold-only gutters.
|
|
81
|
+
height: 'unset',
|
|
82
|
+
alignSelf: 'stretch'
|
|
83
|
+
}),
|
|
74
84
|
'.cm-lineNumbers .cm-gutterElement': {
|
|
75
85
|
paddingLeft: "var(--ds-space-0, 0px)",
|
|
76
86
|
paddingRight: "var(--ds-space-0, 0px)",
|
|
@@ -4,7 +4,7 @@ import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
|
|
|
4
4
|
import { Compartment, Facet, EditorState as CodeMirrorState } from '@codemirror/state';
|
|
5
5
|
import { EditorView as CodeMirror, lineNumbers, gutters } from '@codemirror/view';
|
|
6
6
|
import { getBrowserInfo } from '@atlaskit/editor-common/browser';
|
|
7
|
-
import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
7
|
+
import { areCodeBlockLineNumbersHidden, isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
8
8
|
import { messages as floatingToolbarMessages } from '@atlaskit/editor-common/floating-toolbar';
|
|
9
9
|
import { blockTypeMessages, codeBlockMessages, roleDescriptionMessages } from '@atlaskit/editor-common/messages';
|
|
10
10
|
import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
|
|
@@ -34,6 +34,7 @@ class CodeBlockAdvancedNodeView {
|
|
|
34
34
|
constructor(node, view, getPos, innerDecorations, config) {
|
|
35
35
|
var _config$api, _config$api$contentFo, _contentFormatSharedS, _contentFormatSharedS2, _config$api2, _config$api2$selectio, _config$api3, _config$api3$editorDi, _config$api4;
|
|
36
36
|
_defineProperty(this, "lineWrappingCompartment", new Compartment());
|
|
37
|
+
_defineProperty(this, "lineNumbersCompartment", new Compartment());
|
|
37
38
|
_defineProperty(this, "languageCompartment", new Compartment());
|
|
38
39
|
_defineProperty(this, "readOnlyCompartment", new Compartment());
|
|
39
40
|
_defineProperty(this, "pmDecorationsCompartment", new Compartment());
|
|
@@ -41,6 +42,11 @@ class CodeBlockAdvancedNodeView {
|
|
|
41
42
|
_defineProperty(this, "maybeTryingToReachNodeSelection", false);
|
|
42
43
|
_defineProperty(this, "pmFacet", Facet.define());
|
|
43
44
|
_defineProperty(this, "wordWrappingEnabled", false);
|
|
45
|
+
_defineProperty(this, "lineNumbersHidden", false);
|
|
46
|
+
_defineProperty(this, "selectCodeBlockNodeAndFocus", () => {
|
|
47
|
+
this.selectCodeBlockNode(undefined);
|
|
48
|
+
this.view.focus();
|
|
49
|
+
});
|
|
44
50
|
this.config = config;
|
|
45
51
|
this.node = node;
|
|
46
52
|
this.view = view;
|
|
@@ -64,10 +70,6 @@ class CodeBlockAdvancedNodeView {
|
|
|
64
70
|
formatMessage
|
|
65
71
|
} = config.getIntl();
|
|
66
72
|
const formattedAriaLabel = formatMessage(blockTypeMessages.codeblock);
|
|
67
|
-
const selectNode = () => {
|
|
68
|
-
this.selectCodeBlockNode(undefined);
|
|
69
|
-
this.view.focus();
|
|
70
|
-
};
|
|
71
73
|
const isMacOS = getBrowserInfo().mac;
|
|
72
74
|
this.cm = new CodeMirror({
|
|
73
75
|
doc: this.node.textContent,
|
|
@@ -82,16 +84,9 @@ class CodeBlockAdvancedNodeView {
|
|
|
82
84
|
// Goes before cmTheme to override styles
|
|
83
85
|
config.allowCodeFolding ? [codeFoldingTheme] : [], this.themeCompartment.of(cmTheme({
|
|
84
86
|
contentMode: expValEquals('confluence_compact_text_format', 'isEnabled', true) ? this.contentMode : undefined
|
|
85
|
-
})), syntaxHighlighting(highlightStyle), bracketMatching(),
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
selectNode();
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}),
|
|
93
|
-
// Explicitly disable "sticky" positioning on line numbers to match
|
|
94
|
-
// Renderer behaviour
|
|
87
|
+
})), syntaxHighlighting(highlightStyle), bracketMatching(), expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? this.lineNumbersCompartment.of(this.getLineNumberVisibilityExtensions(node)) : this.getLineNumberExtensions(),
|
|
88
|
+
// Explicitly disable "sticky" positioning on all gutters to match
|
|
89
|
+
// Renderer behaviour.
|
|
95
90
|
gutters({
|
|
96
91
|
fixed: false
|
|
97
92
|
}), CodeMirror.updateListener.of(update => this.forwardUpdate(update)), this.readOnlyCompartment.of([CodeMirrorState.readOnly.of(!this.view.editable), CodeMirror.contentAttributes.of({
|
|
@@ -117,7 +112,7 @@ class CodeBlockAdvancedNodeView {
|
|
|
117
112
|
'aria-describedby': `codesnippet-${this.node.attrs.localId}`
|
|
118
113
|
})
|
|
119
114
|
}), config.allowCodeFolding ? [foldGutterExtension({
|
|
120
|
-
selectNode,
|
|
115
|
+
selectNode: this.selectCodeBlockNodeAndFocus,
|
|
121
116
|
getNode: () => this.node
|
|
122
117
|
})] : [],
|
|
123
118
|
// With platform_editor_fix_advanced_codeblocks_crlf_patch the lineSeparatorExtension is not needed
|
|
@@ -189,6 +184,7 @@ class CodeBlockAdvancedNodeView {
|
|
|
189
184
|
this.updateLanguage();
|
|
190
185
|
this.updateLocalIdAttribute();
|
|
191
186
|
this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
|
|
187
|
+
this.lineNumbersHidden = areCodeBlockLineNumbersHidden(node);
|
|
192
188
|
|
|
193
189
|
// Restore fold state after initialization
|
|
194
190
|
if (config.allowCodeFolding) {
|
|
@@ -288,6 +284,30 @@ class CodeBlockAdvancedNodeView {
|
|
|
288
284
|
this.view.dispatch(tr);
|
|
289
285
|
}
|
|
290
286
|
}
|
|
287
|
+
getLineNumberExtensions() {
|
|
288
|
+
return [lineNumbers({
|
|
289
|
+
domEventHandlers: {
|
|
290
|
+
click: () => {
|
|
291
|
+
this.selectCodeBlockNodeAndFocus();
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
})];
|
|
296
|
+
}
|
|
297
|
+
getLineNumberVisibilityExtensions(node) {
|
|
298
|
+
if (areCodeBlockLineNumbersHidden(node)) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
return this.getLineNumberExtensions();
|
|
302
|
+
}
|
|
303
|
+
getLineNumbersEffects(node) {
|
|
304
|
+
const lineNumbersHidden = areCodeBlockLineNumbersHidden(node);
|
|
305
|
+
if (this.lineNumbersHidden !== lineNumbersHidden) {
|
|
306
|
+
this.lineNumbersHidden = lineNumbersHidden;
|
|
307
|
+
return this.lineNumbersCompartment.reconfigure(this.getLineNumberVisibilityExtensions(node));
|
|
308
|
+
}
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
291
311
|
getWordWrapEffects(node) {
|
|
292
312
|
if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
|
|
293
313
|
this.wordWrappingEnabled = !this.wordWrappingEnabled;
|
|
@@ -338,11 +358,12 @@ class CodeBlockAdvancedNodeView {
|
|
|
338
358
|
// Updates bundled for performance (to avoid multiple-dispatches)
|
|
339
359
|
const changes = getCMSelectionChanges(curText, newText);
|
|
340
360
|
const wordWrapEffect = this.getWordWrapEffects(node);
|
|
361
|
+
const lineNumbersEffect = expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? this.getLineNumbersEffects(node) : undefined;
|
|
341
362
|
const prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
|
|
342
|
-
if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
|
|
363
|
+
if (changes || wordWrapEffect || lineNumbersEffect || prosemirrorDecorationsEffect) {
|
|
343
364
|
this.updating = true;
|
|
344
365
|
this.cm.dispatch({
|
|
345
|
-
effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(effect => !!effect),
|
|
366
|
+
effects: [wordWrapEffect, lineNumbersEffect, prosemirrorDecorationsEffect].filter(effect => !!effect),
|
|
346
367
|
changes
|
|
347
368
|
});
|
|
348
369
|
this.updating = false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { codeBlock, codeBlockWithExtendedAttributes, codeBlockWithLocalId } from '@atlaskit/adf-schema';
|
|
2
|
+
import { areCodeBlockLineNumbersHidden } from '@atlaskit/editor-common/code-block';
|
|
2
3
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
3
4
|
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
4
5
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -12,6 +13,51 @@ const codeBlockClassNames = {
|
|
|
12
13
|
};
|
|
13
14
|
const MATCH_NEWLINES = new RegExp('\n', 'gu');
|
|
14
15
|
const getFontSize = () => expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ? '0.875em' : '0.875rem';
|
|
16
|
+
const getGutterBaseStyle = () => ({
|
|
17
|
+
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
18
|
+
position: 'relative',
|
|
19
|
+
flexShrink: 0,
|
|
20
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
21
|
+
fontSize: getFontSize(),
|
|
22
|
+
boxSizing: 'content-box'
|
|
23
|
+
});
|
|
24
|
+
const getGutterPadding = allowCodeFolding => allowCodeFolding ? `${"var(--ds-space-100, 8px)"} ${"var(--ds-space-250, 20px)"} ${"var(--ds-space-100, 8px)"} ${"var(--ds-space-075, 6px)"}` : "var(--ds-space-100, 8px)";
|
|
25
|
+
const getGuttersWithLineNumbers = (content, config) => ['div', {
|
|
26
|
+
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
27
|
+
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
28
|
+
style: convertToInlineCss({
|
|
29
|
+
...getGutterBaseStyle(),
|
|
30
|
+
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
31
|
+
/* top and bottom | left and right */
|
|
32
|
+
padding: getGutterPadding(config.allowCodeFolding)
|
|
33
|
+
}),
|
|
34
|
+
contenteditable: 'false'
|
|
35
|
+
}, ['div', {
|
|
36
|
+
class: 'code-block-gutter-pseudo-element',
|
|
37
|
+
style: convertToInlineCss({
|
|
38
|
+
textAlign: 'right',
|
|
39
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
40
|
+
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
41
|
+
whiteSpace: 'pre-wrap'
|
|
42
|
+
}),
|
|
43
|
+
'data-label': content
|
|
44
|
+
}]];
|
|
45
|
+
const getFoldOnlyGutter = () => ['div', {
|
|
46
|
+
style: convertToInlineCss({
|
|
47
|
+
...getGutterBaseStyle(),
|
|
48
|
+
padding: `${"var(--ds-space-100, 8px)"} ${"var(--ds-space-150, 12px)"} ${"var(--ds-space-100, 8px)"} ${"var(--ds-space-100, 8px)"}`
|
|
49
|
+
}),
|
|
50
|
+
contenteditable: 'false'
|
|
51
|
+
}];
|
|
52
|
+
const getGutters = (content, config, hideLineNumbers) => {
|
|
53
|
+
if (!hideLineNumbers) {
|
|
54
|
+
return [getGuttersWithLineNumbers(content, config)];
|
|
55
|
+
}
|
|
56
|
+
if (config.allowCodeFolding) {
|
|
57
|
+
return [getFoldOnlyGutter()];
|
|
58
|
+
}
|
|
59
|
+
return [];
|
|
60
|
+
};
|
|
15
61
|
|
|
16
62
|
// Based on: `packages/editor/editor-plugin-code-block/src/nodeviews/code-block.ts`
|
|
17
63
|
const toDOM = (node, formattedAriaLabel, config) => {
|
|
@@ -22,44 +68,26 @@ const toDOM = (node, formattedAriaLabel, config) => {
|
|
|
22
68
|
totalLineCount += (node.text.match(MATCH_NEWLINES) || []).length;
|
|
23
69
|
}
|
|
24
70
|
});
|
|
71
|
+
const hideLineNumbers = areCodeBlockLineNumbersHidden(node);
|
|
25
72
|
const maxDigits = totalLineCount.toString().length;
|
|
26
73
|
const content = node.textContent.split('\n').map((_, i) => i + 1).join('\n');
|
|
74
|
+
const gutters = getGutters(content, config, hideLineNumbers);
|
|
27
75
|
return ['pre', {
|
|
28
76
|
class: codeBlockClassNames.container,
|
|
29
77
|
style: `--lineNumberGutterWidth:${maxDigits}ch;`,
|
|
30
78
|
'data-language': node.attrs.language || '',
|
|
31
79
|
...(expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
32
|
-
'data-wrap': node.attrs.wrap ? 'true' : 'false'
|
|
80
|
+
'data-wrap': node.attrs.wrap ? 'true' : 'false',
|
|
81
|
+
...(hideLineNumbers && {
|
|
82
|
+
'data-hide-line-numbers': 'true'
|
|
83
|
+
})
|
|
33
84
|
})
|
|
34
85
|
}, ['div', {
|
|
35
86
|
class: codeBlockClassNames.start,
|
|
36
87
|
contenteditable: 'false'
|
|
37
88
|
}], ['div', {
|
|
38
89
|
class: codeBlockClassNames.contentWrapper
|
|
39
|
-
}, ['div', {
|
|
40
|
-
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
41
|
-
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
42
|
-
style: convertToInlineCss({
|
|
43
|
-
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
44
|
-
position: 'relative',
|
|
45
|
-
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
46
|
-
/* top and bottom | left and right */
|
|
47
|
-
padding: config.allowCodeFolding ? `${"var(--ds-space-100, 8px)"} ${"var(--ds-space-250, 20px)"} ${"var(--ds-space-100, 8px)"} ${"var(--ds-space-075, 6px)"}` : "var(--ds-space-100, 8px)",
|
|
48
|
-
flexShrink: 0,
|
|
49
|
-
fontSize: getFontSize(),
|
|
50
|
-
boxSizing: 'content-box'
|
|
51
|
-
}),
|
|
52
|
-
contenteditable: 'false'
|
|
53
|
-
}, ['div', {
|
|
54
|
-
class: 'code-block-gutter-pseudo-element',
|
|
55
|
-
style: convertToInlineCss({
|
|
56
|
-
textAlign: 'right',
|
|
57
|
-
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
58
|
-
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
59
|
-
whiteSpace: 'pre-wrap'
|
|
60
|
-
}),
|
|
61
|
-
'data-label': content
|
|
62
|
-
}]], ['div', {
|
|
90
|
+
}, ...gutters, ['div', {
|
|
63
91
|
class: codeBlockClassNames.content
|
|
64
92
|
}, ['code', {
|
|
65
93
|
'data-language': node.attrs.language || '',
|
package/dist/es2019/ui/theme.js
CHANGED
|
@@ -56,7 +56,14 @@ export const cmTheme = options => CodeMirror.theme({
|
|
|
56
56
|
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
57
57
|
border: 'none',
|
|
58
58
|
padding: "var(--ds-space-0, 0px)",
|
|
59
|
-
color: "var(--ds-text-subtlest, #6B6E76)"
|
|
59
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
60
|
+
...(expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
61
|
+
// CodeMirror defaults this to height: 100%, which can resolve against an indefinite
|
|
62
|
+
// parent height in content-height editor and prevent flex stretching when gutter
|
|
63
|
+
// content is sparse, such as fold-only gutters.
|
|
64
|
+
height: 'unset',
|
|
65
|
+
alignSelf: 'stretch'
|
|
66
|
+
})
|
|
60
67
|
},
|
|
61
68
|
'.cm-lineNumbers .cm-gutterElement': {
|
|
62
69
|
paddingLeft: "var(--ds-space-0, 0px)",
|
|
@@ -12,7 +12,7 @@ import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
|
|
|
12
12
|
import { Compartment, Facet, EditorState as CodeMirrorState } from '@codemirror/state';
|
|
13
13
|
import { EditorView as CodeMirror, lineNumbers, gutters } from '@codemirror/view';
|
|
14
14
|
import { getBrowserInfo } from '@atlaskit/editor-common/browser';
|
|
15
|
-
import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
15
|
+
import { areCodeBlockLineNumbersHidden, isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
16
16
|
import { messages as floatingToolbarMessages } from '@atlaskit/editor-common/floating-toolbar';
|
|
17
17
|
import { blockTypeMessages, codeBlockMessages, roleDescriptionMessages } from '@atlaskit/editor-common/messages';
|
|
18
18
|
import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
|
|
@@ -40,14 +40,15 @@ var codeBlockHeights = new WeakMap();
|
|
|
40
40
|
// Based on: https://prosemirror.net/examples/codemirror/
|
|
41
41
|
var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
42
42
|
function CodeBlockAdvancedNodeView(node, view, getPos, innerDecorations, config) {
|
|
43
|
-
var
|
|
43
|
+
var _this = this,
|
|
44
|
+
_config$api,
|
|
44
45
|
_contentFormatSharedS,
|
|
45
46
|
_config$api2,
|
|
46
|
-
_this = this,
|
|
47
47
|
_config$api3,
|
|
48
48
|
_config$api4;
|
|
49
49
|
_classCallCheck(this, CodeBlockAdvancedNodeView);
|
|
50
50
|
_defineProperty(this, "lineWrappingCompartment", new Compartment());
|
|
51
|
+
_defineProperty(this, "lineNumbersCompartment", new Compartment());
|
|
51
52
|
_defineProperty(this, "languageCompartment", new Compartment());
|
|
52
53
|
_defineProperty(this, "readOnlyCompartment", new Compartment());
|
|
53
54
|
_defineProperty(this, "pmDecorationsCompartment", new Compartment());
|
|
@@ -55,6 +56,11 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
55
56
|
_defineProperty(this, "maybeTryingToReachNodeSelection", false);
|
|
56
57
|
_defineProperty(this, "pmFacet", Facet.define());
|
|
57
58
|
_defineProperty(this, "wordWrappingEnabled", false);
|
|
59
|
+
_defineProperty(this, "lineNumbersHidden", false);
|
|
60
|
+
_defineProperty(this, "selectCodeBlockNodeAndFocus", function () {
|
|
61
|
+
_this.selectCodeBlockNode(undefined);
|
|
62
|
+
_this.view.focus();
|
|
63
|
+
});
|
|
58
64
|
this.config = config;
|
|
59
65
|
this.node = node;
|
|
60
66
|
this.view = view;
|
|
@@ -81,10 +87,6 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
81
87
|
var _config$getIntl = config.getIntl(),
|
|
82
88
|
formatMessage = _config$getIntl.formatMessage;
|
|
83
89
|
var formattedAriaLabel = formatMessage(blockTypeMessages.codeblock);
|
|
84
|
-
var selectNode = function selectNode() {
|
|
85
|
-
_this.selectCodeBlockNode(undefined);
|
|
86
|
-
_this.view.focus();
|
|
87
|
-
};
|
|
88
90
|
var isMacOS = getBrowserInfo().mac;
|
|
89
91
|
this.cm = new CodeMirror({
|
|
90
92
|
doc: this.node.textContent,
|
|
@@ -101,16 +103,9 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
101
103
|
// Goes before cmTheme to override styles
|
|
102
104
|
config.allowCodeFolding ? [codeFoldingTheme] : [], this.themeCompartment.of(cmTheme({
|
|
103
105
|
contentMode: expValEquals('confluence_compact_text_format', 'isEnabled', true) ? this.contentMode : undefined
|
|
104
|
-
})), syntaxHighlighting(highlightStyle), bracketMatching(),
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
selectNode();
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}),
|
|
112
|
-
// Explicitly disable "sticky" positioning on line numbers to match
|
|
113
|
-
// Renderer behaviour
|
|
106
|
+
})), syntaxHighlighting(highlightStyle), bracketMatching(), expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? this.lineNumbersCompartment.of(this.getLineNumberVisibilityExtensions(node)) : this.getLineNumberExtensions(),
|
|
107
|
+
// Explicitly disable "sticky" positioning on all gutters to match
|
|
108
|
+
// Renderer behaviour.
|
|
114
109
|
gutters({
|
|
115
110
|
fixed: false
|
|
116
111
|
}), CodeMirror.updateListener.of(function (update) {
|
|
@@ -133,7 +128,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
133
128
|
'aria-label': formattedAriaLabel,
|
|
134
129
|
'aria-describedby': "codesnippet-".concat(this.node.attrs.localId)
|
|
135
130
|
})), config.allowCodeFolding ? [foldGutterExtension({
|
|
136
|
-
selectNode:
|
|
131
|
+
selectNode: this.selectCodeBlockNodeAndFocus,
|
|
137
132
|
getNode: function getNode() {
|
|
138
133
|
return _this.node;
|
|
139
134
|
}
|
|
@@ -215,6 +210,7 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
215
210
|
this.updateLanguage();
|
|
216
211
|
this.updateLocalIdAttribute();
|
|
217
212
|
this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
|
|
213
|
+
this.lineNumbersHidden = areCodeBlockLineNumbersHidden(node);
|
|
218
214
|
|
|
219
215
|
// Restore fold state after initialization
|
|
220
216
|
if (config.allowCodeFolding) {
|
|
@@ -329,6 +325,37 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
329
325
|
this.view.dispatch(tr);
|
|
330
326
|
}
|
|
331
327
|
}
|
|
328
|
+
}, {
|
|
329
|
+
key: "getLineNumberExtensions",
|
|
330
|
+
value: function getLineNumberExtensions() {
|
|
331
|
+
var _this2 = this;
|
|
332
|
+
return [lineNumbers({
|
|
333
|
+
domEventHandlers: {
|
|
334
|
+
click: function click() {
|
|
335
|
+
_this2.selectCodeBlockNodeAndFocus();
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
})];
|
|
340
|
+
}
|
|
341
|
+
}, {
|
|
342
|
+
key: "getLineNumberVisibilityExtensions",
|
|
343
|
+
value: function getLineNumberVisibilityExtensions(node) {
|
|
344
|
+
if (areCodeBlockLineNumbersHidden(node)) {
|
|
345
|
+
return [];
|
|
346
|
+
}
|
|
347
|
+
return this.getLineNumberExtensions();
|
|
348
|
+
}
|
|
349
|
+
}, {
|
|
350
|
+
key: "getLineNumbersEffects",
|
|
351
|
+
value: function getLineNumbersEffects(node) {
|
|
352
|
+
var lineNumbersHidden = areCodeBlockLineNumbersHidden(node);
|
|
353
|
+
if (this.lineNumbersHidden !== lineNumbersHidden) {
|
|
354
|
+
this.lineNumbersHidden = lineNumbersHidden;
|
|
355
|
+
return this.lineNumbersCompartment.reconfigure(this.getLineNumberVisibilityExtensions(node));
|
|
356
|
+
}
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
332
359
|
}, {
|
|
333
360
|
key: "getWordWrapEffects",
|
|
334
361
|
value: function getWordWrapEffects(node) {
|
|
@@ -387,11 +414,12 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
387
414
|
// Updates bundled for performance (to avoid multiple-dispatches)
|
|
388
415
|
var changes = getCMSelectionChanges(curText, newText);
|
|
389
416
|
var wordWrapEffect = this.getWordWrapEffects(node);
|
|
417
|
+
var lineNumbersEffect = expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? this.getLineNumbersEffects(node) : undefined;
|
|
390
418
|
var prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
|
|
391
|
-
if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
|
|
419
|
+
if (changes || wordWrapEffect || lineNumbersEffect || prosemirrorDecorationsEffect) {
|
|
392
420
|
this.updating = true;
|
|
393
421
|
this.cm.dispatch({
|
|
394
|
-
effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(function (effect) {
|
|
422
|
+
effects: [wordWrapEffect, lineNumbersEffect, prosemirrorDecorationsEffect].filter(function (effect) {
|
|
395
423
|
return !!effect;
|
|
396
424
|
}),
|
|
397
425
|
changes: changes
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
1
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
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; }
|
|
4
5
|
import { codeBlock, codeBlockWithExtendedAttributes, codeBlockWithLocalId } from '@atlaskit/adf-schema';
|
|
6
|
+
import { areCodeBlockLineNumbersHidden } from '@atlaskit/editor-common/code-block';
|
|
5
7
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
6
8
|
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
7
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -17,6 +19,57 @@ var MATCH_NEWLINES = new RegExp('\n', 'gu');
|
|
|
17
19
|
var getFontSize = function getFontSize() {
|
|
18
20
|
return expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ? '0.875em' : '0.875rem';
|
|
19
21
|
};
|
|
22
|
+
var getGutterBaseStyle = function getGutterBaseStyle() {
|
|
23
|
+
return {
|
|
24
|
+
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
25
|
+
position: 'relative',
|
|
26
|
+
flexShrink: 0,
|
|
27
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
28
|
+
fontSize: getFontSize(),
|
|
29
|
+
boxSizing: 'content-box'
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
var getGutterPadding = function getGutterPadding(allowCodeFolding) {
|
|
33
|
+
return allowCodeFolding ? "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-250, 20px)", " ", "var(--ds-space-100, 8px)", " ", "var(--ds-space-075, 6px)") : "var(--ds-space-100, 8px)";
|
|
34
|
+
};
|
|
35
|
+
var getGuttersWithLineNumbers = function getGuttersWithLineNumbers(content, config) {
|
|
36
|
+
return ['div', {
|
|
37
|
+
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
38
|
+
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
39
|
+
style: convertToInlineCss(_objectSpread(_objectSpread({}, getGutterBaseStyle()), {}, {
|
|
40
|
+
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
41
|
+
/* top and bottom | left and right */
|
|
42
|
+
padding: getGutterPadding(config.allowCodeFolding)
|
|
43
|
+
})),
|
|
44
|
+
contenteditable: 'false'
|
|
45
|
+
}, ['div', {
|
|
46
|
+
class: 'code-block-gutter-pseudo-element',
|
|
47
|
+
style: convertToInlineCss({
|
|
48
|
+
textAlign: 'right',
|
|
49
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
50
|
+
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
51
|
+
whiteSpace: 'pre-wrap'
|
|
52
|
+
}),
|
|
53
|
+
'data-label': content
|
|
54
|
+
}]];
|
|
55
|
+
};
|
|
56
|
+
var getFoldOnlyGutter = function getFoldOnlyGutter() {
|
|
57
|
+
return ['div', {
|
|
58
|
+
style: convertToInlineCss(_objectSpread(_objectSpread({}, getGutterBaseStyle()), {}, {
|
|
59
|
+
padding: "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-150, 12px)", " ", "var(--ds-space-100, 8px)", " ", "var(--ds-space-100, 8px)")
|
|
60
|
+
})),
|
|
61
|
+
contenteditable: 'false'
|
|
62
|
+
}];
|
|
63
|
+
};
|
|
64
|
+
var getGutters = function getGutters(content, config, hideLineNumbers) {
|
|
65
|
+
if (!hideLineNumbers) {
|
|
66
|
+
return [getGuttersWithLineNumbers(content, config)];
|
|
67
|
+
}
|
|
68
|
+
if (config.allowCodeFolding) {
|
|
69
|
+
return [getFoldOnlyGutter()];
|
|
70
|
+
}
|
|
71
|
+
return [];
|
|
72
|
+
};
|
|
20
73
|
|
|
21
74
|
// Based on: `packages/editor/editor-plugin-code-block/src/nodeviews/code-block.ts`
|
|
22
75
|
var _toDOM = function toDOM(node, formattedAriaLabel, config) {
|
|
@@ -27,45 +80,26 @@ var _toDOM = function toDOM(node, formattedAriaLabel, config) {
|
|
|
27
80
|
totalLineCount += (node.text.match(MATCH_NEWLINES) || []).length;
|
|
28
81
|
}
|
|
29
82
|
});
|
|
83
|
+
var hideLineNumbers = areCodeBlockLineNumbersHidden(node);
|
|
30
84
|
var maxDigits = totalLineCount.toString().length;
|
|
31
85
|
var content = node.textContent.split('\n').map(function (_, i) {
|
|
32
86
|
return i + 1;
|
|
33
87
|
}).join('\n');
|
|
88
|
+
var gutters = getGutters(content, config, hideLineNumbers);
|
|
34
89
|
return ['pre', _objectSpread({
|
|
35
90
|
class: codeBlockClassNames.container,
|
|
36
91
|
style: "--lineNumberGutterWidth:".concat(maxDigits, "ch;"),
|
|
37
92
|
'data-language': node.attrs.language || ''
|
|
38
|
-
}, expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
93
|
+
}, expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && _objectSpread({
|
|
39
94
|
'data-wrap': node.attrs.wrap ? 'true' : 'false'
|
|
40
|
-
}
|
|
95
|
+
}, hideLineNumbers && {
|
|
96
|
+
'data-hide-line-numbers': 'true'
|
|
97
|
+
})), ['div', {
|
|
41
98
|
class: codeBlockClassNames.start,
|
|
42
99
|
contenteditable: 'false'
|
|
43
100
|
}], ['div', {
|
|
44
101
|
class: codeBlockClassNames.contentWrapper
|
|
45
|
-
}, ['div', {
|
|
46
|
-
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
47
|
-
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
48
|
-
style: convertToInlineCss({
|
|
49
|
-
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
50
|
-
position: 'relative',
|
|
51
|
-
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
52
|
-
/* top and bottom | left and right */
|
|
53
|
-
padding: config.allowCodeFolding ? "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-250, 20px)", " ", "var(--ds-space-100, 8px)", " ", "var(--ds-space-075, 6px)") : "var(--ds-space-100, 8px)",
|
|
54
|
-
flexShrink: 0,
|
|
55
|
-
fontSize: getFontSize(),
|
|
56
|
-
boxSizing: 'content-box'
|
|
57
|
-
}),
|
|
58
|
-
contenteditable: 'false'
|
|
59
|
-
}, ['div', {
|
|
60
|
-
class: 'code-block-gutter-pseudo-element',
|
|
61
|
-
style: convertToInlineCss({
|
|
62
|
-
textAlign: 'right',
|
|
63
|
-
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
64
|
-
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
65
|
-
whiteSpace: 'pre-wrap'
|
|
66
|
-
}),
|
|
67
|
-
'data-label': content
|
|
68
|
-
}]], ['div', {
|
|
102
|
+
}].concat(_toConsumableArray(gutters), [['div', {
|
|
69
103
|
class: codeBlockClassNames.content
|
|
70
104
|
}, ['code', _objectSpread({
|
|
71
105
|
'data-language': node.attrs.language || '',
|
|
@@ -74,7 +108,7 @@ var _toDOM = function toDOM(node, formattedAriaLabel, config) {
|
|
|
74
108
|
'aria-label': formattedAriaLabel
|
|
75
109
|
}, fg('platform_editor_adf_with_localid') && {
|
|
76
110
|
'data-local-id': node.attrs.localId
|
|
77
|
-
}), 0]]], ['div', {
|
|
111
|
+
}), 0]]]), ['div', {
|
|
78
112
|
class: codeBlockClassNames.end,
|
|
79
113
|
contenteditable: 'false'
|
|
80
114
|
}]];
|
package/dist/esm/ui/theme.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
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
|
+
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; }
|
|
1
4
|
import { EditorView as CodeMirror } from '@codemirror/view';
|
|
2
5
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
6
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
@@ -59,12 +62,18 @@ export var cmTheme = function cmTheme(options) {
|
|
|
59
62
|
'.cm-gutter': {
|
|
60
63
|
padding: "var(--ds-space-100, 8px)"
|
|
61
64
|
},
|
|
62
|
-
'.cm-gutters': {
|
|
65
|
+
'.cm-gutters': _objectSpread({
|
|
63
66
|
backgroundColor: "var(--ds-background-neutral, #0515240F)",
|
|
64
67
|
border: 'none',
|
|
65
68
|
padding: "var(--ds-space-0, 0px)",
|
|
66
69
|
color: "var(--ds-text-subtlest, #6B6E76)"
|
|
67
|
-
},
|
|
70
|
+
}, expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
71
|
+
// CodeMirror defaults this to height: 100%, which can resolve against an indefinite
|
|
72
|
+
// parent height in content-height editor and prevent flex stretching when gutter
|
|
73
|
+
// content is sparse, such as fold-only gutters.
|
|
74
|
+
height: 'unset',
|
|
75
|
+
alignSelf: 'stretch'
|
|
76
|
+
}),
|
|
68
77
|
'.cm-lineNumbers .cm-gutterElement': {
|
|
69
78
|
paddingLeft: "var(--ds-space-0, 0px)",
|
|
70
79
|
paddingRight: "var(--ds-space-0, 0px)",
|
|
@@ -16,6 +16,7 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
16
16
|
private updating;
|
|
17
17
|
private view;
|
|
18
18
|
private lineWrappingCompartment;
|
|
19
|
+
private lineNumbersCompartment;
|
|
19
20
|
private languageCompartment;
|
|
20
21
|
private readOnlyCompartment;
|
|
21
22
|
private pmDecorationsCompartment;
|
|
@@ -43,6 +44,11 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
43
44
|
private updateLocalIdAttribute;
|
|
44
45
|
private selectCodeBlockNode;
|
|
45
46
|
private wordWrappingEnabled;
|
|
47
|
+
private lineNumbersHidden;
|
|
48
|
+
private selectCodeBlockNodeAndFocus;
|
|
49
|
+
private getLineNumberExtensions;
|
|
50
|
+
private getLineNumberVisibilityExtensions;
|
|
51
|
+
private getLineNumbersEffects;
|
|
46
52
|
private getWordWrapEffects;
|
|
47
53
|
private restoreFoldState;
|
|
48
54
|
private applyContentModeTheme;
|
|
@@ -16,6 +16,7 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
16
16
|
private updating;
|
|
17
17
|
private view;
|
|
18
18
|
private lineWrappingCompartment;
|
|
19
|
+
private lineNumbersCompartment;
|
|
19
20
|
private languageCompartment;
|
|
20
21
|
private readOnlyCompartment;
|
|
21
22
|
private pmDecorationsCompartment;
|
|
@@ -43,6 +44,11 @@ declare class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
43
44
|
private updateLocalIdAttribute;
|
|
44
45
|
private selectCodeBlockNode;
|
|
45
46
|
private wordWrappingEnabled;
|
|
47
|
+
private lineNumbersHidden;
|
|
48
|
+
private selectCodeBlockNodeAndFocus;
|
|
49
|
+
private getLineNumberExtensions;
|
|
50
|
+
private getLineNumberVisibilityExtensions;
|
|
51
|
+
private getLineNumbersEffects;
|
|
46
52
|
private getWordWrapEffects;
|
|
47
53
|
private restoreFoldState;
|
|
48
54
|
private applyContentModeTheme;
|
package/docs/0-intro.tsx
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-code-block-advanced",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.2",
|
|
4
4
|
"description": "CodeBlockAdvanced plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
39
39
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
40
40
|
"@atlaskit/prosemirror-history": "^0.2.0",
|
|
41
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
41
|
+
"@atlaskit/tmp-editor-statsig": "^81.0.0",
|
|
42
42
|
"@atlaskit/tokens": "^13.0.0",
|
|
43
43
|
"@babel/runtime": "^7.0.0",
|
|
44
44
|
"@codemirror/autocomplete": "6.18.4",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"codemirror-lang-elixir": "4.0.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@atlaskit/editor-common": "^114.
|
|
58
|
+
"@atlaskit/editor-common": "^114.32.0",
|
|
59
59
|
"react": "^18.2.0",
|
|
60
60
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
61
61
|
},
|
|
@@ -7,7 +7,10 @@ import type { ViewUpdate } from '@codemirror/view';
|
|
|
7
7
|
import type { IntlShape } from 'react-intl';
|
|
8
8
|
|
|
9
9
|
import { getBrowserInfo } from '@atlaskit/editor-common/browser';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
areCodeBlockLineNumbersHidden,
|
|
12
|
+
isCodeBlockWordWrapEnabled,
|
|
13
|
+
} from '@atlaskit/editor-common/code-block';
|
|
11
14
|
import { messages as floatingToolbarMessages } from '@atlaskit/editor-common/floating-toolbar';
|
|
12
15
|
import {
|
|
13
16
|
blockTypeMessages,
|
|
@@ -68,6 +71,7 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
68
71
|
private updating: boolean;
|
|
69
72
|
private view: EditorView;
|
|
70
73
|
private lineWrappingCompartment = new Compartment();
|
|
74
|
+
private lineNumbersCompartment = new Compartment();
|
|
71
75
|
private languageCompartment = new Compartment();
|
|
72
76
|
private readOnlyCompartment = new Compartment();
|
|
73
77
|
private pmDecorationsCompartment = new Compartment();
|
|
@@ -126,11 +130,6 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
126
130
|
const { formatMessage } = config.getIntl();
|
|
127
131
|
const formattedAriaLabel = formatMessage(blockTypeMessages.codeblock);
|
|
128
132
|
|
|
129
|
-
const selectNode = () => {
|
|
130
|
-
this.selectCodeBlockNode(undefined);
|
|
131
|
-
this.view.focus();
|
|
132
|
-
};
|
|
133
|
-
|
|
134
133
|
const isMacOS = getBrowserInfo().mac;
|
|
135
134
|
|
|
136
135
|
this.cm = new CodeMirror({
|
|
@@ -161,16 +160,11 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
161
160
|
),
|
|
162
161
|
syntaxHighlighting(highlightStyle),
|
|
163
162
|
bracketMatching(),
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
}),
|
|
172
|
-
// Explicitly disable "sticky" positioning on line numbers to match
|
|
173
|
-
// Renderer behaviour
|
|
163
|
+
expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true)
|
|
164
|
+
? this.lineNumbersCompartment.of(this.getLineNumberVisibilityExtensions(node))
|
|
165
|
+
: this.getLineNumberExtensions(),
|
|
166
|
+
// Explicitly disable "sticky" positioning on all gutters to match
|
|
167
|
+
// Renderer behaviour.
|
|
174
168
|
gutters({ fixed: false }),
|
|
175
169
|
CodeMirror.updateListener.of((update) => this.forwardUpdate(update)),
|
|
176
170
|
this.readOnlyCompartment.of([
|
|
@@ -207,7 +201,12 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
207
201
|
}),
|
|
208
202
|
}),
|
|
209
203
|
config.allowCodeFolding
|
|
210
|
-
? [
|
|
204
|
+
? [
|
|
205
|
+
foldGutterExtension({
|
|
206
|
+
selectNode: this.selectCodeBlockNodeAndFocus,
|
|
207
|
+
getNode: () => this.node,
|
|
208
|
+
}),
|
|
209
|
+
]
|
|
211
210
|
: [],
|
|
212
211
|
// With platform_editor_fix_advanced_codeblocks_crlf_patch the lineSeparatorExtension is not needed
|
|
213
212
|
expValEquals('platform_editor_fix_advanced_codeblocks_crlf_patch', 'isEnabled', true)
|
|
@@ -293,6 +292,7 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
293
292
|
this.updateLanguage();
|
|
294
293
|
this.updateLocalIdAttribute();
|
|
295
294
|
this.wordWrappingEnabled = isCodeBlockWordWrapEnabled(node);
|
|
295
|
+
this.lineNumbersHidden = areCodeBlockLineNumbersHidden(node);
|
|
296
296
|
|
|
297
297
|
// Restore fold state after initialization
|
|
298
298
|
if (config.allowCodeFolding) {
|
|
@@ -405,6 +405,44 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
405
405
|
}
|
|
406
406
|
|
|
407
407
|
private wordWrappingEnabled = false;
|
|
408
|
+
private lineNumbersHidden = false;
|
|
409
|
+
|
|
410
|
+
private selectCodeBlockNodeAndFocus = () => {
|
|
411
|
+
this.selectCodeBlockNode(undefined);
|
|
412
|
+
this.view.focus();
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
private getLineNumberExtensions(): Extension[] {
|
|
416
|
+
return [
|
|
417
|
+
lineNumbers({
|
|
418
|
+
domEventHandlers: {
|
|
419
|
+
click: () => {
|
|
420
|
+
this.selectCodeBlockNodeAndFocus();
|
|
421
|
+
return true;
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
}),
|
|
425
|
+
];
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
private getLineNumberVisibilityExtensions(node: PMNode): Extension[] {
|
|
429
|
+
if (areCodeBlockLineNumbersHidden(node)) {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return this.getLineNumberExtensions();
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
private getLineNumbersEffects(node: PMNode) {
|
|
437
|
+
const lineNumbersHidden = areCodeBlockLineNumbersHidden(node);
|
|
438
|
+
if (this.lineNumbersHidden !== lineNumbersHidden) {
|
|
439
|
+
this.lineNumbersHidden = lineNumbersHidden;
|
|
440
|
+
return this.lineNumbersCompartment.reconfigure(
|
|
441
|
+
this.getLineNumberVisibilityExtensions(node),
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
408
446
|
|
|
409
447
|
private getWordWrapEffects(node: PMNode) {
|
|
410
448
|
if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
|
|
@@ -455,11 +493,18 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
455
493
|
// Updates bundled for performance (to avoid multiple-dispatches)
|
|
456
494
|
const changes = getCMSelectionChanges(curText, newText);
|
|
457
495
|
const wordWrapEffect = this.getWordWrapEffects(node);
|
|
496
|
+
const lineNumbersEffect = expValEquals(
|
|
497
|
+
'platform_editor_code_block_q4_lovability',
|
|
498
|
+
'isEnabled',
|
|
499
|
+
true,
|
|
500
|
+
)
|
|
501
|
+
? this.getLineNumbersEffects(node)
|
|
502
|
+
: undefined;
|
|
458
503
|
const prosemirrorDecorationsEffect = this.getProseMirrorDecorationEffects(innerDecorations);
|
|
459
|
-
if (changes || wordWrapEffect || prosemirrorDecorationsEffect) {
|
|
504
|
+
if (changes || wordWrapEffect || lineNumbersEffect || prosemirrorDecorationsEffect) {
|
|
460
505
|
this.updating = true;
|
|
461
506
|
this.cm.dispatch({
|
|
462
|
-
effects: [wordWrapEffect, prosemirrorDecorationsEffect].filter(
|
|
507
|
+
effects: [wordWrapEffect, lineNumbersEffect, prosemirrorDecorationsEffect].filter(
|
|
463
508
|
(effect): effect is StateEffect<unknown> => !!effect,
|
|
464
509
|
),
|
|
465
510
|
changes,
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
codeBlockWithExtendedAttributes,
|
|
4
4
|
codeBlockWithLocalId,
|
|
5
5
|
} from '@atlaskit/adf-schema';
|
|
6
|
+
import { areCodeBlockLineNumbersHidden } from '@atlaskit/editor-common/code-block';
|
|
6
7
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
7
8
|
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
8
9
|
import type { NodeSpec, DOMOutputSpec, Node } from '@atlaskit/editor-prosemirror/model';
|
|
@@ -31,6 +32,75 @@ const getFontSize = () =>
|
|
|
31
32
|
? '0.875em'
|
|
32
33
|
: '0.875rem';
|
|
33
34
|
|
|
35
|
+
const getGutterBaseStyle = () => ({
|
|
36
|
+
backgroundColor: token('color.background.neutral'),
|
|
37
|
+
position: 'relative',
|
|
38
|
+
flexShrink: 0,
|
|
39
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
40
|
+
fontSize: getFontSize(),
|
|
41
|
+
boxSizing: 'content-box',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const getGutterPadding = (allowCodeFolding: boolean) =>
|
|
45
|
+
allowCodeFolding
|
|
46
|
+
? `${token('space.100')} ${token('space.250')} ${token('space.100')} ${token('space.075')}`
|
|
47
|
+
: token('space.100');
|
|
48
|
+
|
|
49
|
+
const getGuttersWithLineNumbers = (content: string, config: Config): DOMOutputSpec => [
|
|
50
|
+
'div',
|
|
51
|
+
{
|
|
52
|
+
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
53
|
+
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
54
|
+
style: convertToInlineCss({
|
|
55
|
+
...getGutterBaseStyle(),
|
|
56
|
+
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
57
|
+
/* top and bottom | left and right */
|
|
58
|
+
padding: getGutterPadding(config.allowCodeFolding),
|
|
59
|
+
}),
|
|
60
|
+
contenteditable: 'false',
|
|
61
|
+
},
|
|
62
|
+
[
|
|
63
|
+
'div',
|
|
64
|
+
{
|
|
65
|
+
class: 'code-block-gutter-pseudo-element',
|
|
66
|
+
style: convertToInlineCss({
|
|
67
|
+
textAlign: 'right',
|
|
68
|
+
color: token('color.text.subtlest'),
|
|
69
|
+
fontFamily: token('font.family.code'),
|
|
70
|
+
whiteSpace: 'pre-wrap',
|
|
71
|
+
}),
|
|
72
|
+
'data-label': content,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
const getFoldOnlyGutter = (): DOMOutputSpec => [
|
|
78
|
+
'div',
|
|
79
|
+
{
|
|
80
|
+
style: convertToInlineCss({
|
|
81
|
+
...getGutterBaseStyle(),
|
|
82
|
+
padding: `${token('space.100')} ${token('space.150')} ${token('space.100')} ${token('space.100')}`,
|
|
83
|
+
}),
|
|
84
|
+
contenteditable: 'false',
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const getGutters = (
|
|
89
|
+
content: string,
|
|
90
|
+
config: Config,
|
|
91
|
+
hideLineNumbers: boolean,
|
|
92
|
+
): DOMOutputSpec[] => {
|
|
93
|
+
if (!hideLineNumbers) {
|
|
94
|
+
return [getGuttersWithLineNumbers(content, config)];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (config.allowCodeFolding) {
|
|
98
|
+
return [getFoldOnlyGutter()];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return [];
|
|
102
|
+
};
|
|
103
|
+
|
|
34
104
|
// Based on: `packages/editor/editor-plugin-code-block/src/nodeviews/code-block.ts`
|
|
35
105
|
const toDOM = (node: Node, formattedAriaLabel: string, config: Config): DOMOutputSpec => {
|
|
36
106
|
let totalLineCount = 1;
|
|
@@ -42,12 +112,14 @@ const toDOM = (node: Node, formattedAriaLabel: string, config: Config): DOMOutpu
|
|
|
42
112
|
}
|
|
43
113
|
});
|
|
44
114
|
|
|
115
|
+
const hideLineNumbers = areCodeBlockLineNumbersHidden(node);
|
|
45
116
|
const maxDigits = totalLineCount.toString().length;
|
|
46
117
|
|
|
47
118
|
const content = node.textContent
|
|
48
119
|
.split('\n')
|
|
49
120
|
.map((_, i) => i + 1)
|
|
50
121
|
.join('\n');
|
|
122
|
+
const gutters = getGutters(content, config, hideLineNumbers);
|
|
51
123
|
|
|
52
124
|
return [
|
|
53
125
|
'pre',
|
|
@@ -57,6 +129,7 @@ const toDOM = (node: Node, formattedAriaLabel: string, config: Config): DOMOutpu
|
|
|
57
129
|
'data-language': node.attrs.language || '',
|
|
58
130
|
...(expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
59
131
|
'data-wrap': node.attrs.wrap ? 'true' : 'false',
|
|
132
|
+
...(hideLineNumbers && { 'data-hide-line-numbers': 'true' }),
|
|
60
133
|
}),
|
|
61
134
|
},
|
|
62
135
|
['div', { class: codeBlockClassNames.start, contenteditable: 'false' }],
|
|
@@ -65,39 +138,7 @@ const toDOM = (node: Node, formattedAriaLabel: string, config: Config): DOMOutpu
|
|
|
65
138
|
{
|
|
66
139
|
class: codeBlockClassNames.contentWrapper,
|
|
67
140
|
},
|
|
68
|
-
|
|
69
|
-
'div',
|
|
70
|
-
{
|
|
71
|
-
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
72
|
-
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
73
|
-
style: convertToInlineCss({
|
|
74
|
-
backgroundColor: token('color.background.neutral'),
|
|
75
|
-
position: 'relative',
|
|
76
|
-
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
77
|
-
/* top and bottom | left and right */
|
|
78
|
-
padding: config.allowCodeFolding
|
|
79
|
-
? `${token('space.100')} ${token('space.250')} ${token('space.100')} ${token('space.075')}`
|
|
80
|
-
: token('space.100'),
|
|
81
|
-
flexShrink: 0,
|
|
82
|
-
fontSize: getFontSize(),
|
|
83
|
-
boxSizing: 'content-box',
|
|
84
|
-
}),
|
|
85
|
-
contenteditable: 'false',
|
|
86
|
-
},
|
|
87
|
-
[
|
|
88
|
-
'div',
|
|
89
|
-
{
|
|
90
|
-
class: 'code-block-gutter-pseudo-element',
|
|
91
|
-
style: convertToInlineCss({
|
|
92
|
-
textAlign: 'right',
|
|
93
|
-
color: token('color.text.subtlest'),
|
|
94
|
-
fontFamily: token('font.family.code'),
|
|
95
|
-
whiteSpace: 'pre-wrap',
|
|
96
|
-
}),
|
|
97
|
-
'data-label': content,
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
],
|
|
141
|
+
...gutters,
|
|
101
142
|
[
|
|
102
143
|
'div',
|
|
103
144
|
{
|
package/src/ui/theme.ts
CHANGED
|
@@ -75,6 +75,13 @@ export const cmTheme = (options?: ThemeOptions): Extension =>
|
|
|
75
75
|
border: 'none',
|
|
76
76
|
padding: token('space.0'),
|
|
77
77
|
color: token('color.text.subtlest'),
|
|
78
|
+
...(expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && {
|
|
79
|
+
// CodeMirror defaults this to height: 100%, which can resolve against an indefinite
|
|
80
|
+
// parent height in content-height editor and prevent flex stretching when gutter
|
|
81
|
+
// content is sparse, such as fold-only gutters.
|
|
82
|
+
height: 'unset',
|
|
83
|
+
alignSelf: 'stretch',
|
|
84
|
+
}),
|
|
78
85
|
},
|
|
79
86
|
'.cm-lineNumbers .cm-gutterElement': {
|
|
80
87
|
paddingLeft: token('space.0'),
|