@atlaskit/editor-plugin-code-block-advanced 1.0.0 → 1.0.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 +22 -0
- package/afm-jira/tsconfig.json +36 -0
- package/afm-post-office/tsconfig.json +36 -0
- package/dist/cjs/nodeviews/codeBlockAdvanced.js +29 -4
- package/dist/cjs/nodeviews/codeBlockNodeWithToDOMFixed.js +42 -12
- package/dist/cjs/nodeviews/extensions/copyButtonDecorations.js +22 -0
- package/dist/cjs/ui/syntaxHighlightingTheme.js +5 -2
- package/dist/cjs/ui/theme.js +4 -3
- package/dist/es2019/nodeviews/codeBlockAdvanced.js +29 -6
- package/dist/es2019/nodeviews/codeBlockNodeWithToDOMFixed.js +58 -28
- package/dist/es2019/nodeviews/extensions/copyButtonDecorations.js +16 -0
- package/dist/es2019/ui/syntaxHighlightingTheme.js +5 -2
- package/dist/es2019/ui/theme.js +4 -3
- package/dist/esm/nodeviews/codeBlockAdvanced.js +31 -6
- package/dist/esm/nodeviews/codeBlockNodeWithToDOMFixed.js +42 -12
- package/dist/esm/nodeviews/extensions/copyButtonDecorations.js +16 -0
- package/dist/esm/ui/syntaxHighlightingTheme.js +5 -2
- package/dist/esm/ui/theme.js +4 -3
- package/dist/types/nodeviews/codeBlockAdvanced.d.ts +3 -0
- package/dist/types/nodeviews/extensions/copyButtonDecorations.d.ts +1 -0
- package/dist/types-ts4.5/nodeviews/codeBlockAdvanced.d.ts +3 -0
- package/dist/types-ts4.5/nodeviews/extensions/copyButtonDecorations.d.ts +1 -0
- package/package.json +4 -4
- package/src/nodeviews/codeBlockAdvanced.ts +30 -2
- package/src/nodeviews/codeBlockNodeWithToDOMFixed.ts +75 -30
- package/src/nodeviews/extensions/copyButtonDecorations.ts +15 -0
- package/src/nodeviews/lazyCodeBlockAdvanced.ts +0 -1
- package/src/ui/syntaxHighlightingTheme.ts +8 -1
- package/src/ui/theme.ts +2 -1
- package/tsconfig.app.json +53 -0
- package/tsconfig.dev.json +47 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-code-block-advanced
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#105726](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/105726)
|
|
8
|
+
[`2eb0f22c4b065`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2eb0f22c4b065) -
|
|
9
|
+
[ux] Fix toDOM implementation whitespace with 100+ lines of code
|
|
10
|
+
- [#103918](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/103918)
|
|
11
|
+
[`29844093c6ab4`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/29844093c6ab4) -
|
|
12
|
+
Expose new shared state for code block plugin which indicates the current node that the copy text
|
|
13
|
+
button is hovered for. Display highlight decorations for the copy text button in the advanced code
|
|
14
|
+
block plugin.
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
17
|
+
## 1.0.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#102828](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/102828)
|
|
22
|
+
[`e9e0bd7d3c706`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e9e0bd7d3c706) -
|
|
23
|
+
[ux] Ensure lazy node view matches code block advanced snippet so there is no layout shift.
|
|
24
|
+
|
|
3
25
|
## 1.0.0
|
|
4
26
|
|
|
5
27
|
### Major Changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../tsconfig.entry-points.jira.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "es5",
|
|
5
|
+
"outDir": "../../../../../tsDist/@atlaskit__editor-plugin-code-block-advanced/app",
|
|
6
|
+
"rootDir": "../",
|
|
7
|
+
"composite": true
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"../src/**/*.ts",
|
|
11
|
+
"../src/**/*.tsx"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"../src/**/__tests__/*",
|
|
15
|
+
"../src/**/*.test.*",
|
|
16
|
+
"../src/**/test.*",
|
|
17
|
+
"../src/**/examples.*"
|
|
18
|
+
],
|
|
19
|
+
"references": [
|
|
20
|
+
{
|
|
21
|
+
"path": "../../editor-common/afm-jira/tsconfig.json"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "../../editor-plugin-code-block/afm-jira/tsconfig.json"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "../../editor-plugin-editor-disabled/afm-jira/tsconfig.json"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "../../editor-plugin-selection/afm-jira/tsconfig.json"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "../../../design-system/tokens/afm-jira/tsconfig.json"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../tsconfig.entry-points.post-office.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "es5",
|
|
5
|
+
"outDir": "../../../../../post-office/tsDist/@atlaskit__editor-plugin-code-block-advanced/app",
|
|
6
|
+
"rootDir": "../",
|
|
7
|
+
"composite": true
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"../src/**/*.ts",
|
|
11
|
+
"../src/**/*.tsx"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"../src/**/__tests__/*",
|
|
15
|
+
"../src/**/*.test.*",
|
|
16
|
+
"../src/**/test.*",
|
|
17
|
+
"../src/**/examples.*"
|
|
18
|
+
],
|
|
19
|
+
"references": [
|
|
20
|
+
{
|
|
21
|
+
"path": "../../editor-common/afm-post-office/tsconfig.json"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "../../editor-plugin-code-block/afm-post-office/tsconfig.json"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "../../editor-plugin-editor-disabled/afm-post-office/tsconfig.json"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "../../editor-plugin-selection/afm-post-office/tsconfig.json"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "../../../design-system/tokens/afm-post-office/tsconfig.json"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -20,6 +20,7 @@ var _theme = require("../ui/theme");
|
|
|
20
20
|
var _syncCMWithPM = require("./codemirrorSync/syncCMWithPM");
|
|
21
21
|
var _updateCMSelection = require("./codemirrorSync/updateCMSelection");
|
|
22
22
|
var _bidiCharWarning = require("./extensions/bidiCharWarning");
|
|
23
|
+
var _copyButtonDecorations = require("./extensions/copyButtonDecorations");
|
|
23
24
|
var _keymap = require("./extensions/keymap");
|
|
24
25
|
var _loader = require("./languages/loader");
|
|
25
26
|
// Based on: https://prosemirror.net/examples/codemirror/
|
|
@@ -28,11 +29,13 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
28
29
|
function CodeBlockAdvancedNodeView(node, view, getPos, config) {
|
|
29
30
|
var _config$api,
|
|
30
31
|
_this = this,
|
|
31
|
-
_config$api2
|
|
32
|
+
_config$api2,
|
|
33
|
+
_config$api3;
|
|
32
34
|
(0, _classCallCheck2.default)(this, CodeBlockAdvancedNodeView);
|
|
33
35
|
(0, _defineProperty2.default)(this, "lineWrappingCompartment", new _state.Compartment());
|
|
34
36
|
(0, _defineProperty2.default)(this, "languageCompartment", new _state.Compartment());
|
|
35
37
|
(0, _defineProperty2.default)(this, "readOnlyCompartment", new _state.Compartment());
|
|
38
|
+
(0, _defineProperty2.default)(this, "copyDecoCompartment", new _state.Compartment());
|
|
36
39
|
(0, _defineProperty2.default)(this, "maybeTryingToReachNodeSelection", false);
|
|
37
40
|
(0, _defineProperty2.default)(this, "wordWrappingEnabled", false);
|
|
38
41
|
this.node = node;
|
|
@@ -48,6 +51,13 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
48
51
|
this.cleanupDisabledState = (_config$api2 = config.api) === null || _config$api2 === void 0 || (_config$api2 = _config$api2.editorDisabled) === null || _config$api2 === void 0 ? void 0 : _config$api2.sharedState.onChange(function () {
|
|
49
52
|
_this.updateReadonlyState();
|
|
50
53
|
});
|
|
54
|
+
this.cleanupCopyButtonDecoration = (_config$api3 = config.api) === null || _config$api3 === void 0 || (_config$api3 = _config$api3.codeBlock) === null || _config$api3 === void 0 ? void 0 : _config$api3.sharedState.onChange(function (_ref) {
|
|
55
|
+
var nextSharedState = _ref.nextSharedState,
|
|
56
|
+
prevSharedState = _ref.prevSharedState;
|
|
57
|
+
if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode) !== (prevSharedState === null || prevSharedState === void 0 ? void 0 : prevSharedState.copyButtonHoverNode)) {
|
|
58
|
+
_this.addCopyButtonDecoration(nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
51
61
|
this.languageLoader = new _loader.LanguageLoader(function (lang) {
|
|
52
62
|
_this.updating = true;
|
|
53
63
|
_this.cm.dispatch({
|
|
@@ -57,13 +67,18 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
57
67
|
});
|
|
58
68
|
this.cm = new _view.EditorView({
|
|
59
69
|
doc: this.node.textContent,
|
|
60
|
-
extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), (0, _keymap.keymapExtension)({
|
|
70
|
+
extensions: [].concat((0, _toConsumableArray2.default)(config.extensions), [this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.copyDecoCompartment.of([]), (0, _keymap.keymapExtension)({
|
|
61
71
|
view: view,
|
|
62
72
|
getPos: getPos,
|
|
63
73
|
getNode: getNode,
|
|
64
74
|
selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
|
|
65
75
|
onMaybeNodeSelection: onMaybeNodeSelection
|
|
66
|
-
}), _theme.cmTheme, (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0,
|
|
76
|
+
}), _theme.cmTheme, (0, _language.syntaxHighlighting)(_syntaxHighlightingTheme.highlightStyle), (0, _language.bracketMatching)(), (0, _view.lineNumbers)(),
|
|
77
|
+
// Explicitly disable "sticky" positioning on line numbers to match
|
|
78
|
+
// Renderer behaviour
|
|
79
|
+
(0, _view.gutters)({
|
|
80
|
+
fixed: false
|
|
81
|
+
}), _view.EditorView.updateListener.of(function (update) {
|
|
67
82
|
return _this.forwardUpdate(update);
|
|
68
83
|
}), this.readOnlyCompartment.of(_view.EditorView.editable.of(this.view.editable)), (0, _autocomplete.closeBrackets)(), _view.EditorView.editorAttributes.of({
|
|
69
84
|
class: 'code-block'
|
|
@@ -81,8 +96,9 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
81
96
|
return (0, _createClass2.default)(CodeBlockAdvancedNodeView, [{
|
|
82
97
|
key: "destroy",
|
|
83
98
|
value: function destroy() {
|
|
84
|
-
var _this$cleanupDisabled;
|
|
99
|
+
var _this$cleanupDisabled, _this$cleanupCopyButt;
|
|
85
100
|
(_this$cleanupDisabled = this.cleanupDisabledState) === null || _this$cleanupDisabled === void 0 || _this$cleanupDisabled.call(this);
|
|
101
|
+
(_this$cleanupCopyButt = this.cleanupCopyButtonDecoration) === null || _this$cleanupCopyButt === void 0 || _this$cleanupCopyButt.call(this);
|
|
86
102
|
}
|
|
87
103
|
}, {
|
|
88
104
|
key: "forwardUpdate",
|
|
@@ -139,6 +155,15 @@ var CodeBlockAdvancedNodeView = /*#__PURE__*/function () {
|
|
|
139
155
|
this.view.dispatch(tr);
|
|
140
156
|
}
|
|
141
157
|
}
|
|
158
|
+
}, {
|
|
159
|
+
key: "addCopyButtonDecoration",
|
|
160
|
+
value: function addCopyButtonDecoration(node) {
|
|
161
|
+
this.updating = true;
|
|
162
|
+
this.cm.dispatch({
|
|
163
|
+
effects: [this.copyDecoCompartment.reconfigure(node && node === this.node ? _copyButtonDecorations.copyButtonDecorations : [])]
|
|
164
|
+
});
|
|
165
|
+
this.updating = false;
|
|
166
|
+
}
|
|
142
167
|
}, {
|
|
143
168
|
key: "updateWordWrap",
|
|
144
169
|
value: function updateWordWrap(node) {
|
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.codeBlockNodeWithFixedToDOM = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _adfSchema = require("@atlaskit/adf-schema");
|
|
10
|
+
var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
|
|
10
11
|
var _styles = require("@atlaskit/editor-common/styles");
|
|
11
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; }
|
|
12
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; }
|
|
@@ -15,30 +16,59 @@ var codeBlockClassNames = {
|
|
|
15
16
|
start: _styles.CodeBlockSharedCssClassName.CODEBLOCK_START,
|
|
16
17
|
end: _styles.CodeBlockSharedCssClassName.CODEBLOCK_END,
|
|
17
18
|
contentWrapper: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER,
|
|
18
|
-
|
|
19
|
-
gutter: _styles.CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER,
|
|
20
|
-
content: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT,
|
|
21
|
-
lineNumberWidget: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WIDGET
|
|
19
|
+
content: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT
|
|
22
20
|
};
|
|
21
|
+
var MATCH_NEWLINES = new RegExp('\n', 'gu');
|
|
23
22
|
|
|
24
|
-
//
|
|
25
|
-
var _toDOM = function toDOM(node,
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
// Based on: `packages/editor/editor-plugin-code-block/src/nodeviews/code-block.ts`
|
|
24
|
+
var _toDOM = function toDOM(node, formattedAriaLabel) {
|
|
25
|
+
var totalLineCount = 1;
|
|
26
|
+
node.forEach(function (node) {
|
|
27
|
+
var text = node.text;
|
|
28
|
+
if (text) {
|
|
29
|
+
totalLineCount += (node.text.match(MATCH_NEWLINES) || []).length;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
var maxDigits = totalLineCount.toString().length;
|
|
33
|
+
var content = node.textContent.split('\n').map(function (_, i) {
|
|
34
|
+
return i + 1;
|
|
35
|
+
}).join('\n');
|
|
36
|
+
return ['pre', {
|
|
37
|
+
class: codeBlockClassNames.container,
|
|
38
|
+
style: "--lineNumberGutterWidth:".concat(maxDigits, "ch;"),
|
|
39
|
+
'data-language': node.attrs.language || ''
|
|
28
40
|
}, ['div', {
|
|
29
41
|
class: codeBlockClassNames.start,
|
|
30
42
|
contenteditable: 'false'
|
|
31
43
|
}], ['div', {
|
|
32
44
|
class: codeBlockClassNames.contentWrapper
|
|
33
45
|
}, ['div', {
|
|
34
|
-
|
|
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: (0, _lazyNodeView.convertToInlineCss)({
|
|
49
|
+
backgroundColor: "var(--ds-background-neutral, #091E420F)",
|
|
50
|
+
position: 'relative',
|
|
51
|
+
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
52
|
+
padding: "var(--ds-space-100, 8px)",
|
|
53
|
+
flexShrink: 0,
|
|
54
|
+
fontSize: '0.875rem',
|
|
55
|
+
boxSizing: 'content-box'
|
|
56
|
+
}),
|
|
35
57
|
contenteditable: 'false'
|
|
36
|
-
}
|
|
58
|
+
}, ['div', {
|
|
59
|
+
class: 'code-block-gutter-pseudo-element',
|
|
60
|
+
style: (0, _lazyNodeView.convertToInlineCss)({
|
|
61
|
+
textAlign: 'right',
|
|
62
|
+
color: "var(--ds-text-subtlest, #626F86)",
|
|
63
|
+
fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
64
|
+
whiteSpace: 'pre-wrap'
|
|
65
|
+
}),
|
|
66
|
+
'data-label': content
|
|
67
|
+
}]], ['div', {
|
|
37
68
|
class: codeBlockClassNames.content
|
|
38
69
|
}, ['code', {
|
|
39
70
|
'data-language': node.attrs.language || '',
|
|
40
71
|
spellcheck: 'false',
|
|
41
|
-
contenteditable: contentEditable ? 'true' : 'false',
|
|
42
72
|
'data-testid': 'code-block--code',
|
|
43
73
|
'aria-label': formattedAriaLabel
|
|
44
74
|
}, 0]]], ['div', {
|
|
@@ -49,7 +79,7 @@ var _toDOM = function toDOM(node, contentEditable, formattedAriaLabel) {
|
|
|
49
79
|
var codeBlockNodeWithFixedToDOM = exports.codeBlockNodeWithFixedToDOM = function codeBlockNodeWithFixedToDOM() {
|
|
50
80
|
return _objectSpread(_objectSpread({}, _adfSchema.codeBlock), {}, {
|
|
51
81
|
toDOM: function toDOM(node) {
|
|
52
|
-
return _toDOM(node,
|
|
82
|
+
return _toDOM(node, '');
|
|
53
83
|
}
|
|
54
84
|
});
|
|
55
85
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.copyButtonDecorations = void 0;
|
|
7
|
+
var _state = require("@codemirror/state");
|
|
8
|
+
var _view = require("@codemirror/view");
|
|
9
|
+
var copyButtonDecorations = exports.copyButtonDecorations = _view.EditorView.decorations.compute([], function (state) {
|
|
10
|
+
var allTextDecoration = _view.Decoration.mark({
|
|
11
|
+
attributes: {
|
|
12
|
+
class: 'ProseMirror-fake-text-selection'
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
// Create a set of decorations for the entire document
|
|
16
|
+
var builder = new _state.RangeSetBuilder();
|
|
17
|
+
for (var i = 0; i < state.doc.lines; i++) {
|
|
18
|
+
builder.add(state.doc.line(i + 1).from, state.doc.line(i + 1).to, allTextDecoration);
|
|
19
|
+
}
|
|
20
|
+
var decorations = builder.finish();
|
|
21
|
+
return decorations;
|
|
22
|
+
});
|
|
@@ -46,8 +46,11 @@ var highlightStyle = exports.highlightStyle = _language.HighlightStyle.define([{
|
|
|
46
46
|
tag: [_highlight.tags.string, _highlight.tags.deleted],
|
|
47
47
|
color: "var(--ds-text-accent-green, #216E4E)"
|
|
48
48
|
}, {
|
|
49
|
-
tag: [_highlight.tags.
|
|
50
|
-
color: "var(--ds-text, #
|
|
49
|
+
tag: [_highlight.tags.special(_highlight.tags.string)],
|
|
50
|
+
color: "var(--ds-text-accent-green, #216E4E)"
|
|
51
|
+
}, {
|
|
52
|
+
tag: [_highlight.tags.regexp, _highlight.tags.escape],
|
|
53
|
+
color: "var(--ds-text-accent-teal, #206A83)"
|
|
51
54
|
}, {
|
|
52
55
|
tag: _highlight.tags.definition(_highlight.tags.variableName),
|
|
53
56
|
color: "var(--ds-text, #172B4D)"
|
package/dist/cjs/ui/theme.js
CHANGED
|
@@ -11,7 +11,6 @@ var cmTheme = exports.cmTheme = _view.EditorView.theme({
|
|
|
11
11
|
padding: '0',
|
|
12
12
|
marginTop: "var(--ds-space-100, 8px)",
|
|
13
13
|
marginBottom: "var(--ds-space-100, 8px)",
|
|
14
|
-
borderRadius: "var(--ds-border-radius, 4px)",
|
|
15
14
|
fontSize: '0.875rem',
|
|
16
15
|
// Custom syntax styling to match existing styling
|
|
17
16
|
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
@@ -37,7 +36,8 @@ var cmTheme = exports.cmTheme = _view.EditorView.theme({
|
|
|
37
36
|
// Custom syntax styling to match existing styling
|
|
38
37
|
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
39
38
|
lineHeight: 'unset',
|
|
40
|
-
fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)"
|
|
39
|
+
fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
40
|
+
borderRadius: "var(--ds-border-radius, 4px)"
|
|
41
41
|
},
|
|
42
42
|
'&.cm-focused .cm-cursor': {
|
|
43
43
|
borderLeftColor: "var(--ds-text, #172B4D)"
|
|
@@ -45,7 +45,8 @@ var cmTheme = exports.cmTheme = _view.EditorView.theme({
|
|
|
45
45
|
'.cm-gutters': {
|
|
46
46
|
backgroundColor: "var(--ds-background-neutral, #091E420F)",
|
|
47
47
|
border: 'none',
|
|
48
|
-
padding: "var(--ds-space-100, 8px)"
|
|
48
|
+
padding: "var(--ds-space-100, 8px)",
|
|
49
|
+
color: "var(--ds-text-subtlest, #626F86)"
|
|
49
50
|
},
|
|
50
51
|
'.cm-lineNumbers .cm-gutterElement': {
|
|
51
52
|
paddingLeft: "var(--ds-space-0, 0px)",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { closeBrackets } from '@codemirror/autocomplete';
|
|
3
|
-
import { syntaxHighlighting } from '@codemirror/language';
|
|
3
|
+
import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
|
|
4
4
|
import { Compartment, EditorSelection } from '@codemirror/state';
|
|
5
|
-
import { EditorView as CodeMirror, lineNumbers } from '@codemirror/view';
|
|
5
|
+
import { EditorView as CodeMirror, lineNumbers, gutters } from '@codemirror/view';
|
|
6
6
|
import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
7
7
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
8
8
|
import { highlightStyle } from '../ui/syntaxHighlightingTheme';
|
|
@@ -10,16 +10,18 @@ import { cmTheme } from '../ui/theme';
|
|
|
10
10
|
import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
|
|
11
11
|
import { updateCMSelection } from './codemirrorSync/updateCMSelection';
|
|
12
12
|
import { bidiCharWarningExtension } from './extensions/bidiCharWarning';
|
|
13
|
+
import { copyButtonDecorations } from './extensions/copyButtonDecorations';
|
|
13
14
|
import { keymapExtension } from './extensions/keymap';
|
|
14
15
|
import { LanguageLoader } from './languages/loader';
|
|
15
16
|
// Based on: https://prosemirror.net/examples/codemirror/
|
|
16
17
|
class CodeBlockAdvancedNodeView {
|
|
17
18
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
18
19
|
constructor(node, view, getPos, config) {
|
|
19
|
-
var _config$api, _config$api$selection, _config$api2, _config$api2$editorDi;
|
|
20
|
+
var _config$api, _config$api$selection, _config$api2, _config$api2$editorDi, _config$api3, _config$api3$codeBloc;
|
|
20
21
|
_defineProperty(this, "lineWrappingCompartment", new Compartment());
|
|
21
22
|
_defineProperty(this, "languageCompartment", new Compartment());
|
|
22
23
|
_defineProperty(this, "readOnlyCompartment", new Compartment());
|
|
24
|
+
_defineProperty(this, "copyDecoCompartment", new Compartment());
|
|
23
25
|
_defineProperty(this, "maybeTryingToReachNodeSelection", false);
|
|
24
26
|
_defineProperty(this, "wordWrappingEnabled", false);
|
|
25
27
|
this.node = node;
|
|
@@ -31,6 +33,14 @@ class CodeBlockAdvancedNodeView {
|
|
|
31
33
|
this.cleanupDisabledState = (_config$api2 = config.api) === null || _config$api2 === void 0 ? void 0 : (_config$api2$editorDi = _config$api2.editorDisabled) === null || _config$api2$editorDi === void 0 ? void 0 : _config$api2$editorDi.sharedState.onChange(() => {
|
|
32
34
|
this.updateReadonlyState();
|
|
33
35
|
});
|
|
36
|
+
this.cleanupCopyButtonDecoration = (_config$api3 = config.api) === null || _config$api3 === void 0 ? void 0 : (_config$api3$codeBloc = _config$api3.codeBlock) === null || _config$api3$codeBloc === void 0 ? void 0 : _config$api3$codeBloc.sharedState.onChange(({
|
|
37
|
+
nextSharedState,
|
|
38
|
+
prevSharedState
|
|
39
|
+
}) => {
|
|
40
|
+
if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode) !== (prevSharedState === null || prevSharedState === void 0 ? void 0 : prevSharedState.copyButtonHoverNode)) {
|
|
41
|
+
this.addCopyButtonDecoration(nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.copyButtonHoverNode);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
34
44
|
this.languageLoader = new LanguageLoader(lang => {
|
|
35
45
|
this.updating = true;
|
|
36
46
|
this.cm.dispatch({
|
|
@@ -40,13 +50,18 @@ class CodeBlockAdvancedNodeView {
|
|
|
40
50
|
});
|
|
41
51
|
this.cm = new CodeMirror({
|
|
42
52
|
doc: this.node.textContent,
|
|
43
|
-
extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), keymapExtension({
|
|
53
|
+
extensions: [...config.extensions, this.lineWrappingCompartment.of([]), this.languageCompartment.of([]), this.copyDecoCompartment.of([]), keymapExtension({
|
|
44
54
|
view,
|
|
45
55
|
getPos,
|
|
46
56
|
getNode,
|
|
47
57
|
selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
|
|
48
58
|
onMaybeNodeSelection
|
|
49
|
-
}), cmTheme, syntaxHighlighting(highlightStyle),
|
|
59
|
+
}), cmTheme, syntaxHighlighting(highlightStyle), bracketMatching(), lineNumbers(),
|
|
60
|
+
// Explicitly disable "sticky" positioning on line numbers to match
|
|
61
|
+
// Renderer behaviour
|
|
62
|
+
gutters({
|
|
63
|
+
fixed: false
|
|
64
|
+
}), CodeMirror.updateListener.of(update => this.forwardUpdate(update)), this.readOnlyCompartment.of(CodeMirror.editable.of(this.view.editable)), closeBrackets(), CodeMirror.editorAttributes.of({
|
|
50
65
|
class: 'code-block'
|
|
51
66
|
}), bidiCharWarningExtension]
|
|
52
67
|
});
|
|
@@ -60,8 +75,9 @@ class CodeBlockAdvancedNodeView {
|
|
|
60
75
|
this.updateLanguage();
|
|
61
76
|
}
|
|
62
77
|
destroy() {
|
|
63
|
-
var _this$cleanupDisabled;
|
|
78
|
+
var _this$cleanupDisabled, _this$cleanupCopyButt;
|
|
64
79
|
(_this$cleanupDisabled = this.cleanupDisabledState) === null || _this$cleanupDisabled === void 0 ? void 0 : _this$cleanupDisabled.call(this);
|
|
80
|
+
(_this$cleanupCopyButt = this.cleanupCopyButtonDecoration) === null || _this$cleanupCopyButt === void 0 ? void 0 : _this$cleanupCopyButt.call(this);
|
|
65
81
|
}
|
|
66
82
|
forwardUpdate(update) {
|
|
67
83
|
var _this$getPos, _this$getPos2;
|
|
@@ -108,6 +124,13 @@ class CodeBlockAdvancedNodeView {
|
|
|
108
124
|
this.view.dispatch(tr);
|
|
109
125
|
}
|
|
110
126
|
}
|
|
127
|
+
addCopyButtonDecoration(node) {
|
|
128
|
+
this.updating = true;
|
|
129
|
+
this.cm.dispatch({
|
|
130
|
+
effects: [this.copyDecoCompartment.reconfigure(node && node === this.node ? copyButtonDecorations : [])]
|
|
131
|
+
});
|
|
132
|
+
this.updating = false;
|
|
133
|
+
}
|
|
111
134
|
updateWordWrap(node) {
|
|
112
135
|
if (this.wordWrappingEnabled !== isCodeBlockWordWrapEnabled(node)) {
|
|
113
136
|
this.updating = true;
|
|
@@ -1,42 +1,72 @@
|
|
|
1
1
|
import { codeBlock } from '@atlaskit/adf-schema';
|
|
2
|
+
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
3
|
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
3
4
|
const codeBlockClassNames = {
|
|
4
5
|
container: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER,
|
|
5
6
|
start: CodeBlockSharedCssClassName.CODEBLOCK_START,
|
|
6
7
|
end: CodeBlockSharedCssClassName.CODEBLOCK_END,
|
|
7
8
|
contentWrapper: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER,
|
|
8
|
-
|
|
9
|
-
gutter: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER,
|
|
10
|
-
content: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT,
|
|
11
|
-
lineNumberWidget: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WIDGET
|
|
9
|
+
content: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT
|
|
12
10
|
};
|
|
11
|
+
const MATCH_NEWLINES = new RegExp('\n', 'gu');
|
|
13
12
|
|
|
14
|
-
//
|
|
15
|
-
const toDOM = (node,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
13
|
+
// Based on: `packages/editor/editor-plugin-code-block/src/nodeviews/code-block.ts`
|
|
14
|
+
const toDOM = (node, formattedAriaLabel) => {
|
|
15
|
+
let totalLineCount = 1;
|
|
16
|
+
node.forEach(node => {
|
|
17
|
+
const text = node.text;
|
|
18
|
+
if (text) {
|
|
19
|
+
totalLineCount += (node.text.match(MATCH_NEWLINES) || []).length;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const maxDigits = totalLineCount.toString().length;
|
|
23
|
+
const content = node.textContent.split('\n').map((_, i) => i + 1).join('\n');
|
|
24
|
+
return ['pre', {
|
|
25
|
+
class: codeBlockClassNames.container,
|
|
26
|
+
style: `--lineNumberGutterWidth:${maxDigits}ch;`,
|
|
27
|
+
'data-language': node.attrs.language || ''
|
|
28
|
+
}, ['div', {
|
|
29
|
+
class: codeBlockClassNames.start,
|
|
30
|
+
contenteditable: 'false'
|
|
31
|
+
}], ['div', {
|
|
32
|
+
class: codeBlockClassNames.contentWrapper
|
|
33
|
+
}, ['div', {
|
|
34
|
+
// Based on packages/editor/editor-common/src/styles/shared/code-block.ts
|
|
35
|
+
// But we can't reuse that class as it adds a ::before that intefers with this approach
|
|
36
|
+
style: convertToInlineCss({
|
|
37
|
+
backgroundColor: "var(--ds-background-neutral, #091E420F)",
|
|
38
|
+
position: 'relative',
|
|
39
|
+
width: 'var(--lineNumberGutterWidth, 2rem)',
|
|
40
|
+
padding: "var(--ds-space-100, 8px)",
|
|
41
|
+
flexShrink: 0,
|
|
42
|
+
fontSize: '0.875rem',
|
|
43
|
+
boxSizing: 'content-box'
|
|
44
|
+
}),
|
|
45
|
+
contenteditable: 'false'
|
|
46
|
+
}, ['div', {
|
|
47
|
+
class: 'code-block-gutter-pseudo-element',
|
|
48
|
+
style: convertToInlineCss({
|
|
49
|
+
textAlign: 'right',
|
|
50
|
+
color: "var(--ds-text-subtlest, #626F86)",
|
|
51
|
+
fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
52
|
+
whiteSpace: 'pre-wrap'
|
|
53
|
+
}),
|
|
54
|
+
'data-label': content
|
|
55
|
+
}]], ['div', {
|
|
56
|
+
class: codeBlockClassNames.content
|
|
57
|
+
}, ['code', {
|
|
58
|
+
'data-language': node.attrs.language || '',
|
|
59
|
+
spellcheck: 'false',
|
|
60
|
+
'data-testid': 'code-block--code',
|
|
61
|
+
'aria-label': formattedAriaLabel
|
|
62
|
+
}, 0]]], ['div', {
|
|
63
|
+
class: codeBlockClassNames.end,
|
|
64
|
+
contenteditable: 'false'
|
|
65
|
+
}]];
|
|
66
|
+
};
|
|
37
67
|
export const codeBlockNodeWithFixedToDOM = () => {
|
|
38
68
|
return {
|
|
39
69
|
...codeBlock,
|
|
40
|
-
toDOM: node => toDOM(node,
|
|
70
|
+
toDOM: node => toDOM(node, '')
|
|
41
71
|
};
|
|
42
72
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RangeSetBuilder } from '@codemirror/state';
|
|
2
|
+
import { EditorView as CodeMirror, Decoration } from '@codemirror/view';
|
|
3
|
+
export const copyButtonDecorations = CodeMirror.decorations.compute([], state => {
|
|
4
|
+
const allTextDecoration = Decoration.mark({
|
|
5
|
+
attributes: {
|
|
6
|
+
class: 'ProseMirror-fake-text-selection'
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
// Create a set of decorations for the entire document
|
|
10
|
+
const builder = new RangeSetBuilder();
|
|
11
|
+
for (let i = 0; i < state.doc.lines; i++) {
|
|
12
|
+
builder.add(state.doc.line(i + 1).from, state.doc.line(i + 1).to, allTextDecoration);
|
|
13
|
+
}
|
|
14
|
+
const decorations = builder.finish();
|
|
15
|
+
return decorations;
|
|
16
|
+
});
|
|
@@ -40,8 +40,11 @@ export const highlightStyle = HighlightStyle.define([{
|
|
|
40
40
|
tag: [tags.string, tags.deleted],
|
|
41
41
|
color: "var(--ds-text-accent-green, #216E4E)"
|
|
42
42
|
}, {
|
|
43
|
-
tag: [tags.
|
|
44
|
-
color: "var(--ds-text, #
|
|
43
|
+
tag: [tags.special(tags.string)],
|
|
44
|
+
color: "var(--ds-text-accent-green, #216E4E)"
|
|
45
|
+
}, {
|
|
46
|
+
tag: [tags.regexp, tags.escape],
|
|
47
|
+
color: "var(--ds-text-accent-teal, #206A83)"
|
|
45
48
|
}, {
|
|
46
49
|
tag: tags.definition(tags.variableName),
|
|
47
50
|
color: "var(--ds-text, #172B4D)"
|
package/dist/es2019/ui/theme.js
CHANGED
|
@@ -5,7 +5,6 @@ export const cmTheme = CodeMirror.theme({
|
|
|
5
5
|
padding: '0',
|
|
6
6
|
marginTop: "var(--ds-space-100, 8px)",
|
|
7
7
|
marginBottom: "var(--ds-space-100, 8px)",
|
|
8
|
-
borderRadius: "var(--ds-border-radius, 4px)",
|
|
9
8
|
fontSize: '0.875rem',
|
|
10
9
|
// Custom syntax styling to match existing styling
|
|
11
10
|
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
@@ -31,7 +30,8 @@ export const cmTheme = CodeMirror.theme({
|
|
|
31
30
|
// Custom syntax styling to match existing styling
|
|
32
31
|
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
|
|
33
32
|
lineHeight: 'unset',
|
|
34
|
-
fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)"
|
|
33
|
+
fontFamily: "var(--ds-font-family-code, ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
|
|
34
|
+
borderRadius: "var(--ds-border-radius, 4px)"
|
|
35
35
|
},
|
|
36
36
|
'&.cm-focused .cm-cursor': {
|
|
37
37
|
borderLeftColor: "var(--ds-text, #172B4D)"
|
|
@@ -39,7 +39,8 @@ export const cmTheme = CodeMirror.theme({
|
|
|
39
39
|
'.cm-gutters': {
|
|
40
40
|
backgroundColor: "var(--ds-background-neutral, #091E420F)",
|
|
41
41
|
border: 'none',
|
|
42
|
-
padding: "var(--ds-space-100, 8px)"
|
|
42
|
+
padding: "var(--ds-space-100, 8px)",
|
|
43
|
+
color: "var(--ds-text-subtlest, #626F86)"
|
|
43
44
|
},
|
|
44
45
|
'.cm-lineNumbers .cm-gutterElement': {
|
|
45
46
|
paddingLeft: "var(--ds-space-0, 0px)",
|