@contentful/field-editor-markdown 1.2.1 → 1.3.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 (136) hide show
  1. package/dist/cjs/MarkdownActions.js +235 -0
  2. package/dist/cjs/MarkdownEditor.js +180 -0
  3. package/dist/cjs/__fixtures__/FakeSdk.js +183 -0
  4. package/dist/cjs/__fixtures__/asset/index.js +37 -0
  5. package/dist/cjs/__fixtures__/content-type/index.js +16 -0
  6. package/dist/cjs/__fixtures__/entry/index.js +33 -0
  7. package/dist/cjs/__fixtures__/fixtures.js +71 -0
  8. package/dist/cjs/__fixtures__/locale/index.js +40 -0
  9. package/dist/cjs/__fixtures__/space/index.js +16 -0
  10. package/dist/cjs/codemirrorImports.js +9 -0
  11. package/dist/cjs/components/HeadingSelector.js +66 -0
  12. package/dist/cjs/components/InsertLinkSelector.js +86 -0
  13. package/dist/cjs/components/MarkdownBottomBar.js +111 -0
  14. package/dist/cjs/components/MarkdownConstraints.js +79 -0
  15. package/dist/cjs/components/MarkdownPreview.js +249 -0
  16. package/dist/cjs/components/MarkdownTabs.js +128 -0
  17. package/dist/cjs/components/MarkdownTextarea/CodeMirrorWrapper.js +383 -0
  18. package/dist/cjs/components/MarkdownTextarea/MarkdownCommands.js +233 -0
  19. package/dist/cjs/components/MarkdownTextarea/MarkdownTextarea.js +190 -0
  20. package/dist/cjs/components/MarkdownTextarea/createMarkdownEditor.js +101 -0
  21. package/dist/cjs/components/MarkdownToolbar.js +367 -0
  22. package/dist/cjs/components/icons.js +193 -0
  23. package/dist/cjs/dialogs/CheatsheetModalDialog.js +239 -0
  24. package/dist/cjs/dialogs/ConfirmInsertAssetModalDialog.js +94 -0
  25. package/dist/cjs/dialogs/EmdebExternalContentDialog.js +202 -0
  26. package/dist/cjs/dialogs/InsertLinkModalDialog.js +149 -0
  27. package/dist/cjs/dialogs/InsertTableModalDialog.js +140 -0
  28. package/dist/cjs/dialogs/SpecialCharacterModalDialog.js +146 -0
  29. package/dist/cjs/dialogs/ZenModeModalDialog.js +257 -0
  30. package/dist/cjs/dialogs/openMarkdownDialog.js +121 -0
  31. package/dist/cjs/dialogs/renderMarkdownDialog.js +108 -0
  32. package/dist/cjs/index.js +29 -0
  33. package/dist/cjs/types.js +20 -0
  34. package/dist/cjs/utils/insertAssetLinks.js +122 -0
  35. package/dist/cjs/utils/insertAssetLinks.spec.js +22 -0
  36. package/dist/cjs/utils/isValidUrl.js +22 -0
  37. package/dist/cjs/utils/linkOrganizer.js +187 -0
  38. package/dist/cjs/utils/linkOrganizer.spec.js +96 -0
  39. package/dist/cjs/utils/replaceMailtoAmp.js +15 -0
  40. package/dist/cjs/utils/replaceMailtoAmp.spec.js +22 -0
  41. package/dist/cjs/utils/specialCharacters.js +228 -0
  42. package/dist/cjs/utils/userAgent.js +28 -0
  43. package/dist/esm/MarkdownActions.js +186 -0
  44. package/dist/esm/MarkdownEditor.js +118 -0
  45. package/dist/esm/__fixtures__/FakeSdk.js +173 -0
  46. package/dist/esm/__fixtures__/asset/index.js +6 -0
  47. package/dist/esm/__fixtures__/content-type/index.js +2 -0
  48. package/dist/esm/__fixtures__/entry/index.js +5 -0
  49. package/dist/esm/__fixtures__/fixtures.js +6 -0
  50. package/dist/esm/__fixtures__/locale/index.js +15 -0
  51. package/dist/esm/__fixtures__/space/index.js +2 -0
  52. package/dist/esm/codemirrorImports.js +5 -0
  53. package/dist/esm/components/HeadingSelector.js +17 -0
  54. package/dist/esm/components/InsertLinkSelector.js +37 -0
  55. package/dist/esm/components/MarkdownBottomBar.js +46 -0
  56. package/dist/esm/components/MarkdownConstraints.js +25 -0
  57. package/dist/esm/components/MarkdownPreview.js +195 -0
  58. package/dist/esm/components/MarkdownTabs.js +74 -0
  59. package/dist/esm/components/MarkdownTextarea/CodeMirrorWrapper.js +329 -0
  60. package/dist/esm/components/MarkdownTextarea/MarkdownCommands.js +218 -0
  61. package/dist/esm/components/MarkdownTextarea/MarkdownTextarea.js +136 -0
  62. package/dist/esm/components/MarkdownTextarea/createMarkdownEditor.js +52 -0
  63. package/dist/esm/components/MarkdownToolbar.js +302 -0
  64. package/dist/esm/components/icons.js +112 -0
  65. package/dist/esm/dialogs/CheatsheetModalDialog.js +177 -0
  66. package/dist/esm/dialogs/ConfirmInsertAssetModalDialog.js +37 -0
  67. package/dist/esm/dialogs/EmdebExternalContentDialog.js +140 -0
  68. package/dist/esm/dialogs/InsertLinkModalDialog.js +92 -0
  69. package/dist/esm/dialogs/InsertTableModalDialog.js +78 -0
  70. package/dist/esm/dialogs/SpecialCharacterModalDialog.js +84 -0
  71. package/dist/esm/dialogs/ZenModeModalDialog.js +195 -0
  72. package/dist/esm/dialogs/openMarkdownDialog.js +72 -0
  73. package/dist/esm/dialogs/renderMarkdownDialog.js +59 -0
  74. package/dist/esm/index.js +5 -0
  75. package/dist/esm/types.js +10 -0
  76. package/dist/esm/utils/insertAssetLinks.js +99 -0
  77. package/dist/esm/utils/insertAssetLinks.spec.js +18 -0
  78. package/dist/esm/utils/isValidUrl.js +4 -0
  79. package/dist/esm/utils/linkOrganizer.js +152 -0
  80. package/dist/esm/utils/linkOrganizer.spec.js +53 -0
  81. package/dist/esm/utils/replaceMailtoAmp.js +5 -0
  82. package/dist/esm/utils/replaceMailtoAmp.spec.js +18 -0
  83. package/dist/esm/utils/specialCharacters.js +218 -0
  84. package/dist/esm/utils/userAgent.js +13 -0
  85. package/dist/{MarkdownActions.d.ts → types/MarkdownActions.d.ts} +38 -38
  86. package/dist/{MarkdownEditor.d.ts → types/MarkdownEditor.d.ts} +22 -22
  87. package/dist/types/__fixtures__/FakeSdk.d.ts +8 -0
  88. package/dist/types/__fixtures__/asset/index.d.ts +6 -0
  89. package/dist/types/__fixtures__/content-type/index.d.ts +2 -0
  90. package/dist/types/__fixtures__/entry/index.d.ts +5 -0
  91. package/dist/types/__fixtures__/fixtures.d.ts +6 -0
  92. package/dist/types/__fixtures__/locale/index.d.ts +42 -0
  93. package/dist/types/__fixtures__/space/index.d.ts +2 -0
  94. package/dist/{codemirrorImports.d.ts → types/codemirrorImports.d.ts} +5 -5
  95. package/dist/{components → types/components}/HeadingSelector.d.ts +7 -7
  96. package/dist/{components → types/components}/InsertLinkSelector.d.ts +9 -9
  97. package/dist/{components → types/components}/MarkdownBottomBar.d.ts +11 -11
  98. package/dist/{components → types/components}/MarkdownConstraints.d.ts +6 -6
  99. package/dist/{components → types/components}/MarkdownPreview.d.ts +14 -14
  100. package/dist/{components → types/components}/MarkdownTabs.d.ts +8 -8
  101. package/dist/{components → types/components}/MarkdownTextarea/CodeMirrorWrapper.d.ts +58 -58
  102. package/dist/{components → types/components}/MarkdownTextarea/MarkdownCommands.d.ts +33 -33
  103. package/dist/{components → types/components}/MarkdownTextarea/MarkdownTextarea.d.ts +17 -17
  104. package/dist/{components → types/components}/MarkdownTextarea/createMarkdownEditor.d.ts +55 -55
  105. package/dist/{components → types/components}/MarkdownToolbar.d.ts +12 -12
  106. package/dist/types/components/icons.d.ts +18 -0
  107. package/dist/{dialogs → types/dialogs}/CheatsheetModalDialog.d.ts +4 -4
  108. package/dist/{dialogs → types/dialogs}/ConfirmInsertAssetModalDialog.d.ts +23 -23
  109. package/dist/{dialogs → types/dialogs}/EmdebExternalContentDialog.d.ts +9 -9
  110. package/dist/{dialogs → types/dialogs}/InsertLinkModalDialog.d.ts +17 -17
  111. package/dist/{dialogs → types/dialogs}/InsertTableModalDialog.d.ts +13 -13
  112. package/dist/{dialogs → types/dialogs}/SpecialCharacterModalDialog.d.ts +9 -9
  113. package/dist/{dialogs → types/dialogs}/ZenModeModalDialog.d.ts +24 -24
  114. package/dist/{dialogs → types/dialogs}/openMarkdownDialog.d.ts +5 -5
  115. package/dist/{dialogs → types/dialogs}/renderMarkdownDialog.d.ts +8 -8
  116. package/dist/{index.d.ts → types/index.d.ts} +5 -5
  117. package/dist/{types.d.ts → types/types.d.ts} +75 -75
  118. package/dist/{utils → types/utils}/insertAssetLinks.d.ts +29 -29
  119. package/dist/types/utils/insertAssetLinks.spec.d.ts +1 -0
  120. package/dist/{utils → types/utils}/isValidUrl.d.ts +2 -2
  121. package/dist/{utils → types/utils}/linkOrganizer.d.ts +6 -6
  122. package/dist/types/utils/linkOrganizer.spec.d.ts +1 -0
  123. package/dist/{utils → types/utils}/replaceMailtoAmp.d.ts +1 -1
  124. package/dist/types/utils/replaceMailtoAmp.spec.d.ts +1 -0
  125. package/dist/{utils → types/utils}/specialCharacters.d.ts +4 -4
  126. package/dist/{utils → types/utils}/userAgent.d.ts +1 -1
  127. package/package.json +25 -11
  128. package/CHANGELOG.md +0 -314
  129. package/dist/components/icons.d.ts +0 -18
  130. package/dist/field-editor-markdown.cjs.development.js +0 -3609
  131. package/dist/field-editor-markdown.cjs.development.js.map +0 -1
  132. package/dist/field-editor-markdown.cjs.production.min.js +0 -216
  133. package/dist/field-editor-markdown.cjs.production.min.js.map +0 -1
  134. package/dist/field-editor-markdown.esm.js +0 -3599
  135. package/dist/field-editor-markdown.esm.js.map +0 -1
  136. package/dist/index.js +0 -8
@@ -0,0 +1,195 @@
1
+ import * as React from 'react';
2
+ import tokens from '@contentful/f36-tokens';
3
+ import DOMPurify from 'dompurify';
4
+ import { css, cx } from 'emotion';
5
+ import Markdown from 'markdown-to-jsx';
6
+ import { replaceMailtoAmp } from '../utils/replaceMailtoAmp';
7
+ const styles = {
8
+ root: css`
9
+ border: 1px solid ${tokens.gray400};
10
+ border-width: 0 1px;
11
+ word-wrap: break-word;
12
+ overflow-wrap: break-word;
13
+ min-height: 300px;
14
+ padding: ${tokens.spacingL};
15
+ font-size: ${tokens.fontSizeM};
16
+ font-family: ${tokens.fontStackPrimary};
17
+ line-height: ${tokens.lineHeightDefault};
18
+ color: ${tokens.gray700};
19
+ white-space: pre-line;
20
+
21
+ h1,
22
+ h2,
23
+ h3,
24
+ h4,
25
+ h5,
26
+ h6 {
27
+ margin-top: ${tokens.spacingL};
28
+ margin-bottom: ${tokens.spacingM};
29
+ color: ${tokens.gray900};
30
+ }
31
+
32
+ h1:first-child,
33
+ h2:first-child,
34
+ h3:first-child,
35
+ h4:first-child,
36
+ h5:first-child,
37
+ h6:first-child {
38
+ margin-top: 0;
39
+ }
40
+
41
+ h1 {
42
+ font-size: 1.9em;
43
+ }
44
+ h2 {
45
+ font-size: 1.75em;
46
+ }
47
+ h3 {
48
+ font-size: 1.6em;
49
+ }
50
+ h4 {
51
+ font-size: 1.45em;
52
+ }
53
+ h5 {
54
+ font-size: 1.3em;
55
+ }
56
+ h6 {
57
+ font-size: 1.15em;
58
+ }
59
+
60
+ p {
61
+ margin-top: 0;
62
+ margin-bottom: ${tokens.spacingM};
63
+ }
64
+
65
+ ul,
66
+ ol {
67
+ margin: ${tokens.spacingS} 0;
68
+ padding-left: ${tokens.spacingM};
69
+ }
70
+ ul > li {
71
+ list-style-type: disc;
72
+ margin-bottom: 0;
73
+ }
74
+
75
+ ol > li {
76
+ list-style-type: decimal;
77
+ margin-bottom: 0;
78
+ }
79
+
80
+ table {
81
+ table-layout: fixed;
82
+ border-right-width: 0;
83
+ border-bottom-width: 0;
84
+ width: 80%;
85
+ margin: ${tokens.spacingM} auto;
86
+ border-spacing: 0;
87
+ border-collapse: collapse;
88
+ border: 1px solid ${tokens.gray300};
89
+ }
90
+
91
+ table th,
92
+ table td {
93
+ padding: 5px;
94
+ border-left-width: 0;
95
+ border-top-width: 0;
96
+ }
97
+
98
+ table th {
99
+ background: ${tokens.gray200};
100
+ }
101
+
102
+ table td {
103
+ border: 1px solid ${tokens.gray300};
104
+ }
105
+
106
+ a {
107
+ color: ${tokens.blue500};
108
+ }
109
+
110
+ hr {
111
+ margin-top: ${tokens.spacingL};
112
+ margin-bottom: ${tokens.spacingL};
113
+ height: 1px;
114
+ background-color: ${tokens.gray300};
115
+ border: none;
116
+ }
117
+
118
+ blockquote {
119
+ border-left: 4px solid ${tokens.gray200};
120
+ padding-left: ${tokens.spacingL};
121
+ margin: 0;
122
+ margin-top: ${tokens.spacingM};
123
+ font-style: italic;
124
+ }
125
+
126
+ img {
127
+ margin: ${tokens.spacingM} auto;
128
+ display: block;
129
+ max-width: 80%;
130
+ max-height: 250px;
131
+ }
132
+
133
+ pre code {
134
+ font-size: ${tokens.fontSizeS};
135
+ font-family: ${tokens.fontStackMonospace};
136
+ }
137
+
138
+ .embedly-card {
139
+ margin: ${tokens.spacingM} auto;
140
+ display: block;
141
+ }
142
+ `,
143
+ framed: css({
144
+ height: '100%',
145
+ maxHeight: '500px',
146
+ overflowY: 'auto'
147
+ }),
148
+ zen: css({
149
+ maxWidth: '650px',
150
+ margin: '0 auto',
151
+ border: 'none !important'
152
+ }),
153
+ rtl: css({
154
+ direction: 'rtl'
155
+ })
156
+ };
157
+ function MarkdownLink(props) {
158
+ const { Embedly , children , ...rest } = props;
159
+ if (props.className === 'embedly-card' && Embedly) {
160
+ return React.createElement(Embedly, {
161
+ url: props.href
162
+ });
163
+ }
164
+ return React.createElement("a", {
165
+ ...rest,
166
+ target: "_blank",
167
+ rel: "noopener noreferrer"
168
+ }, children);
169
+ }
170
+ export const MarkdownPreview = React.memo((props)=>{
171
+ const className = cx(styles.root, props.minHeight !== undefined ? css({
172
+ minHeight: props.minHeight
173
+ }) : undefined, props.mode === 'default' ? styles.framed : styles.zen, props.direction === 'rtl' ? styles.rtl : undefined);
174
+ const cleanHTML = React.useMemo(()=>{
175
+ return replaceMailtoAmp(DOMPurify.sanitize(props.value));
176
+ }, [
177
+ props.value
178
+ ]);
179
+ return React.createElement("div", {
180
+ className: className,
181
+ "data-test-id": "markdown-preview"
182
+ }, React.createElement(Markdown, {
183
+ options: {
184
+ overrides: {
185
+ a: {
186
+ component: MarkdownLink,
187
+ props: {
188
+ Embedly: props.previewComponents?.embedly
189
+ }
190
+ }
191
+ }
192
+ }
193
+ }, cleanHTML));
194
+ });
195
+ MarkdownPreview.displayName = 'MarkdownPreview';
@@ -0,0 +1,74 @@
1
+ import * as React from 'react';
2
+ import tokens from '@contentful/f36-tokens';
3
+ import { css, cx } from 'emotion';
4
+ const styles = {
5
+ root: css({
6
+ display: 'flex',
7
+ zIndex: 10,
8
+ flexDirection: 'row',
9
+ justifyContent: 'flex-end',
10
+ overflow: 'hidden',
11
+ marginBottom: '-1px',
12
+ fontSize: tokens.fontSizeM
13
+ }),
14
+ tab: css({
15
+ cursor: 'pointer',
16
+ color: tokens.gray700,
17
+ padding: tokens.spacingXs,
18
+ minWidth: '70px',
19
+ border: `1px solid ${tokens.gray400}`,
20
+ borderTopLeftRadius: tokens.borderRadiusSmall,
21
+ borderTopRightRadius: tokens.borderRadiusSmall,
22
+ marginLeft: tokens.spacingXs,
23
+ textAlign: 'center',
24
+ backgroundColor: tokens.gray100,
25
+ borderBottomColor: tokens.gray100,
26
+ outline: 'none',
27
+ '&:focus': {
28
+ boxShadow: tokens.boxShadowHeavy
29
+ },
30
+ transition: `all ${tokens.transitionEasingDefault} ${tokens.transitionDurationShort}`
31
+ }),
32
+ inactiveTab: css({
33
+ background: tokens.gray200,
34
+ borderBottomColor: tokens.gray400,
35
+ '&:hover': {
36
+ background: tokens.gray300
37
+ }
38
+ })
39
+ };
40
+ function MarkdownTabItem(props) {
41
+ return React.createElement("div", {
42
+ className: cx(styles.tab, {
43
+ [styles.inactiveTab]: props.isActive === false
44
+ }),
45
+ onClick: ()=>{
46
+ props.onSelect(props.name);
47
+ },
48
+ onKeyDown: (e)=>{
49
+ if (e.keyCode === 13) {
50
+ props.onSelect(props.name);
51
+ }
52
+ },
53
+ tabIndex: 0,
54
+ role: "tab",
55
+ "aria-controls": props.name,
56
+ "aria-selected": props.isActive === true,
57
+ "data-test-id": props.testId
58
+ }, props.children);
59
+ }
60
+ export function MarkdownTabs(props) {
61
+ return React.createElement("div", {
62
+ className: styles.root
63
+ }, React.createElement(MarkdownTabItem, {
64
+ name: "editor",
65
+ onSelect: props.onSelect,
66
+ isActive: props.active === 'editor',
67
+ testId: "markdown-tab-md"
68
+ }, "Editor"), React.createElement(MarkdownTabItem, {
69
+ name: "preview",
70
+ onSelect: props.onSelect,
71
+ isActive: props.active === 'preview',
72
+ testId: "markdown-tab-preview"
73
+ }, "Preview"));
74
+ }
@@ -0,0 +1,329 @@
1
+ import CodeMirror from 'codemirror';
2
+ import 'codemirror/addon/edit/matchbrackets';
3
+ import throttle from 'lodash/throttle';
4
+ import transform from 'lodash/transform';
5
+ import * as userAgent from '../../utils/userAgent';
6
+ function stripUnit(value) {
7
+ if (typeof value !== 'string') return value;
8
+ const cssRegex = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;
9
+ const matchedValue = value.match(cssRegex);
10
+ if (!matchedValue) {
11
+ throw new Error("Couldn't match unit in given string");
12
+ }
13
+ return parseFloat(value);
14
+ }
15
+ export function create(host, options) {
16
+ const { direction , fixedHeight , height , readOnly } = options || {};
17
+ let initializedWithValue = false;
18
+ const LF = '\n';
19
+ const EDITOR_SIZE = {
20
+ min: height ? stripUnit(height) : 300,
21
+ max: 500,
22
+ shift: 50
23
+ };
24
+ const cm = CodeMirror(host, {
25
+ direction,
26
+ readOnly,
27
+ mode: 'markdown',
28
+ lineNumbers: false,
29
+ undoDepth: 200,
30
+ matchBrackets: true,
31
+ lineWrapping: true,
32
+ lineSeparator: null,
33
+ theme: 'elegant',
34
+ tabSize: 2,
35
+ indentWithTabs: false,
36
+ indentUnit: 2,
37
+ autoRefresh: true,
38
+ spellcheck: true,
39
+ inputStyle: 'contenteditable'
40
+ });
41
+ cm.setSize('100%', EDITOR_SIZE.min);
42
+ if (!fixedHeight) {
43
+ cm.on('change', throttle(assureHeight, 150));
44
+ }
45
+ cm.setOption('extraKeys', {
46
+ Tab: function() {
47
+ replaceSelectedText(getIndentation());
48
+ },
49
+ Enter: 'newlineAndIndentContinueMarkdownList',
50
+ Esc: ()=>{
51
+ cm.getInputField().blur();
52
+ }
53
+ });
54
+ return {
55
+ destroy,
56
+ disable,
57
+ enable,
58
+ attachEvent,
59
+ addKeyShortcuts,
60
+ setValue,
61
+ cmd,
62
+ moveToLineBeginning,
63
+ moveIfNotEmpty,
64
+ restoreCursor,
65
+ moveToLineEnd,
66
+ usePrimarySelection,
67
+ focus,
68
+ select,
69
+ selectBackwards,
70
+ selectAll: ()=>cm.execCommand('selectAll'),
71
+ extendSelectionBy,
72
+ insertAtCursor,
73
+ insertAtLineBeginning,
74
+ wrapSelection,
75
+ removeFromLineBeginning,
76
+ removeSelectedText,
77
+ replaceSelectedText,
78
+ getCursor,
79
+ setCursor,
80
+ getSelection,
81
+ getLine,
82
+ isLineEmpty,
83
+ getSelectedText,
84
+ getSelectionLength,
85
+ getCurrentLine,
86
+ getCurrentLineNumber,
87
+ getCurrentCharacter,
88
+ getCurrentLineLength,
89
+ lineStartsWith,
90
+ getIndentation,
91
+ getNl,
92
+ getValue,
93
+ getLinesCount,
94
+ getHistorySize,
95
+ setReadOnly: (value)=>cm.setOption('readOnly', value),
96
+ getHistory: ()=>cm.getHistory(),
97
+ setHistory: (history)=>cm.setHistory(history),
98
+ setFullsize: ()=>{
99
+ cm.setSize('100%', '100%');
100
+ cm.refresh();
101
+ },
102
+ refresh: ()=>cm.refresh()
103
+ };
104
+ function destroy() {
105
+ cm.toTextArea();
106
+ }
107
+ function disable() {
108
+ cm.setOption('readOnly', 'nocursor');
109
+ }
110
+ function enable() {
111
+ cm.setOption('readOnly', false);
112
+ }
113
+ function assureHeight() {
114
+ const current = cm.heightAtLine(cm.lastLine(), 'local') + EDITOR_SIZE.shift;
115
+ let next = current;
116
+ if (current < EDITOR_SIZE.min) {
117
+ next = EDITOR_SIZE.min;
118
+ }
119
+ if (current > EDITOR_SIZE.max) {
120
+ next = EDITOR_SIZE.max;
121
+ }
122
+ cm.setSize('100%', next);
123
+ }
124
+ function attachEvent(name, fn, throttleInterval) {
125
+ if (throttleInterval) {
126
+ fn = throttle(fn, throttleInterval);
127
+ }
128
+ cm.on(name, fn);
129
+ }
130
+ function addKeyShortcuts(map) {
131
+ const ctrlKey = userAgent.getCtrlKey();
132
+ cm.addKeyMap(transform(map, (acc, value, key)=>{
133
+ acc[ctrlKey + '-' + key] = value;
134
+ }, {}));
135
+ }
136
+ function setValue(value) {
137
+ value = value || '';
138
+ if (getValue() === value) {
139
+ return;
140
+ }
141
+ const line = getCurrentLineNumber();
142
+ const ch = getCurrentCharacter();
143
+ cm.setValue(value);
144
+ restoreCursor(ch, line, true);
145
+ if (!initializedWithValue) {
146
+ cm.clearHistory();
147
+ initializedWithValue = true;
148
+ }
149
+ }
150
+ function cmd(name) {
151
+ cm.execCommand(name);
152
+ cm.focus();
153
+ }
154
+ function moveToLineBeginning(lineNumber) {
155
+ cm.setCursor({
156
+ line: defaultToCurrentLineNumber(lineNumber),
157
+ ch: 0
158
+ });
159
+ cm.focus();
160
+ }
161
+ function moveIfNotEmpty() {
162
+ if (getCurrentLineLength() < 1) {
163
+ return;
164
+ }
165
+ const next = getCurrentLineNumber() + 1;
166
+ if (cm.lastLine() < next) {
167
+ moveToLineEnd();
168
+ insertAtCursor(getNl());
169
+ }
170
+ moveToLineBeginning(next);
171
+ }
172
+ function restoreCursor(character, lineNumber, noFocus) {
173
+ cm.setCursor(defaultToCurrentLineNumber(lineNumber), character, {
174
+ scroll: !noFocus
175
+ });
176
+ if (!noFocus) {
177
+ cm.focus();
178
+ }
179
+ }
180
+ function moveToLineEnd(lineNumber) {
181
+ cm.setCursor({
182
+ line: defaultToCurrentLineNumber(lineNumber),
183
+ ch: getCurrentLineLength()
184
+ });
185
+ cm.focus();
186
+ }
187
+ function defaultToCurrentLineNumber(lineNumber) {
188
+ if (lineNumber === 0 || lineNumber !== undefined && lineNumber > 0) {
189
+ return lineNumber;
190
+ }
191
+ return getCurrentLineNumber();
192
+ }
193
+ function usePrimarySelection() {
194
+ cmd('singleSelection');
195
+ }
196
+ function focus() {
197
+ cm.focus();
198
+ }
199
+ function select(from, to) {
200
+ cm.setSelection(from, to);
201
+ cm.focus();
202
+ }
203
+ function selectBackwards(skip, len) {
204
+ select(getPos(-skip - len), getPos(-skip));
205
+ function getPos(modifier) {
206
+ return {
207
+ line: getCurrentLineNumber(),
208
+ ch: getCurrentCharacter() + modifier
209
+ };
210
+ }
211
+ }
212
+ function extendSelectionBy(modifier) {
213
+ select(getPos('anchor', 0), getPos('head', modifier));
214
+ function getPos(prop, modifier) {
215
+ const selection = getSelection();
216
+ if (!selection) {
217
+ return {
218
+ line: 0,
219
+ ch: 0
220
+ };
221
+ }
222
+ return {
223
+ line: selection[prop].line,
224
+ ch: selection[prop].ch + modifier
225
+ };
226
+ }
227
+ }
228
+ function insertAtCursor(text) {
229
+ cm.replaceRange(text, cm.getCursor());
230
+ cm.focus();
231
+ }
232
+ function insertAtLineBeginning(text) {
233
+ const initialCh = getCurrentCharacter();
234
+ moveToLineBeginning();
235
+ insertAtCursor(text);
236
+ restoreCursor(initialCh + text.length);
237
+ cm.focus();
238
+ }
239
+ function wrapSelection(wrapper) {
240
+ const replacement = wrapper + getSelectedText() + wrapper;
241
+ const selection = getSelection();
242
+ if (selection) {
243
+ cm.replaceRange(replacement, selection.anchor, selection?.head);
244
+ cm.focus();
245
+ }
246
+ }
247
+ function removeFromLineBeginning(charCount) {
248
+ const lineNumber = getCurrentLineNumber();
249
+ cm.replaceRange('', {
250
+ line: lineNumber,
251
+ ch: 0
252
+ }, {
253
+ line: lineNumber,
254
+ ch: charCount
255
+ });
256
+ cm.focus();
257
+ }
258
+ function removeSelectedText() {
259
+ cm.replaceSelection('');
260
+ cm.focus();
261
+ }
262
+ function replaceSelectedText(replacement, select) {
263
+ cm.replaceSelection(replacement, select);
264
+ cm.focus();
265
+ }
266
+ function getCursor() {
267
+ return cm.getCursor();
268
+ }
269
+ function setCursor(cursor) {
270
+ cm.setCursor(cursor);
271
+ }
272
+ function getSelection() {
273
+ const selections = cm.listSelections();
274
+ if (!cm.somethingSelected() || !selections || selections.length < 1) {
275
+ return null;
276
+ }
277
+ return selections[0];
278
+ }
279
+ function getLine(lineNumber) {
280
+ return cm.getLine(lineNumber) || '';
281
+ }
282
+ function isLineEmpty(lineNumber) {
283
+ const n = defaultToCurrentLineNumber(lineNumber);
284
+ return n > -1 && getLine(n).length < 1 && n < cm.lineCount();
285
+ }
286
+ function getLinesCount() {
287
+ return cm.lineCount();
288
+ }
289
+ function getSelectedText() {
290
+ return getSelection() ? cm.getSelection() : '';
291
+ }
292
+ function getSelectionLength() {
293
+ return getSelectedText().length;
294
+ }
295
+ function getCurrentLine() {
296
+ return getLine(getCurrentLineNumber());
297
+ }
298
+ function getCurrentLineNumber() {
299
+ return cm.getCursor().line;
300
+ }
301
+ function getCurrentCharacter() {
302
+ return cm.getCursor().ch;
303
+ }
304
+ function getCurrentLineLength() {
305
+ return getCurrentLine().length;
306
+ }
307
+ function lineStartsWith(text) {
308
+ return getCurrentLine().startsWith(text);
309
+ }
310
+ function getIndentation() {
311
+ return repeat(' ', cm.getOption('indentUnit') ?? 0);
312
+ }
313
+ function getNl(n = 1) {
314
+ if (n < 1) {
315
+ return '';
316
+ }
317
+ return repeat(LF, n);
318
+ }
319
+ function getValue() {
320
+ return cm.getValue() || '';
321
+ }
322
+ function getHistorySize(which) {
323
+ const history = cm.historySize();
324
+ return which ? history[which] : history;
325
+ }
326
+ function repeat(what, n) {
327
+ return new Array(n + 1).join(what);
328
+ }
329
+ }