@atlaskit/editor-plugin-code-block 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +30 -0
- package/dist/cjs/actions.js +201 -0
- package/dist/cjs/ide-ux/bracket-handling.js +35 -0
- package/dist/cjs/ide-ux/commands.js +115 -0
- package/dist/cjs/ide-ux/line-handling.js +81 -0
- package/dist/cjs/ide-ux/paired-character-handling.js +23 -0
- package/dist/cjs/ide-ux/quote-handling.js +40 -0
- package/dist/cjs/index.js +13 -0
- package/dist/cjs/language-list.js +62 -0
- package/dist/cjs/nodeviews/code-block.js +153 -0
- package/dist/cjs/plugin-key.js +8 -0
- package/dist/cjs/plugin.js +120 -0
- package/dist/cjs/pm-plugins/actions.js +10 -0
- package/dist/cjs/pm-plugins/codeBlockCopySelectionPlugin.js +113 -0
- package/dist/cjs/pm-plugins/ide-ux.js +132 -0
- package/dist/cjs/pm-plugins/input-rule.js +68 -0
- package/dist/cjs/pm-plugins/keymaps.js +66 -0
- package/dist/cjs/pm-plugins/main-state.js +10 -0
- package/dist/cjs/pm-plugins/main.js +114 -0
- package/dist/cjs/refresh-browser-selection.js +29 -0
- package/dist/cjs/toolbar.js +131 -0
- package/dist/cjs/transform-to-code-block.js +84 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/ui/class-names.js +15 -0
- package/dist/cjs/utils.js +28 -0
- package/dist/es2019/actions.js +211 -0
- package/dist/es2019/ide-ux/bracket-handling.js +27 -0
- package/dist/es2019/ide-ux/commands.js +115 -0
- package/dist/es2019/ide-ux/line-handling.js +75 -0
- package/dist/es2019/ide-ux/paired-character-handling.js +12 -0
- package/dist/es2019/ide-ux/quote-handling.js +32 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/language-list.js +51 -0
- package/dist/es2019/nodeviews/code-block.js +126 -0
- package/dist/es2019/plugin-key.js +2 -0
- package/dist/es2019/plugin.js +104 -0
- package/dist/es2019/pm-plugins/actions.js +4 -0
- package/dist/es2019/pm-plugins/codeBlockCopySelectionPlugin.js +101 -0
- package/dist/es2019/pm-plugins/ide-ux.js +135 -0
- package/dist/es2019/pm-plugins/input-rule.js +60 -0
- package/dist/es2019/pm-plugins/keymaps.js +58 -0
- package/dist/es2019/pm-plugins/main-state.js +2 -0
- package/dist/es2019/pm-plugins/main.js +102 -0
- package/dist/es2019/refresh-browser-selection.js +25 -0
- package/dist/es2019/toolbar.js +108 -0
- package/dist/es2019/transform-to-code-block.js +79 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/ui/class-names.js +9 -0
- package/dist/es2019/utils.js +4 -0
- package/dist/esm/actions.js +191 -0
- package/dist/esm/ide-ux/bracket-handling.js +29 -0
- package/dist/esm/ide-ux/commands.js +107 -0
- package/dist/esm/ide-ux/line-handling.js +73 -0
- package/dist/esm/ide-ux/paired-character-handling.js +16 -0
- package/dist/esm/ide-ux/quote-handling.js +34 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/language-list.js +52 -0
- package/dist/esm/nodeviews/code-block.js +146 -0
- package/dist/esm/plugin-key.js +2 -0
- package/dist/esm/plugin.js +113 -0
- package/dist/esm/pm-plugins/actions.js +4 -0
- package/dist/esm/pm-plugins/codeBlockCopySelectionPlugin.js +103 -0
- package/dist/esm/pm-plugins/ide-ux.js +126 -0
- package/dist/esm/pm-plugins/input-rule.js +62 -0
- package/dist/esm/pm-plugins/keymaps.js +59 -0
- package/dist/esm/pm-plugins/main-state.js +4 -0
- package/dist/esm/pm-plugins/main.js +107 -0
- package/dist/esm/refresh-browser-selection.js +25 -0
- package/dist/esm/toolbar.js +121 -0
- package/dist/esm/transform-to-code-block.js +77 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/ui/class-names.js +9 -0
- package/dist/esm/utils.js +4 -0
- package/dist/types/actions.d.ts +18 -0
- package/dist/types/ide-ux/bracket-handling.d.ts +12 -0
- package/dist/types/ide-ux/commands.d.ts +7 -0
- package/dist/types/ide-ux/line-handling.d.ts +25 -0
- package/dist/types/ide-ux/paired-character-handling.d.ts +2 -0
- package/dist/types/ide-ux/quote-handling.d.ts +12 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/language-list.d.ts +942 -0
- package/dist/types/nodeviews/code-block.d.ts +21 -0
- package/dist/types/plugin-key.d.ts +2 -0
- package/dist/types/plugin.d.ts +19 -0
- package/dist/types/pm-plugins/actions.d.ts +4 -0
- package/dist/types/pm-plugins/codeBlockCopySelectionPlugin.d.ts +11 -0
- package/dist/types/pm-plugins/ide-ux.d.ts +5 -0
- package/dist/types/pm-plugins/input-rule.d.ts +3 -0
- package/dist/types/pm-plugins/keymaps.d.ts +4 -0
- package/dist/types/pm-plugins/main-state.d.ts +8 -0
- package/dist/types/pm-plugins/main.d.ts +10 -0
- package/dist/types/refresh-browser-selection.d.ts +5 -0
- package/dist/types/toolbar.d.ts +14 -0
- package/dist/types/transform-to-code-block.d.ts +3 -0
- package/dist/types/types.d.ts +6 -0
- package/dist/types/ui/class-names.d.ts +8 -0
- package/dist/types/utils.d.ts +4 -0
- package/dist/types-ts4.5/actions.d.ts +18 -0
- package/dist/types-ts4.5/ide-ux/bracket-handling.d.ts +12 -0
- package/dist/types-ts4.5/ide-ux/commands.d.ts +7 -0
- package/dist/types-ts4.5/ide-ux/line-handling.d.ts +25 -0
- package/dist/types-ts4.5/ide-ux/paired-character-handling.d.ts +2 -0
- package/dist/types-ts4.5/ide-ux/quote-handling.d.ts +12 -0
- package/dist/types-ts4.5/index.d.ts +3 -0
- package/dist/types-ts4.5/language-list.d.ts +1641 -0
- package/dist/types-ts4.5/nodeviews/code-block.d.ts +21 -0
- package/dist/types-ts4.5/plugin-key.d.ts +2 -0
- package/dist/types-ts4.5/plugin.d.ts +19 -0
- package/dist/types-ts4.5/pm-plugins/actions.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/codeBlockCopySelectionPlugin.d.ts +14 -0
- package/dist/types-ts4.5/pm-plugins/ide-ux.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/input-rule.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/keymaps.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/main-state.d.ts +8 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +10 -0
- package/dist/types-ts4.5/refresh-browser-selection.d.ts +5 -0
- package/dist/types-ts4.5/toolbar.d.ts +14 -0
- package/dist/types-ts4.5/transform-to-code-block.d.ts +3 -0
- package/dist/types-ts4.5/types.d.ts +6 -0
- package/dist/types-ts4.5/ui/class-names.d.ts +8 -0
- package/dist/types-ts4.5/utils.d.ts +4 -0
- package/package.json +99 -0
- package/report.api.md +73 -0
- package/tmp/api-report-tmp.d.ts +45 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getPluginState = void 0;
|
|
7
|
+
var _pluginKey = require("../plugin-key");
|
|
8
|
+
var getPluginState = exports.getPluginState = function getPluginState(state) {
|
|
9
|
+
return _pluginKey.pluginKey.getState(state);
|
|
10
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createPlugin = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
10
|
+
var _selection = require("@atlaskit/editor-common/selection");
|
|
11
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
12
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
13
|
+
var _actions = require("../actions");
|
|
14
|
+
var _codeBlock = require("../nodeviews/code-block");
|
|
15
|
+
var _pluginKey = require("../plugin-key");
|
|
16
|
+
var _classNames = require("../ui/class-names");
|
|
17
|
+
var _utils2 = require("../utils");
|
|
18
|
+
var _actions2 = require("./actions");
|
|
19
|
+
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; }
|
|
20
|
+
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; }
|
|
21
|
+
var createPlugin = exports.createPlugin = function createPlugin(_ref) {
|
|
22
|
+
var _ref$useLongPressSele = _ref.useLongPressSelection,
|
|
23
|
+
useLongPressSelection = _ref$useLongPressSele === void 0 ? false : _ref$useLongPressSele,
|
|
24
|
+
getIntl = _ref.getIntl,
|
|
25
|
+
appearance = _ref.appearance,
|
|
26
|
+
_ref$allowComposition = _ref.allowCompositionInputOverride,
|
|
27
|
+
allowCompositionInputOverride = _ref$allowComposition === void 0 ? false : _ref$allowComposition;
|
|
28
|
+
var handleDOMEvents = {};
|
|
29
|
+
|
|
30
|
+
// ME-1599: Composition on mobile was causing the DOM observer to mutate the code block
|
|
31
|
+
// incorrecly and lose content when pressing enter in the middle of a code block line.
|
|
32
|
+
if (allowCompositionInputOverride) {
|
|
33
|
+
handleDOMEvents.beforeinput = function (view, event) {
|
|
34
|
+
var keyEvent = event;
|
|
35
|
+
var eventInputType = keyEvent.inputType;
|
|
36
|
+
var eventText = keyEvent.data;
|
|
37
|
+
if (_utils.browser.ios && event.composed &&
|
|
38
|
+
// insertParagraph will be the input type when the enter key is pressed.
|
|
39
|
+
eventInputType === 'insertParagraph' && (0, _utils2.findCodeBlock)(view.state, view.state.selection)) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
return true;
|
|
42
|
+
} else if (_utils.browser.android && event.composed && eventInputType === 'insertCompositionText' && eventText[(eventText === null || eventText === void 0 ? void 0 : eventText.length) - 1] === '\n' && (0, _utils2.findCodeBlock)(view.state, view.state.selection)) {
|
|
43
|
+
var resultingText = event.target.outerText + '\n';
|
|
44
|
+
if (resultingText.endsWith(eventText)) {
|
|
45
|
+
// End of paragraph
|
|
46
|
+
setTimeout(function () {
|
|
47
|
+
view.someProp('handleKeyDown', function (f) {
|
|
48
|
+
return f(view, new KeyboardEvent('keydown', {
|
|
49
|
+
bubbles: true,
|
|
50
|
+
cancelable: true,
|
|
51
|
+
key: 'Enter',
|
|
52
|
+
code: 'Enter'
|
|
53
|
+
}));
|
|
54
|
+
});
|
|
55
|
+
}, 0);
|
|
56
|
+
} else {
|
|
57
|
+
// Middle of paragraph, end of line
|
|
58
|
+
(0, _actions.ignoreFollowingMutations)(view.state, view.dispatch);
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (_utils.browser.android) {
|
|
63
|
+
(0, _actions.resetShouldIgnoreFollowingMutations)(view.state, view.dispatch);
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return new _safePlugin.SafePlugin({
|
|
69
|
+
state: {
|
|
70
|
+
init: function init(_, state) {
|
|
71
|
+
var node = (0, _utils2.findCodeBlock)(state, state.selection);
|
|
72
|
+
return {
|
|
73
|
+
pos: node ? node.pos : null,
|
|
74
|
+
contentCopied: false,
|
|
75
|
+
isNodeSelected: false,
|
|
76
|
+
shouldIgnoreFollowingMutations: false
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
apply: function apply(tr, pluginState, _oldState, newState) {
|
|
80
|
+
if (tr.docChanged || tr.selectionSet) {
|
|
81
|
+
var node = (0, _utils2.findCodeBlock)(newState, tr.selection);
|
|
82
|
+
var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
83
|
+
pos: node ? node.pos : null,
|
|
84
|
+
isNodeSelected: tr.selection instanceof _state.NodeSelection
|
|
85
|
+
});
|
|
86
|
+
return newPluginState;
|
|
87
|
+
}
|
|
88
|
+
var meta = tr.getMeta(_pluginKey.pluginKey);
|
|
89
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.type) === _actions2.ACTIONS.SET_COPIED_TO_CLIPBOARD) {
|
|
90
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
91
|
+
contentCopied: meta.data
|
|
92
|
+
});
|
|
93
|
+
} else if ((meta === null || meta === void 0 ? void 0 : meta.type) === _actions2.ACTIONS.SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS) {
|
|
94
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
95
|
+
shouldIgnoreFollowingMutations: meta.data
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return pluginState;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
key: _pluginKey.pluginKey,
|
|
102
|
+
props: {
|
|
103
|
+
nodeViews: {
|
|
104
|
+
codeBlock: _codeBlock.codeBlockNodeView
|
|
105
|
+
},
|
|
106
|
+
handleClickOn: (0, _selection.createSelectionClickHandler)(['codeBlock'], function (target) {
|
|
107
|
+
return !!(target.closest(".".concat(_classNames.codeBlockClassNames.gutter)) || target.classList.contains(_classNames.codeBlockClassNames.content));
|
|
108
|
+
}, {
|
|
109
|
+
useLongPressSelection: useLongPressSelection
|
|
110
|
+
}),
|
|
111
|
+
handleDOMEvents: handleDOMEvents
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.refreshBrowserSelection = exports.default = void 0;
|
|
7
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
8
|
+
var _pluginKey = require("./plugin-key");
|
|
9
|
+
// Workaround for a firefox issue where dom selection is off sync
|
|
10
|
+
// https://product-fabric.atlassian.net/browse/ED-12442
|
|
11
|
+
var refreshBrowserSelection = exports.refreshBrowserSelection = function refreshBrowserSelection() {
|
|
12
|
+
var domSelection = window.getSelection();
|
|
13
|
+
if (domSelection) {
|
|
14
|
+
var domRange = domSelection && domSelection.rangeCount === 1 && domSelection.getRangeAt(0).cloneRange();
|
|
15
|
+
if (domRange) {
|
|
16
|
+
domSelection.removeAllRanges();
|
|
17
|
+
domSelection.addRange(domRange);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var refreshBrowserSelectionOnChange = function refreshBrowserSelectionOnChange(transaction, editorState) {
|
|
22
|
+
var _pluginKey$getState;
|
|
23
|
+
if (_utils.browser.gecko && transaction.docChanged &&
|
|
24
|
+
// codeblockState.pos should be set if current selection is in a codeblock.
|
|
25
|
+
typeof ((_pluginKey$getState = _pluginKey.pluginKey.getState(editorState)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.pos) === 'number') {
|
|
26
|
+
refreshBrowserSelection();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var _default = exports.default = refreshBrowserSelectionOnChange;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.messages = exports.languageListFilter = exports.getToolbarConfig = void 0;
|
|
9
|
+
var _reactIntlNext = require("react-intl-next");
|
|
10
|
+
var _messages = _interopRequireWildcard(require("@atlaskit/editor-common/messages"));
|
|
11
|
+
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
12
|
+
var _copy = _interopRequireDefault(require("@atlaskit/icon/glyph/copy"));
|
|
13
|
+
var _remove = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/remove"));
|
|
14
|
+
var _actions = require("./actions");
|
|
15
|
+
var _languageList = require("./language-list");
|
|
16
|
+
var _pluginKey = require("./plugin-key");
|
|
17
|
+
var _codeBlockCopySelectionPlugin = require("./pm-plugins/codeBlockCopySelectionPlugin");
|
|
18
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
20
|
+
var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
|
|
21
|
+
selectLanguage: {
|
|
22
|
+
id: 'fabric.editor.selectLanguage',
|
|
23
|
+
defaultMessage: 'Select language',
|
|
24
|
+
description: 'Code blocks display software code. A prompt to select the software language the code is written in.'
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
var languageList = (0, _languageList.createLanguageList)(_languageList.DEFAULT_LANGUAGES);
|
|
28
|
+
var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig() {
|
|
29
|
+
var allowCopyToClipboard = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
30
|
+
var api = arguments.length > 1 ? arguments[1] : undefined;
|
|
31
|
+
return function (state, _ref) {
|
|
32
|
+
var _api$decorations$acti, _api$analytics, _codeBlockState$pos, _node$attrs;
|
|
33
|
+
var formatMessage = _ref.formatMessage;
|
|
34
|
+
var _ref2 = (_api$decorations$acti = api === null || api === void 0 ? void 0 : api.decorations.actions) !== null && _api$decorations$acti !== void 0 ? _api$decorations$acti : {},
|
|
35
|
+
hoverDecoration = _ref2.hoverDecoration;
|
|
36
|
+
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
37
|
+
var codeBlockState = _pluginKey.pluginKey.getState(state);
|
|
38
|
+
var pos = (_codeBlockState$pos = codeBlockState === null || codeBlockState === void 0 ? void 0 : codeBlockState.pos) !== null && _codeBlockState$pos !== void 0 ? _codeBlockState$pos : null;
|
|
39
|
+
if (!codeBlockState || pos === null) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
var node = state.doc.nodeAt(pos);
|
|
43
|
+
var nodeType = state.schema.nodes.codeBlock;
|
|
44
|
+
if ((node === null || node === void 0 ? void 0 : node.type) !== nodeType) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
var language = node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.language;
|
|
48
|
+
var options = languageList.map(function (lang) {
|
|
49
|
+
return {
|
|
50
|
+
label: lang.name,
|
|
51
|
+
value: (0, _languageList.getLanguageIdentifier)(lang),
|
|
52
|
+
alias: lang.alias
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// If language is not undefined search for it in the value and then search in the aliases
|
|
57
|
+
var defaultValue = language ? options.find(function (option) {
|
|
58
|
+
return option.value === language;
|
|
59
|
+
}) || options.find(function (option) {
|
|
60
|
+
return option.alias.includes(language);
|
|
61
|
+
}) : null;
|
|
62
|
+
var languageSelect = {
|
|
63
|
+
id: 'editor.codeBlock.languageOptions',
|
|
64
|
+
type: 'select',
|
|
65
|
+
selectType: 'list',
|
|
66
|
+
onChange: function onChange(option) {
|
|
67
|
+
return (0, _actions.changeLanguage)(editorAnalyticsAPI)(option.value);
|
|
68
|
+
},
|
|
69
|
+
defaultValue: defaultValue,
|
|
70
|
+
placeholder: formatMessage(messages.selectLanguage),
|
|
71
|
+
options: options,
|
|
72
|
+
filterOption: languageListFilter
|
|
73
|
+
};
|
|
74
|
+
var separator = {
|
|
75
|
+
type: 'separator'
|
|
76
|
+
};
|
|
77
|
+
var copyToClipboardItems = !allowCopyToClipboard ? [] : [{
|
|
78
|
+
id: 'editor.codeBlock.copy',
|
|
79
|
+
type: 'button',
|
|
80
|
+
appearance: 'subtle',
|
|
81
|
+
icon: _copy.default,
|
|
82
|
+
// note: copyContentToClipboard contains logic that also removes the
|
|
83
|
+
// visual feedback for the copy button
|
|
84
|
+
onClick: _actions.copyContentToClipboard,
|
|
85
|
+
title: formatMessage(codeBlockState.contentCopied ? _messages.codeBlockButtonMessages.copiedCodeToClipboard : _messages.codeBlockButtonMessages.copyCodeToClipboard),
|
|
86
|
+
onMouseEnter: _codeBlockCopySelectionPlugin.provideVisualFeedbackForCopyButton,
|
|
87
|
+
// note: resetCopiedState contains logic that also removes the
|
|
88
|
+
// visual feedback for the copy button
|
|
89
|
+
onMouseLeave: _actions.resetCopiedState,
|
|
90
|
+
onFocus: _codeBlockCopySelectionPlugin.provideVisualFeedbackForCopyButton,
|
|
91
|
+
onBlur: _codeBlockCopySelectionPlugin.removeVisualFeedbackForCopyButton,
|
|
92
|
+
hideTooltipOnClick: false,
|
|
93
|
+
disabled: codeBlockState.isNodeSelected,
|
|
94
|
+
tabIndex: null
|
|
95
|
+
}, separator];
|
|
96
|
+
var deleteButton = {
|
|
97
|
+
id: 'editor.codeBlock.delete',
|
|
98
|
+
type: 'button',
|
|
99
|
+
appearance: 'danger',
|
|
100
|
+
icon: _remove.default,
|
|
101
|
+
onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, true),
|
|
102
|
+
onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false),
|
|
103
|
+
onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, true),
|
|
104
|
+
onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false),
|
|
105
|
+
onClick: _actions.removeCodeBlock,
|
|
106
|
+
title: formatMessage(_messages.default.remove),
|
|
107
|
+
tabIndex: null
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
title: 'CodeBlock floating controls',
|
|
111
|
+
getDomRef: function getDomRef(view) {
|
|
112
|
+
return (0, _utils.findDomRefAtPos)(pos, view.domAtPos.bind(view));
|
|
113
|
+
},
|
|
114
|
+
nodeType: nodeType,
|
|
115
|
+
items: [languageSelect, separator].concat(copyToClipboardItems, [deleteButton]),
|
|
116
|
+
scrollable: true
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Filters language list based on both name and alias properties.
|
|
123
|
+
*/
|
|
124
|
+
var languageListFilter = exports.languageListFilter = function languageListFilter(option, rawInput) {
|
|
125
|
+
var _ref3 = option,
|
|
126
|
+
data = _ref3.data;
|
|
127
|
+
var searchString = rawInput.toLowerCase();
|
|
128
|
+
return data.label.toLowerCase().includes(searchString) || data.alias.some(function (alias) {
|
|
129
|
+
return alias.toLowerCase() === searchString;
|
|
130
|
+
});
|
|
131
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isConvertableToCodeBlock = isConvertableToCodeBlock;
|
|
7
|
+
exports.transformToCodeBlockAction = transformToCodeBlockAction;
|
|
8
|
+
var _selection = require("@atlaskit/editor-common/selection");
|
|
9
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
10
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
11
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
12
|
+
function transformToCodeBlockAction(state, start, attrs) {
|
|
13
|
+
var startOfCodeBlockText = state.selection.$from;
|
|
14
|
+
var endPosition = state.selection.empty && !(state.selection instanceof _selection.GapCursorSelection) ? startOfCodeBlockText.end() : state.selection.$to.pos;
|
|
15
|
+
var startLinePosition = startOfCodeBlockText.start();
|
|
16
|
+
//when cmd+A is used to select the content. start position should be 0.
|
|
17
|
+
var parentStartPosition = startOfCodeBlockText.depth === 0 ? 0 : startOfCodeBlockText.before();
|
|
18
|
+
var contentSlice = state.doc.slice(startOfCodeBlockText.pos, endPosition);
|
|
19
|
+
var codeBlockSlice = (0, _utils.mapSlice)(contentSlice, function (node, parent, index) {
|
|
20
|
+
if (node.type === state.schema.nodes.hardBreak) {
|
|
21
|
+
return state.schema.text('\n');
|
|
22
|
+
}
|
|
23
|
+
if (node.isText) {
|
|
24
|
+
return node.mark([]);
|
|
25
|
+
}
|
|
26
|
+
if (node.isInline) {
|
|
27
|
+
// Convert dates
|
|
28
|
+
if (node.attrs.timestamp) {
|
|
29
|
+
return state.schema.text((0, _utils.timestampToString)(node.attrs.timestamp, null));
|
|
30
|
+
}
|
|
31
|
+
// Convert links
|
|
32
|
+
if (node.attrs.url) {
|
|
33
|
+
return state.schema.text(node.attrs.url);
|
|
34
|
+
}
|
|
35
|
+
return node.attrs.text ? state.schema.text(node.attrs.text) : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// if the current node is the last child of the Slice exit early to prevent
|
|
39
|
+
// adding additional line breaks
|
|
40
|
+
if (contentSlice.content.childCount - 1 === index) {
|
|
41
|
+
return node.content;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//useful to decide whether to append line breaks when the content has list items.
|
|
45
|
+
var isParentLastChild = parent && contentSlice.content.childCount - 1 === index;
|
|
46
|
+
|
|
47
|
+
// add line breaks at the end of each paragraph to mimic layout of selected content
|
|
48
|
+
// do not add line breaks when the 'paragraph' parent is last child.
|
|
49
|
+
if (node.content.childCount && node.type === state.schema.nodes.paragraph && !isParentLastChild) {
|
|
50
|
+
return node.content.append(_model.Fragment.from(state.schema.text('\n\n')));
|
|
51
|
+
}
|
|
52
|
+
return node.content.childCount ? node.content : null;
|
|
53
|
+
});
|
|
54
|
+
var tr = state.tr;
|
|
55
|
+
|
|
56
|
+
// Replace current block node
|
|
57
|
+
var startMapped = startLinePosition === start ? parentStartPosition : start;
|
|
58
|
+
var codeBlock = state.schema.nodes.codeBlock;
|
|
59
|
+
var codeBlockNode = codeBlock.createChecked(attrs, codeBlockSlice.content);
|
|
60
|
+
tr.replaceWith(startMapped, Math.min(endPosition, tr.doc.content.size), codeBlockNode);
|
|
61
|
+
|
|
62
|
+
// Reposition cursor when inserting into layouts or table headers
|
|
63
|
+
var mapped = tr.doc.resolve(tr.mapping.map(startMapped) + 1);
|
|
64
|
+
var selection = _state.TextSelection.findFrom(mapped, state.selection instanceof _selection.GapCursorSelection ? -1 : 1, true);
|
|
65
|
+
if (selection) {
|
|
66
|
+
return tr.setSelection(selection);
|
|
67
|
+
}
|
|
68
|
+
return tr.setSelection(_state.TextSelection.create(tr.doc, Math.min(start + startOfCodeBlockText.node().nodeSize - 1, tr.doc.content.size)));
|
|
69
|
+
}
|
|
70
|
+
function isConvertableToCodeBlock(state) {
|
|
71
|
+
// Before a document is loaded, there is no selection.
|
|
72
|
+
if (!state.selection) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
var $from = state.selection.$from;
|
|
76
|
+
var node = $from.parent;
|
|
77
|
+
if (!node.isTextblock || node.type === state.schema.nodes.codeBlock) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
var parentDepth = $from.depth - 1;
|
|
81
|
+
var parentNode = $from.node(parentDepth);
|
|
82
|
+
var index = $from.index(parentDepth);
|
|
83
|
+
return parentNode.canReplaceWith(index, index + 1, state.schema.nodes.codeBlock);
|
|
84
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.codeBlockClassNames = void 0;
|
|
7
|
+
var _styles = require("@atlaskit/editor-common/styles");
|
|
8
|
+
var codeBlockClassNames = exports.codeBlockClassNames = {
|
|
9
|
+
container: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER,
|
|
10
|
+
start: _styles.CodeBlockSharedCssClassName.CODEBLOCK_START,
|
|
11
|
+
end: _styles.CodeBlockSharedCssClassName.CODEBLOCK_END,
|
|
12
|
+
contentWrapper: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER,
|
|
13
|
+
gutter: _styles.CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER,
|
|
14
|
+
content: _styles.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT
|
|
15
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "findCodeBlock", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _transforms.findCodeBlock;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.getCursor = getCursor;
|
|
13
|
+
Object.defineProperty(exports, "transformSingleLineCodeBlockToCodeMark", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function get() {
|
|
16
|
+
return _transforms.transformSingleLineCodeBlockToCodeMark;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "transformSliceToJoinAdjacentCodeBlocks", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function get() {
|
|
22
|
+
return _transforms.transformSliceToJoinAdjacentCodeBlocks;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
var _transforms = require("@atlaskit/editor-common/transforms");
|
|
26
|
+
function getCursor(selection) {
|
|
27
|
+
return selection.$cursor || undefined;
|
|
28
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { copyToClipboard } from '@atlaskit/editor-common/clipboard';
|
|
3
|
+
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
|
4
|
+
import { shouldSplitSelectedNodeOnNodeInsertion } from '@atlaskit/editor-common/insert';
|
|
5
|
+
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
import { findParentNodeOfType, findSelectedNodeOfType, isNodeSelection, removeParentNodeOfType, removeSelectedNode, safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
7
|
+
import { pluginKey } from './plugin-key';
|
|
8
|
+
import { ACTIONS } from './pm-plugins/actions';
|
|
9
|
+
import { copySelectionPluginKey } from './pm-plugins/codeBlockCopySelectionPlugin';
|
|
10
|
+
import { transformToCodeBlockAction } from './transform-to-code-block';
|
|
11
|
+
export const removeCodeBlock = (state, dispatch) => {
|
|
12
|
+
const {
|
|
13
|
+
schema: {
|
|
14
|
+
nodes
|
|
15
|
+
},
|
|
16
|
+
tr
|
|
17
|
+
} = state;
|
|
18
|
+
if (dispatch) {
|
|
19
|
+
let removeTr = tr;
|
|
20
|
+
if (findSelectedNodeOfType(nodes.codeBlock)(tr.selection)) {
|
|
21
|
+
removeTr = removeSelectedNode(tr);
|
|
22
|
+
} else {
|
|
23
|
+
removeTr = removeParentNodeOfType(nodes.codeBlock)(tr);
|
|
24
|
+
}
|
|
25
|
+
dispatch(removeTr);
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
export const changeLanguage = editorAnalyticsAPI => language => (state, dispatch) => {
|
|
30
|
+
var _pluginKey$getState;
|
|
31
|
+
const {
|
|
32
|
+
codeBlock
|
|
33
|
+
} = state.schema.nodes;
|
|
34
|
+
const pos = (_pluginKey$getState = pluginKey.getState(state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.pos;
|
|
35
|
+
if (typeof pos !== 'number') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const tr = state.tr.setNodeMarkup(pos, codeBlock, {
|
|
39
|
+
language
|
|
40
|
+
}).setMeta('scrollIntoView', false);
|
|
41
|
+
const selection = isNodeSelection(state.selection) ? NodeSelection.create(tr.doc, pos) : tr.selection;
|
|
42
|
+
const result = tr.setSelection(selection);
|
|
43
|
+
if (dispatch) {
|
|
44
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
|
|
45
|
+
action: ACTION.LANGUAGE_SELECTED,
|
|
46
|
+
actionSubject: ACTION_SUBJECT.CODE_BLOCK,
|
|
47
|
+
attributes: {
|
|
48
|
+
language
|
|
49
|
+
},
|
|
50
|
+
eventType: EVENT_TYPE.TRACK
|
|
51
|
+
})(result);
|
|
52
|
+
dispatch(result);
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
};
|
|
56
|
+
export const copyContentToClipboard = (state, dispatch) => {
|
|
57
|
+
const {
|
|
58
|
+
schema: {
|
|
59
|
+
nodes
|
|
60
|
+
},
|
|
61
|
+
tr
|
|
62
|
+
} = state;
|
|
63
|
+
const codeBlock = findParentNodeOfType(nodes.codeBlock)(tr.selection);
|
|
64
|
+
const textContent = codeBlock && codeBlock.node.textContent;
|
|
65
|
+
if (textContent) {
|
|
66
|
+
copyToClipboard(textContent);
|
|
67
|
+
let copyToClipboardTr = tr;
|
|
68
|
+
copyToClipboardTr.setMeta(pluginKey, {
|
|
69
|
+
type: ACTIONS.SET_COPIED_TO_CLIPBOARD,
|
|
70
|
+
data: true
|
|
71
|
+
});
|
|
72
|
+
copyToClipboardTr.setMeta(copySelectionPluginKey, 'remove-selection');
|
|
73
|
+
if (dispatch) {
|
|
74
|
+
dispatch(copyToClipboardTr);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
};
|
|
79
|
+
export const resetCopiedState = (state, dispatch) => {
|
|
80
|
+
const {
|
|
81
|
+
tr
|
|
82
|
+
} = state;
|
|
83
|
+
const codeBlockState = pluginKey.getState(state);
|
|
84
|
+
let resetCopiedStateTr = tr;
|
|
85
|
+
if (codeBlockState && codeBlockState.contentCopied) {
|
|
86
|
+
resetCopiedStateTr.setMeta(pluginKey, {
|
|
87
|
+
type: ACTIONS.SET_COPIED_TO_CLIPBOARD,
|
|
88
|
+
data: false
|
|
89
|
+
});
|
|
90
|
+
resetCopiedStateTr.setMeta(copySelectionPluginKey, 'remove-selection');
|
|
91
|
+
if (dispatch) {
|
|
92
|
+
dispatch(resetCopiedStateTr);
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
const clearSelectionStateTransaction = state.tr;
|
|
96
|
+
clearSelectionStateTransaction.setMeta(copySelectionPluginKey, 'remove-selection');
|
|
97
|
+
// note: dispatch should always be defined when called from the
|
|
98
|
+
// floating toolbar. Howver the Command type which floating toolbar uses
|
|
99
|
+
// (and resetCopiedState) uses suggests it's optional.
|
|
100
|
+
if (dispatch) {
|
|
101
|
+
dispatch(clearSelectionStateTransaction);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
};
|
|
106
|
+
export const ignoreFollowingMutations = (state, dispatch) => {
|
|
107
|
+
const {
|
|
108
|
+
tr
|
|
109
|
+
} = state;
|
|
110
|
+
const ignoreFollowingMutationsTr = tr;
|
|
111
|
+
ignoreFollowingMutationsTr.setMeta(pluginKey, {
|
|
112
|
+
type: ACTIONS.SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS,
|
|
113
|
+
data: true
|
|
114
|
+
});
|
|
115
|
+
if (dispatch) {
|
|
116
|
+
dispatch(ignoreFollowingMutationsTr);
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
};
|
|
120
|
+
export const resetShouldIgnoreFollowingMutations = (state, dispatch) => {
|
|
121
|
+
const {
|
|
122
|
+
tr
|
|
123
|
+
} = state;
|
|
124
|
+
const ignoreFollowingMutationsTr = tr;
|
|
125
|
+
ignoreFollowingMutationsTr.setMeta(pluginKey, {
|
|
126
|
+
type: ACTIONS.SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS,
|
|
127
|
+
data: false
|
|
128
|
+
});
|
|
129
|
+
if (dispatch) {
|
|
130
|
+
dispatch(ignoreFollowingMutationsTr);
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* This function creates a new transaction that inserts a code block,
|
|
137
|
+
* if there is text selected it will wrap the current selection if not it will
|
|
138
|
+
* append the codeblock to the end of the document.
|
|
139
|
+
*/
|
|
140
|
+
export function createInsertCodeBlockTransaction({
|
|
141
|
+
state
|
|
142
|
+
}) {
|
|
143
|
+
var _state$selection$$fro;
|
|
144
|
+
let {
|
|
145
|
+
tr
|
|
146
|
+
} = state;
|
|
147
|
+
const {
|
|
148
|
+
from
|
|
149
|
+
} = state.selection;
|
|
150
|
+
const {
|
|
151
|
+
codeBlock
|
|
152
|
+
} = state.schema.nodes;
|
|
153
|
+
const grandParentNodeType = (_state$selection$$fro = state.selection.$from.node(-1)) === null || _state$selection$$fro === void 0 ? void 0 : _state$selection$$fro.type;
|
|
154
|
+
const parentNodeType = state.selection.$from.parent.type;
|
|
155
|
+
|
|
156
|
+
/** We always want to append a codeBlock unless we're inserting into a paragraph
|
|
157
|
+
* AND it's a valid child of the grandparent node.
|
|
158
|
+
* Insert the current selection as codeBlock content unless it contains nodes other
|
|
159
|
+
* than paragraphs and inline.
|
|
160
|
+
*/
|
|
161
|
+
const canInsertCodeBlock = shouldSplitSelectedNodeOnNodeInsertion({
|
|
162
|
+
parentNodeType,
|
|
163
|
+
grandParentNodeType,
|
|
164
|
+
content: codeBlock.createAndFill()
|
|
165
|
+
}) && contentAllowedInCodeBlock(state);
|
|
166
|
+
if (canInsertCodeBlock) {
|
|
167
|
+
tr = transformToCodeBlockAction(state, from);
|
|
168
|
+
} else {
|
|
169
|
+
safeInsert(codeBlock.createAndFill())(tr).scrollIntoView();
|
|
170
|
+
}
|
|
171
|
+
return tr;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Check if the current selection contains any nodes that are not permitted
|
|
176
|
+
* as codeBlock child nodes. Note that this allows paragraphs and inline nodes
|
|
177
|
+
* as we extract their text content.
|
|
178
|
+
*/
|
|
179
|
+
function contentAllowedInCodeBlock(state) {
|
|
180
|
+
const {
|
|
181
|
+
$from,
|
|
182
|
+
$to
|
|
183
|
+
} = state.selection;
|
|
184
|
+
let isAllowedChild = true;
|
|
185
|
+
state.doc.nodesBetween($from.pos, $to.pos, node => {
|
|
186
|
+
if (!isAllowedChild) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
return isAllowedChild = node.type === state.schema.nodes.listItem || node.type === state.schema.nodes.bulletList || node.type === state.schema.nodes.orderedList || node.type === state.schema.nodes.paragraph || node.isInline || node.isText;
|
|
190
|
+
});
|
|
191
|
+
return isAllowedChild;
|
|
192
|
+
}
|
|
193
|
+
export function insertCodeBlockWithAnalytics(inputMethod, analyticsAPI) {
|
|
194
|
+
return withAnalytics(analyticsAPI, {
|
|
195
|
+
action: ACTION.INSERTED,
|
|
196
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
197
|
+
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
|
|
198
|
+
attributes: {
|
|
199
|
+
inputMethod: inputMethod
|
|
200
|
+
},
|
|
201
|
+
eventType: EVENT_TYPE.TRACK
|
|
202
|
+
})(function (state, dispatch) {
|
|
203
|
+
let tr = createInsertCodeBlockTransaction({
|
|
204
|
+
state
|
|
205
|
+
});
|
|
206
|
+
if (dispatch) {
|
|
207
|
+
dispatch(tr);
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const BRACKET_MAP = {
|
|
2
|
+
'{': '}',
|
|
3
|
+
'[': ']',
|
|
4
|
+
'(': ')'
|
|
5
|
+
};
|
|
6
|
+
export const shouldAutoCloseBracket = (before, after) => {
|
|
7
|
+
// when directly before a closing bracket
|
|
8
|
+
if (/^[}\])]/.test(after)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// exclusion: when directly before a non-whitespace character
|
|
13
|
+
if (/^[^\s]/.test(after)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
18
|
+
export const getAutoClosingBracketInfo = (before, after) => {
|
|
19
|
+
const left = Object.keys(BRACKET_MAP).find(item => before.endsWith(item));
|
|
20
|
+
const right = left ? BRACKET_MAP[left] : undefined;
|
|
21
|
+
const hasTrailingMatchingBracket = right ? after.startsWith(right) : false;
|
|
22
|
+
return {
|
|
23
|
+
left,
|
|
24
|
+
right,
|
|
25
|
+
hasTrailingMatchingBracket
|
|
26
|
+
};
|
|
27
|
+
};
|