@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.
Files changed (126) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE.md +13 -0
  3. package/README.md +30 -0
  4. package/dist/cjs/actions.js +201 -0
  5. package/dist/cjs/ide-ux/bracket-handling.js +35 -0
  6. package/dist/cjs/ide-ux/commands.js +115 -0
  7. package/dist/cjs/ide-ux/line-handling.js +81 -0
  8. package/dist/cjs/ide-ux/paired-character-handling.js +23 -0
  9. package/dist/cjs/ide-ux/quote-handling.js +40 -0
  10. package/dist/cjs/index.js +13 -0
  11. package/dist/cjs/language-list.js +62 -0
  12. package/dist/cjs/nodeviews/code-block.js +153 -0
  13. package/dist/cjs/plugin-key.js +8 -0
  14. package/dist/cjs/plugin.js +120 -0
  15. package/dist/cjs/pm-plugins/actions.js +10 -0
  16. package/dist/cjs/pm-plugins/codeBlockCopySelectionPlugin.js +113 -0
  17. package/dist/cjs/pm-plugins/ide-ux.js +132 -0
  18. package/dist/cjs/pm-plugins/input-rule.js +68 -0
  19. package/dist/cjs/pm-plugins/keymaps.js +66 -0
  20. package/dist/cjs/pm-plugins/main-state.js +10 -0
  21. package/dist/cjs/pm-plugins/main.js +114 -0
  22. package/dist/cjs/refresh-browser-selection.js +29 -0
  23. package/dist/cjs/toolbar.js +131 -0
  24. package/dist/cjs/transform-to-code-block.js +84 -0
  25. package/dist/cjs/types.js +5 -0
  26. package/dist/cjs/ui/class-names.js +15 -0
  27. package/dist/cjs/utils.js +28 -0
  28. package/dist/es2019/actions.js +211 -0
  29. package/dist/es2019/ide-ux/bracket-handling.js +27 -0
  30. package/dist/es2019/ide-ux/commands.js +115 -0
  31. package/dist/es2019/ide-ux/line-handling.js +75 -0
  32. package/dist/es2019/ide-ux/paired-character-handling.js +12 -0
  33. package/dist/es2019/ide-ux/quote-handling.js +32 -0
  34. package/dist/es2019/index.js +1 -0
  35. package/dist/es2019/language-list.js +51 -0
  36. package/dist/es2019/nodeviews/code-block.js +126 -0
  37. package/dist/es2019/plugin-key.js +2 -0
  38. package/dist/es2019/plugin.js +104 -0
  39. package/dist/es2019/pm-plugins/actions.js +4 -0
  40. package/dist/es2019/pm-plugins/codeBlockCopySelectionPlugin.js +101 -0
  41. package/dist/es2019/pm-plugins/ide-ux.js +135 -0
  42. package/dist/es2019/pm-plugins/input-rule.js +60 -0
  43. package/dist/es2019/pm-plugins/keymaps.js +58 -0
  44. package/dist/es2019/pm-plugins/main-state.js +2 -0
  45. package/dist/es2019/pm-plugins/main.js +102 -0
  46. package/dist/es2019/refresh-browser-selection.js +25 -0
  47. package/dist/es2019/toolbar.js +108 -0
  48. package/dist/es2019/transform-to-code-block.js +79 -0
  49. package/dist/es2019/types.js +1 -0
  50. package/dist/es2019/ui/class-names.js +9 -0
  51. package/dist/es2019/utils.js +4 -0
  52. package/dist/esm/actions.js +191 -0
  53. package/dist/esm/ide-ux/bracket-handling.js +29 -0
  54. package/dist/esm/ide-ux/commands.js +107 -0
  55. package/dist/esm/ide-ux/line-handling.js +73 -0
  56. package/dist/esm/ide-ux/paired-character-handling.js +16 -0
  57. package/dist/esm/ide-ux/quote-handling.js +34 -0
  58. package/dist/esm/index.js +1 -0
  59. package/dist/esm/language-list.js +52 -0
  60. package/dist/esm/nodeviews/code-block.js +146 -0
  61. package/dist/esm/plugin-key.js +2 -0
  62. package/dist/esm/plugin.js +113 -0
  63. package/dist/esm/pm-plugins/actions.js +4 -0
  64. package/dist/esm/pm-plugins/codeBlockCopySelectionPlugin.js +103 -0
  65. package/dist/esm/pm-plugins/ide-ux.js +126 -0
  66. package/dist/esm/pm-plugins/input-rule.js +62 -0
  67. package/dist/esm/pm-plugins/keymaps.js +59 -0
  68. package/dist/esm/pm-plugins/main-state.js +4 -0
  69. package/dist/esm/pm-plugins/main.js +107 -0
  70. package/dist/esm/refresh-browser-selection.js +25 -0
  71. package/dist/esm/toolbar.js +121 -0
  72. package/dist/esm/transform-to-code-block.js +77 -0
  73. package/dist/esm/types.js +1 -0
  74. package/dist/esm/ui/class-names.js +9 -0
  75. package/dist/esm/utils.js +4 -0
  76. package/dist/types/actions.d.ts +18 -0
  77. package/dist/types/ide-ux/bracket-handling.d.ts +12 -0
  78. package/dist/types/ide-ux/commands.d.ts +7 -0
  79. package/dist/types/ide-ux/line-handling.d.ts +25 -0
  80. package/dist/types/ide-ux/paired-character-handling.d.ts +2 -0
  81. package/dist/types/ide-ux/quote-handling.d.ts +12 -0
  82. package/dist/types/index.d.ts +3 -0
  83. package/dist/types/language-list.d.ts +942 -0
  84. package/dist/types/nodeviews/code-block.d.ts +21 -0
  85. package/dist/types/plugin-key.d.ts +2 -0
  86. package/dist/types/plugin.d.ts +19 -0
  87. package/dist/types/pm-plugins/actions.d.ts +4 -0
  88. package/dist/types/pm-plugins/codeBlockCopySelectionPlugin.d.ts +11 -0
  89. package/dist/types/pm-plugins/ide-ux.d.ts +5 -0
  90. package/dist/types/pm-plugins/input-rule.d.ts +3 -0
  91. package/dist/types/pm-plugins/keymaps.d.ts +4 -0
  92. package/dist/types/pm-plugins/main-state.d.ts +8 -0
  93. package/dist/types/pm-plugins/main.d.ts +10 -0
  94. package/dist/types/refresh-browser-selection.d.ts +5 -0
  95. package/dist/types/toolbar.d.ts +14 -0
  96. package/dist/types/transform-to-code-block.d.ts +3 -0
  97. package/dist/types/types.d.ts +6 -0
  98. package/dist/types/ui/class-names.d.ts +8 -0
  99. package/dist/types/utils.d.ts +4 -0
  100. package/dist/types-ts4.5/actions.d.ts +18 -0
  101. package/dist/types-ts4.5/ide-ux/bracket-handling.d.ts +12 -0
  102. package/dist/types-ts4.5/ide-ux/commands.d.ts +7 -0
  103. package/dist/types-ts4.5/ide-ux/line-handling.d.ts +25 -0
  104. package/dist/types-ts4.5/ide-ux/paired-character-handling.d.ts +2 -0
  105. package/dist/types-ts4.5/ide-ux/quote-handling.d.ts +12 -0
  106. package/dist/types-ts4.5/index.d.ts +3 -0
  107. package/dist/types-ts4.5/language-list.d.ts +1641 -0
  108. package/dist/types-ts4.5/nodeviews/code-block.d.ts +21 -0
  109. package/dist/types-ts4.5/plugin-key.d.ts +2 -0
  110. package/dist/types-ts4.5/plugin.d.ts +19 -0
  111. package/dist/types-ts4.5/pm-plugins/actions.d.ts +4 -0
  112. package/dist/types-ts4.5/pm-plugins/codeBlockCopySelectionPlugin.d.ts +14 -0
  113. package/dist/types-ts4.5/pm-plugins/ide-ux.d.ts +5 -0
  114. package/dist/types-ts4.5/pm-plugins/input-rule.d.ts +3 -0
  115. package/dist/types-ts4.5/pm-plugins/keymaps.d.ts +4 -0
  116. package/dist/types-ts4.5/pm-plugins/main-state.d.ts +8 -0
  117. package/dist/types-ts4.5/pm-plugins/main.d.ts +10 -0
  118. package/dist/types-ts4.5/refresh-browser-selection.d.ts +5 -0
  119. package/dist/types-ts4.5/toolbar.d.ts +14 -0
  120. package/dist/types-ts4.5/transform-to-code-block.d.ts +3 -0
  121. package/dist/types-ts4.5/types.d.ts +6 -0
  122. package/dist/types-ts4.5/ui/class-names.d.ts +8 -0
  123. package/dist/types-ts4.5/utils.d.ts +4 -0
  124. package/package.json +99 -0
  125. package/report.api.md +73 -0
  126. 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,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -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
+ };