@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.
- package/dist/cjs/MarkdownActions.js +235 -0
- package/dist/cjs/MarkdownEditor.js +180 -0
- package/dist/cjs/__fixtures__/FakeSdk.js +183 -0
- package/dist/cjs/__fixtures__/asset/index.js +37 -0
- package/dist/cjs/__fixtures__/content-type/index.js +16 -0
- package/dist/cjs/__fixtures__/entry/index.js +33 -0
- package/dist/cjs/__fixtures__/fixtures.js +71 -0
- package/dist/cjs/__fixtures__/locale/index.js +40 -0
- package/dist/cjs/__fixtures__/space/index.js +16 -0
- package/dist/cjs/codemirrorImports.js +9 -0
- package/dist/cjs/components/HeadingSelector.js +66 -0
- package/dist/cjs/components/InsertLinkSelector.js +86 -0
- package/dist/cjs/components/MarkdownBottomBar.js +111 -0
- package/dist/cjs/components/MarkdownConstraints.js +79 -0
- package/dist/cjs/components/MarkdownPreview.js +249 -0
- package/dist/cjs/components/MarkdownTabs.js +128 -0
- package/dist/cjs/components/MarkdownTextarea/CodeMirrorWrapper.js +383 -0
- package/dist/cjs/components/MarkdownTextarea/MarkdownCommands.js +233 -0
- package/dist/cjs/components/MarkdownTextarea/MarkdownTextarea.js +190 -0
- package/dist/cjs/components/MarkdownTextarea/createMarkdownEditor.js +101 -0
- package/dist/cjs/components/MarkdownToolbar.js +367 -0
- package/dist/cjs/components/icons.js +193 -0
- package/dist/cjs/dialogs/CheatsheetModalDialog.js +239 -0
- package/dist/cjs/dialogs/ConfirmInsertAssetModalDialog.js +94 -0
- package/dist/cjs/dialogs/EmdebExternalContentDialog.js +202 -0
- package/dist/cjs/dialogs/InsertLinkModalDialog.js +149 -0
- package/dist/cjs/dialogs/InsertTableModalDialog.js +140 -0
- package/dist/cjs/dialogs/SpecialCharacterModalDialog.js +146 -0
- package/dist/cjs/dialogs/ZenModeModalDialog.js +257 -0
- package/dist/cjs/dialogs/openMarkdownDialog.js +121 -0
- package/dist/cjs/dialogs/renderMarkdownDialog.js +108 -0
- package/dist/cjs/index.js +29 -0
- package/dist/cjs/types.js +20 -0
- package/dist/cjs/utils/insertAssetLinks.js +122 -0
- package/dist/cjs/utils/insertAssetLinks.spec.js +22 -0
- package/dist/cjs/utils/isValidUrl.js +22 -0
- package/dist/cjs/utils/linkOrganizer.js +187 -0
- package/dist/cjs/utils/linkOrganizer.spec.js +96 -0
- package/dist/cjs/utils/replaceMailtoAmp.js +15 -0
- package/dist/cjs/utils/replaceMailtoAmp.spec.js +22 -0
- package/dist/cjs/utils/specialCharacters.js +228 -0
- package/dist/cjs/utils/userAgent.js +28 -0
- package/dist/esm/MarkdownActions.js +186 -0
- package/dist/esm/MarkdownEditor.js +118 -0
- package/dist/esm/__fixtures__/FakeSdk.js +173 -0
- package/dist/esm/__fixtures__/asset/index.js +6 -0
- package/dist/esm/__fixtures__/content-type/index.js +2 -0
- package/dist/esm/__fixtures__/entry/index.js +5 -0
- package/dist/esm/__fixtures__/fixtures.js +6 -0
- package/dist/esm/__fixtures__/locale/index.js +15 -0
- package/dist/esm/__fixtures__/space/index.js +2 -0
- package/dist/esm/codemirrorImports.js +5 -0
- package/dist/esm/components/HeadingSelector.js +17 -0
- package/dist/esm/components/InsertLinkSelector.js +37 -0
- package/dist/esm/components/MarkdownBottomBar.js +46 -0
- package/dist/esm/components/MarkdownConstraints.js +25 -0
- package/dist/esm/components/MarkdownPreview.js +195 -0
- package/dist/esm/components/MarkdownTabs.js +74 -0
- package/dist/esm/components/MarkdownTextarea/CodeMirrorWrapper.js +329 -0
- package/dist/esm/components/MarkdownTextarea/MarkdownCommands.js +218 -0
- package/dist/esm/components/MarkdownTextarea/MarkdownTextarea.js +136 -0
- package/dist/esm/components/MarkdownTextarea/createMarkdownEditor.js +52 -0
- package/dist/esm/components/MarkdownToolbar.js +302 -0
- package/dist/esm/components/icons.js +112 -0
- package/dist/esm/dialogs/CheatsheetModalDialog.js +177 -0
- package/dist/esm/dialogs/ConfirmInsertAssetModalDialog.js +37 -0
- package/dist/esm/dialogs/EmdebExternalContentDialog.js +140 -0
- package/dist/esm/dialogs/InsertLinkModalDialog.js +92 -0
- package/dist/esm/dialogs/InsertTableModalDialog.js +78 -0
- package/dist/esm/dialogs/SpecialCharacterModalDialog.js +84 -0
- package/dist/esm/dialogs/ZenModeModalDialog.js +195 -0
- package/dist/esm/dialogs/openMarkdownDialog.js +72 -0
- package/dist/esm/dialogs/renderMarkdownDialog.js +59 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/types.js +10 -0
- package/dist/esm/utils/insertAssetLinks.js +99 -0
- package/dist/esm/utils/insertAssetLinks.spec.js +18 -0
- package/dist/esm/utils/isValidUrl.js +4 -0
- package/dist/esm/utils/linkOrganizer.js +152 -0
- package/dist/esm/utils/linkOrganizer.spec.js +53 -0
- package/dist/esm/utils/replaceMailtoAmp.js +5 -0
- package/dist/esm/utils/replaceMailtoAmp.spec.js +18 -0
- package/dist/esm/utils/specialCharacters.js +218 -0
- package/dist/esm/utils/userAgent.js +13 -0
- package/dist/{MarkdownActions.d.ts → types/MarkdownActions.d.ts} +38 -38
- package/dist/{MarkdownEditor.d.ts → types/MarkdownEditor.d.ts} +22 -22
- package/dist/types/__fixtures__/FakeSdk.d.ts +8 -0
- package/dist/types/__fixtures__/asset/index.d.ts +6 -0
- package/dist/types/__fixtures__/content-type/index.d.ts +2 -0
- package/dist/types/__fixtures__/entry/index.d.ts +5 -0
- package/dist/types/__fixtures__/fixtures.d.ts +6 -0
- package/dist/types/__fixtures__/locale/index.d.ts +42 -0
- package/dist/types/__fixtures__/space/index.d.ts +2 -0
- package/dist/{codemirrorImports.d.ts → types/codemirrorImports.d.ts} +5 -5
- package/dist/{components → types/components}/HeadingSelector.d.ts +7 -7
- package/dist/{components → types/components}/InsertLinkSelector.d.ts +9 -9
- package/dist/{components → types/components}/MarkdownBottomBar.d.ts +11 -11
- package/dist/{components → types/components}/MarkdownConstraints.d.ts +6 -6
- package/dist/{components → types/components}/MarkdownPreview.d.ts +14 -14
- package/dist/{components → types/components}/MarkdownTabs.d.ts +8 -8
- package/dist/{components → types/components}/MarkdownTextarea/CodeMirrorWrapper.d.ts +58 -58
- package/dist/{components → types/components}/MarkdownTextarea/MarkdownCommands.d.ts +33 -33
- package/dist/{components → types/components}/MarkdownTextarea/MarkdownTextarea.d.ts +17 -17
- package/dist/{components → types/components}/MarkdownTextarea/createMarkdownEditor.d.ts +55 -55
- package/dist/{components → types/components}/MarkdownToolbar.d.ts +12 -12
- package/dist/types/components/icons.d.ts +18 -0
- package/dist/{dialogs → types/dialogs}/CheatsheetModalDialog.d.ts +4 -4
- package/dist/{dialogs → types/dialogs}/ConfirmInsertAssetModalDialog.d.ts +23 -23
- package/dist/{dialogs → types/dialogs}/EmdebExternalContentDialog.d.ts +9 -9
- package/dist/{dialogs → types/dialogs}/InsertLinkModalDialog.d.ts +17 -17
- package/dist/{dialogs → types/dialogs}/InsertTableModalDialog.d.ts +13 -13
- package/dist/{dialogs → types/dialogs}/SpecialCharacterModalDialog.d.ts +9 -9
- package/dist/{dialogs → types/dialogs}/ZenModeModalDialog.d.ts +24 -24
- package/dist/{dialogs → types/dialogs}/openMarkdownDialog.d.ts +5 -5
- package/dist/{dialogs → types/dialogs}/renderMarkdownDialog.d.ts +8 -8
- package/dist/{index.d.ts → types/index.d.ts} +5 -5
- package/dist/{types.d.ts → types/types.d.ts} +75 -75
- package/dist/{utils → types/utils}/insertAssetLinks.d.ts +29 -29
- package/dist/types/utils/insertAssetLinks.spec.d.ts +1 -0
- package/dist/{utils → types/utils}/isValidUrl.d.ts +2 -2
- package/dist/{utils → types/utils}/linkOrganizer.d.ts +6 -6
- package/dist/types/utils/linkOrganizer.spec.d.ts +1 -0
- package/dist/{utils → types/utils}/replaceMailtoAmp.d.ts +1 -1
- package/dist/types/utils/replaceMailtoAmp.spec.d.ts +1 -0
- package/dist/{utils → types/utils}/specialCharacters.d.ts +4 -4
- package/dist/{utils → types/utils}/userAgent.d.ts +1 -1
- package/package.json +25 -11
- package/CHANGELOG.md +0 -314
- package/dist/components/icons.d.ts +0 -18
- package/dist/field-editor-markdown.cjs.development.js +0 -3609
- package/dist/field-editor-markdown.cjs.development.js.map +0 -1
- package/dist/field-editor-markdown.cjs.production.min.js +0 -216
- package/dist/field-editor-markdown.cjs.production.min.js.map +0 -1
- package/dist/field-editor-markdown.esm.js +0 -3599
- package/dist/field-editor-markdown.esm.js.map +0 -1
- package/dist/index.js +0 -8
|
@@ -1,3609 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
6
|
-
|
|
7
|
-
require('codemirror/mode/markdown/markdown');
|
|
8
|
-
require('codemirror/mode/xml/xml');
|
|
9
|
-
require('codemirror/addon/edit/continuelist');
|
|
10
|
-
require('codemirror/addon/mode/overlay');
|
|
11
|
-
require('codemirror/addon/display/autorefresh');
|
|
12
|
-
var React = require('react');
|
|
13
|
-
var React__default = _interopDefault(React);
|
|
14
|
-
var tokens = _interopDefault(require('@contentful/f36-tokens'));
|
|
15
|
-
var fieldEditorShared = require('@contentful/field-editor-shared');
|
|
16
|
-
var emotion = require('emotion');
|
|
17
|
-
var f36Components = require('@contentful/f36-components');
|
|
18
|
-
var DOMPurify = _interopDefault(require('dompurify'));
|
|
19
|
-
var Markdown = _interopDefault(require('markdown-to-jsx'));
|
|
20
|
-
var CodeMirror = _interopDefault(require('codemirror'));
|
|
21
|
-
require('codemirror/addon/edit/matchbrackets');
|
|
22
|
-
var throttle = _interopDefault(require('lodash/throttle'));
|
|
23
|
-
var transform = _interopDefault(require('lodash/transform'));
|
|
24
|
-
var get = _interopDefault(require('lodash/get'));
|
|
25
|
-
var max = _interopDefault(require('lodash/max'));
|
|
26
|
-
var min = _interopDefault(require('lodash/min'));
|
|
27
|
-
var range = _interopDefault(require('lodash/range'));
|
|
28
|
-
var times = _interopDefault(require('lodash/times'));
|
|
29
|
-
var repeat = _interopDefault(require('lodash/repeat'));
|
|
30
|
-
var f36Icons = require('@contentful/f36-icons');
|
|
31
|
-
var inRange = _interopDefault(require('lodash/inRange'));
|
|
32
|
-
var isObject = _interopDefault(require('lodash/isObject'));
|
|
33
|
-
var extend = _interopDefault(require('lodash/extend'));
|
|
34
|
-
var isString = _interopDefault(require('lodash/isString'));
|
|
35
|
-
var isFinite = _interopDefault(require('lodash/isFinite'));
|
|
36
|
-
var forEach = _interopDefault(require('lodash/forEach'));
|
|
37
|
-
|
|
38
|
-
const styles = {
|
|
39
|
-
root: /*#__PURE__*/emotion.css({
|
|
40
|
-
display: 'flex',
|
|
41
|
-
justifyContent: 'space-between',
|
|
42
|
-
background: tokens.gray100,
|
|
43
|
-
border: `1px solid ${tokens.gray400}`,
|
|
44
|
-
borderBottomLeftRadius: tokens.borderRadiusSmall,
|
|
45
|
-
borderBottomRightRadius: tokens.borderRadiusSmall,
|
|
46
|
-
padding: `${tokens.spacingXs} ${tokens.spacingS}`
|
|
47
|
-
}),
|
|
48
|
-
help: /*#__PURE__*/emotion.css({
|
|
49
|
-
color: tokens.gray700,
|
|
50
|
-
fontSize: tokens.fontSizeS,
|
|
51
|
-
button: {
|
|
52
|
-
fontSize: tokens.fontSizeS,
|
|
53
|
-
lineHeight: 'inherit'
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
};
|
|
57
|
-
function MarkdownHelp(props) {
|
|
58
|
-
return React__default.createElement(f36Components.Paragraph, {
|
|
59
|
-
marginBottom: "none",
|
|
60
|
-
className: styles.help
|
|
61
|
-
}, "Format your text like a pro with the", ' ', React__default.createElement(f36Components.TextLink, {
|
|
62
|
-
as: "button",
|
|
63
|
-
testId: "open-markdown-cheatsheet-button",
|
|
64
|
-
onClick: () => {
|
|
65
|
-
props.onClick();
|
|
66
|
-
}
|
|
67
|
-
}, "markdown cheatsheet"), ".");
|
|
68
|
-
}
|
|
69
|
-
function MarkdownBottomBar(props) {
|
|
70
|
-
return React__default.createElement("div", {
|
|
71
|
-
className: styles.root
|
|
72
|
-
}, props.children);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const styles$1 = {
|
|
76
|
-
root: /*#__PURE__*/emotion.css({
|
|
77
|
-
display: 'flex',
|
|
78
|
-
justifyContent: 'space-between',
|
|
79
|
-
fontSize: tokens.fontSizeM,
|
|
80
|
-
marginTop: tokens.spacingXs,
|
|
81
|
-
color: tokens.gray700
|
|
82
|
-
})
|
|
83
|
-
};
|
|
84
|
-
function MarkdownConstraints(props) {
|
|
85
|
-
const constraints = fieldEditorShared.ConstraintsUtils.fromFieldValidations(props.sdk.field.validations, props.sdk.field.type);
|
|
86
|
-
const checkConstraint = fieldEditorShared.ConstraintsUtils.makeChecker(constraints);
|
|
87
|
-
return React__default.createElement("div", {
|
|
88
|
-
className: styles$1.root
|
|
89
|
-
}, React__default.createElement(fieldEditorShared.CharCounter, {
|
|
90
|
-
value: props.value,
|
|
91
|
-
checkConstraint: checkConstraint
|
|
92
|
-
}), React__default.createElement(fieldEditorShared.CharValidation, {
|
|
93
|
-
constraints: constraints
|
|
94
|
-
}));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// This code will replace '&' with '&' only inside the href attribute of the mailto link.
|
|
98
|
-
// Otherwise the mailto link will not work correctly
|
|
99
|
-
const replaceMailtoAmp = string => {
|
|
100
|
-
return string.replace(/href="mailto:[^"]*&/g, function (match) {
|
|
101
|
-
return match.replace(/&/g, '&');
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const styles$2 = {
|
|
106
|
-
root: emotion.css`
|
|
107
|
-
border: 1px solid ${tokens.gray400};
|
|
108
|
-
border-width: 0 1px;
|
|
109
|
-
word-wrap: break-word;
|
|
110
|
-
overflow-wrap: break-word;
|
|
111
|
-
min-height: 300px;
|
|
112
|
-
padding: ${tokens.spacingL};
|
|
113
|
-
font-size: ${tokens.fontSizeM};
|
|
114
|
-
font-family: ${tokens.fontStackPrimary};
|
|
115
|
-
line-height: ${tokens.lineHeightDefault};
|
|
116
|
-
color: ${tokens.gray700};
|
|
117
|
-
white-space: pre-line;
|
|
118
|
-
|
|
119
|
-
h1,
|
|
120
|
-
h2,
|
|
121
|
-
h3,
|
|
122
|
-
h4,
|
|
123
|
-
h5,
|
|
124
|
-
h6 {
|
|
125
|
-
margin-top: ${tokens.spacingL};
|
|
126
|
-
margin-bottom: ${tokens.spacingM};
|
|
127
|
-
color: ${tokens.gray900};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
h1:first-child,
|
|
131
|
-
h2:first-child,
|
|
132
|
-
h3:first-child,
|
|
133
|
-
h4:first-child,
|
|
134
|
-
h5:first-child,
|
|
135
|
-
h6:first-child {
|
|
136
|
-
margin-top: 0;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
h1 {
|
|
140
|
-
font-size: 1.9em;
|
|
141
|
-
}
|
|
142
|
-
h2 {
|
|
143
|
-
font-size: 1.75em;
|
|
144
|
-
}
|
|
145
|
-
h3 {
|
|
146
|
-
font-size: 1.6em;
|
|
147
|
-
}
|
|
148
|
-
h4 {
|
|
149
|
-
font-size: 1.45em;
|
|
150
|
-
}
|
|
151
|
-
h5 {
|
|
152
|
-
font-size: 1.3em;
|
|
153
|
-
}
|
|
154
|
-
h6 {
|
|
155
|
-
font-size: 1.15em;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
p {
|
|
159
|
-
margin-top: 0;
|
|
160
|
-
margin-bottom: ${tokens.spacingM};
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
ul,
|
|
164
|
-
ol {
|
|
165
|
-
margin: ${tokens.spacingS} 0;
|
|
166
|
-
padding-left: ${tokens.spacingM};
|
|
167
|
-
}
|
|
168
|
-
ul > li {
|
|
169
|
-
list-style-type: disc;
|
|
170
|
-
margin-bottom: 0;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
ol > li {
|
|
174
|
-
list-style-type: decimal;
|
|
175
|
-
margin-bottom: 0;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
table {
|
|
179
|
-
table-layout: fixed;
|
|
180
|
-
border-right-width: 0;
|
|
181
|
-
border-bottom-width: 0;
|
|
182
|
-
width: 80%;
|
|
183
|
-
margin: ${tokens.spacingM} auto;
|
|
184
|
-
border-spacing: 0;
|
|
185
|
-
border-collapse: collapse;
|
|
186
|
-
border: 1px solid ${tokens.gray300};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
table th,
|
|
190
|
-
table td {
|
|
191
|
-
padding: 5px;
|
|
192
|
-
border-left-width: 0;
|
|
193
|
-
border-top-width: 0;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
table th {
|
|
197
|
-
background: ${tokens.gray200};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
table td {
|
|
201
|
-
border: 1px solid ${tokens.gray300};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
a {
|
|
205
|
-
color: ${tokens.blue500};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
hr {
|
|
209
|
-
margin-top: ${tokens.spacingL};
|
|
210
|
-
margin-bottom: ${tokens.spacingL};
|
|
211
|
-
height: 1px;
|
|
212
|
-
background-color: ${tokens.gray300};
|
|
213
|
-
border: none;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
blockquote {
|
|
217
|
-
border-left: 4px solid ${tokens.gray200};
|
|
218
|
-
padding-left: ${tokens.spacingL};
|
|
219
|
-
margin: 0;
|
|
220
|
-
margin-top: ${tokens.spacingM};
|
|
221
|
-
font-style: italic;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
img {
|
|
225
|
-
margin: ${tokens.spacingM} auto;
|
|
226
|
-
display: block;
|
|
227
|
-
max-width: 80%;
|
|
228
|
-
max-height: 250px;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
pre code {
|
|
232
|
-
font-size: ${tokens.fontSizeS};
|
|
233
|
-
font-family: ${tokens.fontStackMonospace};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.embedly-card {
|
|
237
|
-
margin: ${tokens.spacingM} auto;
|
|
238
|
-
display: block;
|
|
239
|
-
}
|
|
240
|
-
`,
|
|
241
|
-
framed: /*#__PURE__*/emotion.css({
|
|
242
|
-
height: '100%',
|
|
243
|
-
maxHeight: '500px',
|
|
244
|
-
overflowY: 'auto'
|
|
245
|
-
}),
|
|
246
|
-
zen: /*#__PURE__*/emotion.css({
|
|
247
|
-
maxWidth: '650px',
|
|
248
|
-
margin: '0 auto',
|
|
249
|
-
border: 'none !important'
|
|
250
|
-
}),
|
|
251
|
-
rtl: /*#__PURE__*/emotion.css({
|
|
252
|
-
direction: 'rtl'
|
|
253
|
-
})
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
function MarkdownLink(props) {
|
|
257
|
-
const {
|
|
258
|
-
Embedly,
|
|
259
|
-
children,
|
|
260
|
-
...rest
|
|
261
|
-
} = props;
|
|
262
|
-
|
|
263
|
-
if (props.className === 'embedly-card' && Embedly) {
|
|
264
|
-
return React__default.createElement(Embedly, {
|
|
265
|
-
url: props.href
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return React__default.createElement("a", { ...rest,
|
|
270
|
-
target: "_blank",
|
|
271
|
-
rel: "noopener noreferrer"
|
|
272
|
-
}, children);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const MarkdownPreview = /*#__PURE__*/React__default.memo(props => {
|
|
276
|
-
var _props$previewCompone;
|
|
277
|
-
|
|
278
|
-
const className = emotion.cx(styles$2.root, props.minHeight !== undefined ? emotion.css({
|
|
279
|
-
minHeight: props.minHeight
|
|
280
|
-
}) : undefined, props.mode === 'default' ? styles$2.framed : styles$2.zen, props.direction === 'rtl' ? styles$2.rtl : undefined); // See the list of allowed Tags here:
|
|
281
|
-
// https://github.com/cure53/DOMPurify/blob/main/src/tags.js#L3-L121
|
|
282
|
-
|
|
283
|
-
const cleanHTML = React__default.useMemo(() => {
|
|
284
|
-
return replaceMailtoAmp(DOMPurify.sanitize(props.value));
|
|
285
|
-
}, [props.value]);
|
|
286
|
-
return React__default.createElement("div", {
|
|
287
|
-
className: className,
|
|
288
|
-
"data-test-id": "markdown-preview"
|
|
289
|
-
}, React__default.createElement(Markdown, {
|
|
290
|
-
options: {
|
|
291
|
-
overrides: {
|
|
292
|
-
a: {
|
|
293
|
-
// eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/no-explicit-any
|
|
294
|
-
component: MarkdownLink,
|
|
295
|
-
props: {
|
|
296
|
-
Embedly: (_props$previewCompone = props.previewComponents) == null ? void 0 : _props$previewCompone.embedly
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}, cleanHTML));
|
|
302
|
-
});
|
|
303
|
-
MarkdownPreview.displayName = 'MarkdownPreview';
|
|
304
|
-
|
|
305
|
-
const styles$3 = {
|
|
306
|
-
root: /*#__PURE__*/emotion.css({
|
|
307
|
-
display: 'flex',
|
|
308
|
-
zIndex: 10,
|
|
309
|
-
flexDirection: 'row',
|
|
310
|
-
justifyContent: 'flex-end',
|
|
311
|
-
overflow: 'hidden',
|
|
312
|
-
marginBottom: '-1px',
|
|
313
|
-
fontSize: tokens.fontSizeM
|
|
314
|
-
}),
|
|
315
|
-
tab: /*#__PURE__*/emotion.css({
|
|
316
|
-
cursor: 'pointer',
|
|
317
|
-
color: tokens.gray700,
|
|
318
|
-
padding: tokens.spacingXs,
|
|
319
|
-
minWidth: '70px',
|
|
320
|
-
border: `1px solid ${tokens.gray400}`,
|
|
321
|
-
borderTopLeftRadius: tokens.borderRadiusSmall,
|
|
322
|
-
borderTopRightRadius: tokens.borderRadiusSmall,
|
|
323
|
-
marginLeft: tokens.spacingXs,
|
|
324
|
-
textAlign: 'center',
|
|
325
|
-
backgroundColor: tokens.gray100,
|
|
326
|
-
borderBottomColor: tokens.gray100,
|
|
327
|
-
outline: 'none',
|
|
328
|
-
'&:focus': {
|
|
329
|
-
boxShadow: tokens.boxShadowHeavy
|
|
330
|
-
},
|
|
331
|
-
transition: `all ${tokens.transitionEasingDefault} ${tokens.transitionDurationShort}`
|
|
332
|
-
}),
|
|
333
|
-
inactiveTab: /*#__PURE__*/emotion.css({
|
|
334
|
-
background: tokens.gray200,
|
|
335
|
-
borderBottomColor: tokens.gray400,
|
|
336
|
-
'&:hover': {
|
|
337
|
-
background: tokens.gray300
|
|
338
|
-
}
|
|
339
|
-
})
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
function MarkdownTabItem(props) {
|
|
343
|
-
return React__default.createElement("div", {
|
|
344
|
-
className: emotion.cx(styles$3.tab, {
|
|
345
|
-
[styles$3.inactiveTab]: props.isActive === false
|
|
346
|
-
}),
|
|
347
|
-
onClick: () => {
|
|
348
|
-
props.onSelect(props.name);
|
|
349
|
-
},
|
|
350
|
-
onKeyDown: e => {
|
|
351
|
-
if (e.keyCode === 13) {
|
|
352
|
-
props.onSelect(props.name);
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
tabIndex: 0,
|
|
356
|
-
role: "tab",
|
|
357
|
-
"aria-controls": props.name,
|
|
358
|
-
"aria-selected": props.isActive === true,
|
|
359
|
-
"data-test-id": props.testId
|
|
360
|
-
}, props.children);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
function MarkdownTabs(props) {
|
|
364
|
-
return React__default.createElement("div", {
|
|
365
|
-
className: styles$3.root
|
|
366
|
-
}, React__default.createElement(MarkdownTabItem, {
|
|
367
|
-
name: "editor",
|
|
368
|
-
onSelect: props.onSelect,
|
|
369
|
-
isActive: props.active === 'editor',
|
|
370
|
-
testId: "markdown-tab-md"
|
|
371
|
-
}, "Editor"), React__default.createElement(MarkdownTabItem, {
|
|
372
|
-
name: "preview",
|
|
373
|
-
onSelect: props.onSelect,
|
|
374
|
-
isActive: props.active === 'preview',
|
|
375
|
-
testId: "markdown-tab-preview"
|
|
376
|
-
}, "Preview"));
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
const userAgent = /*#__PURE__*/get(window, 'navigator.userAgent', '');
|
|
380
|
-
const platform = /*#__PURE__*/get(window, 'navigator.platform', '');
|
|
381
|
-
let ctrlKey = 'Ctrl';
|
|
382
|
-
const tests = {
|
|
383
|
-
// eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/ban-ts-comment
|
|
384
|
-
// @ts-ignore ignore missing MSStream
|
|
385
|
-
ios: /*#__PURE__*/ /(iphone os|ipad|iphone|ipod)/i.test(userAgent) && !window.MSStream
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
if (tests.ios || /mac(68k|ppc|intel)/i.test(platform)) {
|
|
389
|
-
ctrlKey = 'Cmd';
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function getCtrlKey() {
|
|
393
|
-
return ctrlKey;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/* eslint-disable @typescript-eslint/no-use-before-define, @typescript-eslint/no-explicit-any */
|
|
397
|
-
|
|
398
|
-
function stripUnit(value) {
|
|
399
|
-
if (typeof value !== 'string') return value;
|
|
400
|
-
const cssRegex = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;
|
|
401
|
-
const matchedValue = value.match(cssRegex);
|
|
402
|
-
|
|
403
|
-
if (!matchedValue) {
|
|
404
|
-
throw new Error("Couldn't match unit in given string");
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return parseFloat(value);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
function create(host, options) {
|
|
411
|
-
const {
|
|
412
|
-
direction,
|
|
413
|
-
fixedHeight,
|
|
414
|
-
height,
|
|
415
|
-
readOnly
|
|
416
|
-
} = options || {}; // Set to true if `setValue()` has been called. This is to prevent
|
|
417
|
-
// undoing the initial content.
|
|
418
|
-
|
|
419
|
-
let initializedWithValue = false;
|
|
420
|
-
const LF = '\n';
|
|
421
|
-
const EDITOR_SIZE = {
|
|
422
|
-
min: height ? stripUnit(height) : 300,
|
|
423
|
-
max: 500,
|
|
424
|
-
shift: 50
|
|
425
|
-
};
|
|
426
|
-
const cm = CodeMirror(host, {
|
|
427
|
-
direction,
|
|
428
|
-
readOnly,
|
|
429
|
-
mode: 'markdown',
|
|
430
|
-
lineNumbers: false,
|
|
431
|
-
undoDepth: 200,
|
|
432
|
-
matchBrackets: true,
|
|
433
|
-
lineWrapping: true,
|
|
434
|
-
// When `lineSeparator === null` the document will be split
|
|
435
|
-
// on CRLFs as well as lone CRs and LFs. A single LF will
|
|
436
|
-
// be used as line separator in all output
|
|
437
|
-
lineSeparator: null,
|
|
438
|
-
theme: 'elegant',
|
|
439
|
-
tabSize: 2,
|
|
440
|
-
indentWithTabs: false,
|
|
441
|
-
indentUnit: 2,
|
|
442
|
-
autoRefresh: true,
|
|
443
|
-
spellcheck: true,
|
|
444
|
-
inputStyle: 'contenteditable'
|
|
445
|
-
});
|
|
446
|
-
cm.setSize('100%', EDITOR_SIZE.min);
|
|
447
|
-
|
|
448
|
-
if (!fixedHeight) {
|
|
449
|
-
cm.on('change', throttle(assureHeight, 150));
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
cm.setOption('extraKeys', {
|
|
453
|
-
Tab: function () {
|
|
454
|
-
replaceSelectedText(getIndentation());
|
|
455
|
-
},
|
|
456
|
-
Enter: 'newlineAndIndentContinueMarkdownList',
|
|
457
|
-
Esc: () => {
|
|
458
|
-
cm.getInputField().blur();
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
/**
|
|
462
|
-
* @description
|
|
463
|
-
* Custom API for a CodeMirror instance.
|
|
464
|
-
*
|
|
465
|
-
* An instance wraps a CodeMirror instance and provides a custom interface
|
|
466
|
-
* on top of CodeMirror.
|
|
467
|
-
*/
|
|
468
|
-
|
|
469
|
-
return {
|
|
470
|
-
destroy,
|
|
471
|
-
disable,
|
|
472
|
-
enable,
|
|
473
|
-
attachEvent,
|
|
474
|
-
addKeyShortcuts,
|
|
475
|
-
setValue,
|
|
476
|
-
cmd,
|
|
477
|
-
moveToLineBeginning,
|
|
478
|
-
moveIfNotEmpty,
|
|
479
|
-
restoreCursor,
|
|
480
|
-
moveToLineEnd,
|
|
481
|
-
usePrimarySelection,
|
|
482
|
-
focus,
|
|
483
|
-
select,
|
|
484
|
-
selectBackwards,
|
|
485
|
-
selectAll: () => cm.execCommand('selectAll'),
|
|
486
|
-
extendSelectionBy,
|
|
487
|
-
insertAtCursor,
|
|
488
|
-
insertAtLineBeginning,
|
|
489
|
-
wrapSelection,
|
|
490
|
-
removeFromLineBeginning,
|
|
491
|
-
removeSelectedText,
|
|
492
|
-
replaceSelectedText,
|
|
493
|
-
getCursor,
|
|
494
|
-
setCursor,
|
|
495
|
-
getSelection,
|
|
496
|
-
getLine,
|
|
497
|
-
isLineEmpty,
|
|
498
|
-
getSelectedText,
|
|
499
|
-
getSelectionLength,
|
|
500
|
-
getCurrentLine,
|
|
501
|
-
getCurrentLineNumber,
|
|
502
|
-
getCurrentCharacter,
|
|
503
|
-
getCurrentLineLength,
|
|
504
|
-
lineStartsWith,
|
|
505
|
-
getIndentation,
|
|
506
|
-
getNl,
|
|
507
|
-
getValue,
|
|
508
|
-
getLinesCount,
|
|
509
|
-
getHistorySize,
|
|
510
|
-
setReadOnly: value => cm.setOption('readOnly', value),
|
|
511
|
-
getHistory: () => cm.getHistory(),
|
|
512
|
-
setHistory: history => cm.setHistory(history),
|
|
513
|
-
setFullsize: () => {
|
|
514
|
-
cm.setSize('100%', '100%');
|
|
515
|
-
cm.refresh();
|
|
516
|
-
},
|
|
517
|
-
refresh: () => cm.refresh()
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
function destroy() {
|
|
521
|
-
// @ts-expect-error
|
|
522
|
-
cm.toTextArea();
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
function disable() {
|
|
526
|
-
cm.setOption('readOnly', 'nocursor');
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
function enable() {
|
|
530
|
-
cm.setOption('readOnly', false);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
function assureHeight() {
|
|
534
|
-
const current = cm.heightAtLine(cm.lastLine(), 'local') + EDITOR_SIZE.shift;
|
|
535
|
-
let next = current;
|
|
536
|
-
|
|
537
|
-
if (current < EDITOR_SIZE.min) {
|
|
538
|
-
next = EDITOR_SIZE.min;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
if (current > EDITOR_SIZE.max) {
|
|
542
|
-
next = EDITOR_SIZE.max;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
cm.setSize('100%', next);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
function attachEvent(name, fn, throttleInterval) {
|
|
549
|
-
if (throttleInterval) {
|
|
550
|
-
fn = throttle(fn, throttleInterval);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
cm.on(name, fn);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
function addKeyShortcuts(map) {
|
|
557
|
-
const ctrlKey = getCtrlKey();
|
|
558
|
-
cm.addKeyMap(transform(map, (acc, value, key) => {
|
|
559
|
-
// eslint-disable-next-line -- TODO: describe this disable
|
|
560
|
-
// @ts-ignore
|
|
561
|
-
acc[ctrlKey + '-' + key] = value;
|
|
562
|
-
}, {}));
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* low-level editor manipulation functions
|
|
566
|
-
*/
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* @description
|
|
570
|
-
* Sets the content of the editor while preserving the cursor
|
|
571
|
-
* position.
|
|
572
|
-
*
|
|
573
|
-
* If called for the first time it will not record the change in
|
|
574
|
-
* the history.
|
|
575
|
-
*/
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
function setValue(value) {
|
|
579
|
-
value = value || '';
|
|
580
|
-
|
|
581
|
-
if (getValue() === value) {
|
|
582
|
-
return;
|
|
583
|
-
} // set value, but save cursor position first
|
|
584
|
-
// position will be restored, but w/o focus (third arg)
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
const line = getCurrentLineNumber();
|
|
588
|
-
const ch = getCurrentCharacter();
|
|
589
|
-
cm.setValue(value);
|
|
590
|
-
restoreCursor(ch, line, true); // We do not want to record the initial population in the
|
|
591
|
-
// history. Otherwise it would always be possible to revert to
|
|
592
|
-
// the empty string.
|
|
593
|
-
|
|
594
|
-
if (!initializedWithValue) {
|
|
595
|
-
cm.clearHistory();
|
|
596
|
-
initializedWithValue = true;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
function cmd(name) {
|
|
601
|
-
cm.execCommand(name);
|
|
602
|
-
cm.focus();
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
function moveToLineBeginning(lineNumber) {
|
|
606
|
-
cm.setCursor({
|
|
607
|
-
line: defaultToCurrentLineNumber(lineNumber),
|
|
608
|
-
ch: 0
|
|
609
|
-
});
|
|
610
|
-
cm.focus();
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* @description
|
|
614
|
-
* Insert a new line below the cursor and move to the beginning of
|
|
615
|
-
* that line.
|
|
616
|
-
*
|
|
617
|
-
* Only do this if the editor has content and we are not already on
|
|
618
|
-
* the last line.
|
|
619
|
-
*
|
|
620
|
-
* TODO rename this
|
|
621
|
-
*/
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
function moveIfNotEmpty() {
|
|
625
|
-
if (getCurrentLineLength() < 1) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
const next = getCurrentLineNumber() + 1;
|
|
630
|
-
|
|
631
|
-
if (cm.lastLine() < next) {
|
|
632
|
-
moveToLineEnd();
|
|
633
|
-
insertAtCursor(getNl());
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
moveToLineBeginning(next);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
function restoreCursor(character, lineNumber, noFocus) {
|
|
640
|
-
cm.setCursor(defaultToCurrentLineNumber(lineNumber), character, {
|
|
641
|
-
scroll: !noFocus
|
|
642
|
-
});
|
|
643
|
-
|
|
644
|
-
if (!noFocus) {
|
|
645
|
-
cm.focus();
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
function moveToLineEnd(lineNumber) {
|
|
650
|
-
cm.setCursor({
|
|
651
|
-
line: defaultToCurrentLineNumber(lineNumber),
|
|
652
|
-
ch: getCurrentLineLength()
|
|
653
|
-
});
|
|
654
|
-
cm.focus();
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
function defaultToCurrentLineNumber(lineNumber) {
|
|
658
|
-
if (lineNumber === 0 || lineNumber !== undefined && lineNumber > 0) {
|
|
659
|
-
return lineNumber;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
return getCurrentLineNumber();
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
function usePrimarySelection() {
|
|
666
|
-
cmd('singleSelection');
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
function focus() {
|
|
670
|
-
cm.focus();
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
function select(from, to) {
|
|
674
|
-
cm.setSelection(from, to);
|
|
675
|
-
cm.focus();
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
function selectBackwards(skip, len) {
|
|
679
|
-
select(getPos(-skip - len), getPos(-skip));
|
|
680
|
-
|
|
681
|
-
function getPos(modifier) {
|
|
682
|
-
return {
|
|
683
|
-
line: getCurrentLineNumber(),
|
|
684
|
-
ch: getCurrentCharacter() + modifier
|
|
685
|
-
};
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
function extendSelectionBy(modifier) {
|
|
690
|
-
select(getPos('anchor', 0), getPos('head', modifier));
|
|
691
|
-
|
|
692
|
-
function getPos(prop, modifier) {
|
|
693
|
-
const selection = getSelection();
|
|
694
|
-
|
|
695
|
-
if (!selection) {
|
|
696
|
-
return {
|
|
697
|
-
line: 0,
|
|
698
|
-
ch: 0
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
return {
|
|
703
|
-
line: selection[prop].line,
|
|
704
|
-
ch: selection[prop].ch + modifier
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
function insertAtCursor(text) {
|
|
710
|
-
cm.replaceRange(text, cm.getCursor());
|
|
711
|
-
cm.focus();
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
function insertAtLineBeginning(text) {
|
|
715
|
-
const initialCh = getCurrentCharacter();
|
|
716
|
-
moveToLineBeginning();
|
|
717
|
-
insertAtCursor(text);
|
|
718
|
-
restoreCursor(initialCh + text.length);
|
|
719
|
-
cm.focus();
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
function wrapSelection(wrapper) {
|
|
723
|
-
const replacement = wrapper + getSelectedText() + wrapper;
|
|
724
|
-
const selection = getSelection();
|
|
725
|
-
|
|
726
|
-
if (selection) {
|
|
727
|
-
cm.replaceRange(replacement, selection.anchor, selection == null ? void 0 : selection.head);
|
|
728
|
-
cm.focus();
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
function removeFromLineBeginning(charCount) {
|
|
733
|
-
const lineNumber = getCurrentLineNumber();
|
|
734
|
-
cm.replaceRange('', {
|
|
735
|
-
line: lineNumber,
|
|
736
|
-
ch: 0
|
|
737
|
-
}, {
|
|
738
|
-
line: lineNumber,
|
|
739
|
-
ch: charCount
|
|
740
|
-
});
|
|
741
|
-
cm.focus();
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
function removeSelectedText() {
|
|
745
|
-
cm.replaceSelection('');
|
|
746
|
-
cm.focus();
|
|
747
|
-
}
|
|
748
|
-
/**
|
|
749
|
-
* @description
|
|
750
|
-
* Replace the selected text with the given string.
|
|
751
|
-
*
|
|
752
|
-
* If nothing is selected it will insert the text at the current
|
|
753
|
-
* cursor position
|
|
754
|
-
*
|
|
755
|
-
* The optional `select` parameter controls what will be selected
|
|
756
|
-
* afters wards. By default the cursor will be at the end of the
|
|
757
|
-
* inserted text. You can pass 'around' to select the inserted
|
|
758
|
-
* text.
|
|
759
|
-
*/
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
function replaceSelectedText(replacement, select) {
|
|
763
|
-
cm.replaceSelection(replacement, select);
|
|
764
|
-
cm.focus();
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* low-level editor get/check functions
|
|
768
|
-
*/
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
function getCursor() {
|
|
772
|
-
return cm.getCursor();
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
function setCursor(cursor) {
|
|
776
|
-
cm.setCursor(cursor);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
function getSelection() {
|
|
780
|
-
const selections = cm.listSelections();
|
|
781
|
-
|
|
782
|
-
if (!cm.somethingSelected() || !selections || selections.length < 1) {
|
|
783
|
-
return null;
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
return selections[0];
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
function getLine(lineNumber) {
|
|
790
|
-
return cm.getLine(lineNumber) || '';
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
function isLineEmpty(lineNumber) {
|
|
794
|
-
const n = defaultToCurrentLineNumber(lineNumber);
|
|
795
|
-
return n > -1 && getLine(n).length < 1 && n < cm.lineCount();
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
function getLinesCount() {
|
|
799
|
-
return cm.lineCount();
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
function getSelectedText() {
|
|
803
|
-
return getSelection() ? cm.getSelection() : '';
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
function getSelectionLength() {
|
|
807
|
-
return getSelectedText().length;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
function getCurrentLine() {
|
|
811
|
-
return getLine(getCurrentLineNumber());
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
function getCurrentLineNumber() {
|
|
815
|
-
return cm.getCursor().line;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
function getCurrentCharacter() {
|
|
819
|
-
return cm.getCursor().ch;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
function getCurrentLineLength() {
|
|
823
|
-
return getCurrentLine().length;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
function lineStartsWith(text) {
|
|
827
|
-
return getCurrentLine().startsWith(text);
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
function getIndentation() {
|
|
831
|
-
return repeat(' ', cm.getOption('indentUnit') ?? 0);
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
function getNl(n = 1) {
|
|
835
|
-
if (n < 1) {
|
|
836
|
-
return '';
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
return repeat(LF, n);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
function getValue() {
|
|
843
|
-
return cm.getValue() || '';
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
function getHistorySize(which) {
|
|
847
|
-
const history = cm.historySize();
|
|
848
|
-
return which ? history[which] : history;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
function repeat(what, n) {
|
|
852
|
-
return new Array(n + 1).join(what);
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
857
|
-
|
|
858
|
-
function createPrefixToggleFn(prefix) {
|
|
859
|
-
return editor => {
|
|
860
|
-
if (editor.lineStartsWith(prefix)) {
|
|
861
|
-
editor.removeFromLineBeginning(prefix.length);
|
|
862
|
-
} else {
|
|
863
|
-
editor.insertAtLineBeginning(prefix);
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
/**
|
|
868
|
-
* Wraps the current selection with a marker.
|
|
869
|
-
*
|
|
870
|
-
* If nothing is selected it inserts the given text wrapped in the
|
|
871
|
-
* marker and selects the inner text
|
|
872
|
-
*
|
|
873
|
-
* Used b the `bold`, `italic`, and `strike` commands.
|
|
874
|
-
*/
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
function wrapSelection(editor, marker, emptyText) {
|
|
878
|
-
return () => {
|
|
879
|
-
editor.usePrimarySelection(); // there's a selection - wrap it with inline marker
|
|
880
|
-
|
|
881
|
-
if (editor.getSelection()) {
|
|
882
|
-
const selectedText = editor.getSelectedText();
|
|
883
|
-
|
|
884
|
-
if (selectedText.startsWith(marker) && selectedText.endsWith(marker)) {
|
|
885
|
-
const markerLength = marker.length;
|
|
886
|
-
const textWithoutMarker = selectedText.slice(markerLength, selectedText.length - markerLength);
|
|
887
|
-
editor.replaceSelectedText(textWithoutMarker);
|
|
888
|
-
} else {
|
|
889
|
-
editor.wrapSelection(marker);
|
|
890
|
-
}
|
|
891
|
-
} else {
|
|
892
|
-
// no selection - insert sample text and select it
|
|
893
|
-
editor.insertAtCursor(marker + emptyText + marker);
|
|
894
|
-
editor.selectBackwards(marker.length, emptyText.length);
|
|
895
|
-
}
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
const HEADER_CHAR = '#';
|
|
900
|
-
const quoteToggleFn = /*#__PURE__*/createPrefixToggleFn('> ');
|
|
901
|
-
const codeToggleFn = /*#__PURE__*/createPrefixToggleFn(' ');
|
|
902
|
-
/**
|
|
903
|
-
* @description
|
|
904
|
-
* A collection of commands used by the user bound to a
|
|
905
|
-
* CodeMirrorWrapper instance.
|
|
906
|
-
*
|
|
907
|
-
* The command collection only depends on the wrapper instance and is
|
|
908
|
-
* used by UI from code mirror stuff.
|
|
909
|
-
*/
|
|
910
|
-
|
|
911
|
-
function create$1(editor) {
|
|
912
|
-
return {
|
|
913
|
-
bold: wrapSelection(editor, '__', 'text in bold'),
|
|
914
|
-
italic: wrapSelection(editor, '*', 'text in italic'),
|
|
915
|
-
strike: wrapSelection(editor, '~~', 'striked out'),
|
|
916
|
-
quote: modifySelection(editor, quoteToggleFn),
|
|
917
|
-
code: modifySelection(editor, codeToggleFn),
|
|
918
|
-
link,
|
|
919
|
-
h1: toggleHeader(editor, 1),
|
|
920
|
-
h2: toggleHeader(editor, 2),
|
|
921
|
-
h3: toggleHeader(editor, 3),
|
|
922
|
-
ul: modifySelection(editor, ulToggleFn, true),
|
|
923
|
-
ol: modifySelection(editor, olToggleFn, true),
|
|
924
|
-
undo: function () {
|
|
925
|
-
editor.cmd('undo');
|
|
926
|
-
},
|
|
927
|
-
redo: function () {
|
|
928
|
-
editor.cmd('redo');
|
|
929
|
-
},
|
|
930
|
-
hr,
|
|
931
|
-
indent,
|
|
932
|
-
dedent,
|
|
933
|
-
table
|
|
934
|
-
};
|
|
935
|
-
/**
|
|
936
|
-
* @description
|
|
937
|
-
* Insert a line with `---` below the cursor.
|
|
938
|
-
*/
|
|
939
|
-
|
|
940
|
-
function hr() {
|
|
941
|
-
editor.moveIfNotEmpty();
|
|
942
|
-
const nl = editor.getNl();
|
|
943
|
-
const markup = nl + '---' + nl + nl;
|
|
944
|
-
editor.insertAtCursor(markup);
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* @description
|
|
948
|
-
* Indent the current line.
|
|
949
|
-
*/
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
function indent() {
|
|
953
|
-
editor.insertAtLineBeginning(editor.getIndentation());
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
* @description
|
|
957
|
-
* Dedent the current line.
|
|
958
|
-
*/
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
function dedent() {
|
|
962
|
-
const indentation = editor.getIndentation();
|
|
963
|
-
|
|
964
|
-
if (editor.lineStartsWith(indentation)) {
|
|
965
|
-
editor.removeFromLineBeginning(indentation.length);
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
* @description
|
|
970
|
-
* Insert a markdown table template in a new line.
|
|
971
|
-
*/
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
function table(config) {
|
|
975
|
-
const nl = editor.getNl();
|
|
976
|
-
editor.moveIfNotEmpty();
|
|
977
|
-
editor.insertAtCursor(nl);
|
|
978
|
-
const line = editor.getCurrentLineNumber();
|
|
979
|
-
editor.insertAtCursor(tableTemplate(config.rows, config.cols).join(nl));
|
|
980
|
-
editor.insertAtCursor(nl + nl);
|
|
981
|
-
editor.restoreCursor(2, line);
|
|
982
|
-
}
|
|
983
|
-
/**
|
|
984
|
-
* @description
|
|
985
|
-
* Inserts or replaces the current selection with a markdown link
|
|
986
|
-
*/
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
function link(url, text, title) {
|
|
990
|
-
editor.usePrimarySelection();
|
|
991
|
-
const linkTitle = title ? ' "' + title + '"' : '';
|
|
992
|
-
const link = text ? '[' + text + '](' + url + linkTitle + ')' : '<' + url + '>';
|
|
993
|
-
editor.replaceSelectedText(link, 'around');
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* For each line in the selection move to that line and call
|
|
998
|
-
* `toggleFn` with the 1-based index of the line in the selection.
|
|
999
|
-
*
|
|
1000
|
-
* If there is no selection we just call `toggleFn(editor)`.
|
|
1001
|
-
*/
|
|
1002
|
-
|
|
1003
|
-
function modifySelection(editor, toggleFn, isList) {
|
|
1004
|
-
return () => {
|
|
1005
|
-
editor.usePrimarySelection();
|
|
1006
|
-
const selection = editor.getSelection();
|
|
1007
|
-
|
|
1008
|
-
if (selection) {
|
|
1009
|
-
// there's a selection - toggle list bullet for each line
|
|
1010
|
-
// listNumber is 1, 2, 3... and can be used as ol bullet
|
|
1011
|
-
forLineIn(selection, (lineNumber, listNumber) => {
|
|
1012
|
-
// TODO move this into forLineIn
|
|
1013
|
-
editor.moveToLineBeginning(lineNumber);
|
|
1014
|
-
toggleFn(editor, listNumber);
|
|
1015
|
-
});
|
|
1016
|
-
editor.moveToLineEnd();
|
|
1017
|
-
} else {
|
|
1018
|
-
// there's no selection - just toggle line prefix
|
|
1019
|
-
// but if adding list, add whitespace before and after list
|
|
1020
|
-
if (isList && !getListNumber(editor) && !editor.lineStartsWith('- ')) {
|
|
1021
|
-
prepareListWhitespace(editor);
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
toggleFn(editor);
|
|
1025
|
-
}
|
|
1026
|
-
};
|
|
1027
|
-
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Calls callback for each line number that is in the selection
|
|
1030
|
-
*
|
|
1031
|
-
* The second argument is the 1-based index of the iteration.
|
|
1032
|
-
*
|
|
1033
|
-
* @param {CodeMirror.Selection} selection
|
|
1034
|
-
* param {function(number)} cb
|
|
1035
|
-
*/
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
function forLineIn(selection, cb) {
|
|
1039
|
-
// anchor/head depend on selection direction, so min & max have to be used
|
|
1040
|
-
const lines = [selection.anchor.line, selection.head.line];
|
|
1041
|
-
const maxNumber = max(lines);
|
|
1042
|
-
const minNumber = min(lines);
|
|
1043
|
-
const lineRange = range(minNumber || 0, maxNumber !== undefined ? maxNumber + 1 : undefined);
|
|
1044
|
-
lineRange.forEach((lineNumber, i) => {
|
|
1045
|
-
cb(lineNumber, i + 1);
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
function prepareListWhitespace(editor) {
|
|
1050
|
-
const line = editor.getCurrentLineNumber();
|
|
1051
|
-
const isCurrentLineEmpty = editor.isLineEmpty(line);
|
|
1052
|
-
const isPrevLineEmpty = line > 0 ? editor.isLineEmpty(line - 1) : false;
|
|
1053
|
-
const isNextLineEmpty = line < editor.getLinesCount() - 1 ? editor.isLineEmpty(line + 1) : true;
|
|
1054
|
-
let linesToInsert = isCurrentLineEmpty ? 2 : 4;
|
|
1055
|
-
|
|
1056
|
-
if (isPrevLineEmpty) {
|
|
1057
|
-
linesToInsert = linesToInsert - 1;
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
if (isNextLineEmpty) {
|
|
1061
|
-
linesToInsert = linesToInsert - 1;
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
editor.moveToLineEnd();
|
|
1065
|
-
editor.insertAtCursor(editor.getNl(linesToInsert));
|
|
1066
|
-
editor.restoreCursor(0, isCurrentLineEmpty ? line : line + 2);
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
function getListNumber(editor) {
|
|
1070
|
-
const result = editor.getCurrentLine().match(/^(\d+\. )/);
|
|
1071
|
-
return result ? result[1] : null;
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
function ulToggleFn(editor) {
|
|
1075
|
-
if (editor.lineStartsWith('- ')) {
|
|
1076
|
-
editor.removeFromLineBeginning(2);
|
|
1077
|
-
} else {
|
|
1078
|
-
const listNumber = getListNumber(editor);
|
|
1079
|
-
|
|
1080
|
-
if (listNumber) {
|
|
1081
|
-
editor.removeFromLineBeginning(listNumber.length);
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
editor.insertAtLineBeginning('- ');
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
function olToggleFn(editor, n) {
|
|
1089
|
-
const listNumber = getListNumber(editor);
|
|
1090
|
-
|
|
1091
|
-
if (listNumber) {
|
|
1092
|
-
editor.removeFromLineBeginning(listNumber.length);
|
|
1093
|
-
} else {
|
|
1094
|
-
if (editor.lineStartsWith('- ')) {
|
|
1095
|
-
editor.removeFromLineBeginning(2);
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
editor.insertAtLineBeginning((n || 1) + '. ');
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
/**
|
|
1102
|
-
* From a table layout specification build a Markdown table template.
|
|
1103
|
-
*
|
|
1104
|
-
* Returns the lines as an array.
|
|
1105
|
-
* Used by the `table()` command
|
|
1106
|
-
*
|
|
1107
|
-
* @param {object} config
|
|
1108
|
-
* @param {number} rows
|
|
1109
|
-
* @param {number} cols
|
|
1110
|
-
* @returns {string[]}
|
|
1111
|
-
*/
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
function tableTemplate(nrows, ncols) {
|
|
1115
|
-
const cellWidth = new Array(11);
|
|
1116
|
-
const cell = ' ' + cellWidth.join(' ') + ' |';
|
|
1117
|
-
const separatorCell = ' ' + cellWidth.join('-') + ' |';
|
|
1118
|
-
let baseRow = '|';
|
|
1119
|
-
let separatorRow = '|';
|
|
1120
|
-
times(ncols, () => {
|
|
1121
|
-
baseRow += cell;
|
|
1122
|
-
separatorRow += separatorCell;
|
|
1123
|
-
});
|
|
1124
|
-
const bodyRows = range(nrows).map(() => baseRow.replace(/\| {5}/g, '| Cell'));
|
|
1125
|
-
const headerRow = baseRow.replace(/\| {7}/g, '| Header');
|
|
1126
|
-
return [headerRow, separatorRow].concat(bodyRows);
|
|
1127
|
-
}
|
|
1128
|
-
/**
|
|
1129
|
-
* Toggles the header prefix for a given level on the current line.
|
|
1130
|
-
*
|
|
1131
|
-
* - Removes a header when one of the same level is
|
|
1132
|
-
* - Replaces the header if there is one of a different level
|
|
1133
|
-
* - Otherwise inserts the header
|
|
1134
|
-
*/
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
function toggleHeader(editor, level) {
|
|
1138
|
-
return () => {
|
|
1139
|
-
const initialCh = editor.getCurrentCharacter();
|
|
1140
|
-
const currentHeader = selectHeader(editor);
|
|
1141
|
-
const prefix = repeat(HEADER_CHAR, level); // there's no header at the current line - create one
|
|
1142
|
-
|
|
1143
|
-
if (!currentHeader) {
|
|
1144
|
-
editor.moveToLineBeginning();
|
|
1145
|
-
editor.insertAtCursor(prefix + ' ');
|
|
1146
|
-
editor.restoreCursor(initialCh + prefix.length + 1);
|
|
1147
|
-
return;
|
|
1148
|
-
} // there's exactly the same header - remove one
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
if (editor.getSelectedText() === prefix) {
|
|
1152
|
-
editor.extendSelectionBy(1);
|
|
1153
|
-
const removedCh = editor.getSelectionLength();
|
|
1154
|
-
editor.removeSelectedText();
|
|
1155
|
-
editor.restoreCursor(initialCh - removedCh);
|
|
1156
|
-
return;
|
|
1157
|
-
} // there's another header at the current line - replace
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
const diff = prefix.length - editor.getSelectionLength();
|
|
1161
|
-
editor.replaceSelectedText(prefix);
|
|
1162
|
-
editor.restoreCursor(initialCh + diff);
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
|
-
/**
|
|
1166
|
-
* On the current line select a Markdown header prefix. That is the
|
|
1167
|
-
* string at the beginning of the line that consists of up to six `#`.
|
|
1168
|
-
*
|
|
1169
|
-
* If the selection was successful return the selected string.
|
|
1170
|
-
*/
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
function selectHeader(editor) {
|
|
1174
|
-
const result = editor.getCurrentLine().match(/^( {0,3})(#{1,6}) /);
|
|
1175
|
-
|
|
1176
|
-
if (!result) {
|
|
1177
|
-
return null;
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
const indentation = result[1];
|
|
1181
|
-
const header = result[2];
|
|
1182
|
-
editor.select(getPos(0), getPos(header.length));
|
|
1183
|
-
return editor.getSelection();
|
|
1184
|
-
|
|
1185
|
-
function getPos(modifier) {
|
|
1186
|
-
return {
|
|
1187
|
-
line: editor.getCurrentLineNumber(),
|
|
1188
|
-
ch: indentation.length + modifier
|
|
1189
|
-
};
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1194
|
-
function createMarkdownEditor(host, options) {
|
|
1195
|
-
const editor = create(host, options);
|
|
1196
|
-
|
|
1197
|
-
function wrapChange(fn) {
|
|
1198
|
-
return (e, ch) => {
|
|
1199
|
-
fn(editor.getValue(), e, ch);
|
|
1200
|
-
};
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
const api = {
|
|
1204
|
-
actions: create$1(editor),
|
|
1205
|
-
history: {
|
|
1206
|
-
hasUndo: function () {
|
|
1207
|
-
return editor.getHistorySize('undo') > 0;
|
|
1208
|
-
},
|
|
1209
|
-
hasRedo: function () {
|
|
1210
|
-
return editor.getHistorySize('redo') > 0;
|
|
1211
|
-
}
|
|
1212
|
-
},
|
|
1213
|
-
events: {
|
|
1214
|
-
onScroll: function (fn) {
|
|
1215
|
-
editor.attachEvent('scroll', fn, 150);
|
|
1216
|
-
},
|
|
1217
|
-
onChange: function (fn) {
|
|
1218
|
-
editor.attachEvent('change', wrapChange(fn), 0);
|
|
1219
|
-
},
|
|
1220
|
-
onPaste: function (fn) {
|
|
1221
|
-
editor.attachEvent('paste', fn, 0);
|
|
1222
|
-
}
|
|
1223
|
-
},
|
|
1224
|
-
insert: editor.insertAtCursor,
|
|
1225
|
-
focus: editor.focus,
|
|
1226
|
-
getContent: editor.getValue,
|
|
1227
|
-
destroy: editor.destroy,
|
|
1228
|
-
setContent: editor.setValue,
|
|
1229
|
-
getSelectedText: editor.getSelectedText,
|
|
1230
|
-
usePrimarySelection: editor.usePrimarySelection,
|
|
1231
|
-
setReadOnly: editor.setReadOnly,
|
|
1232
|
-
selectBackwards: editor.selectBackwards,
|
|
1233
|
-
getCursor: editor.getCursor,
|
|
1234
|
-
setCursor: editor.setCursor,
|
|
1235
|
-
clear: () => editor.setValue(''),
|
|
1236
|
-
selectAll: editor.selectAll,
|
|
1237
|
-
setFullsize: editor.setFullsize,
|
|
1238
|
-
refresh: editor.refresh
|
|
1239
|
-
};
|
|
1240
|
-
editor.addKeyShortcuts({
|
|
1241
|
-
B: api.actions.bold,
|
|
1242
|
-
I: api.actions.italic
|
|
1243
|
-
});
|
|
1244
|
-
return api;
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
const styles$4 = {
|
|
1248
|
-
root: emotion.css`
|
|
1249
|
-
border: 1px solid ${tokens.gray400};
|
|
1250
|
-
border-width: 0 1px;
|
|
1251
|
-
overflow-y: auto;
|
|
1252
|
-
height: auto;
|
|
1253
|
-
min-height: 300px;
|
|
1254
|
-
|
|
1255
|
-
.CodeMirror {
|
|
1256
|
-
height: auto;
|
|
1257
|
-
line-height: ${tokens.lineHeightDefault};
|
|
1258
|
-
}
|
|
1259
|
-
.CodeMirror-lines {
|
|
1260
|
-
color: ${tokens.gray700};
|
|
1261
|
-
padding: ${tokens.spacingL};
|
|
1262
|
-
}
|
|
1263
|
-
.CodeMirror-code {
|
|
1264
|
-
font-family: ${tokens.fontStackMonospace};
|
|
1265
|
-
font-size: ${tokens.fontSizeM};
|
|
1266
|
-
}
|
|
1267
|
-
.CodeMirror-scroll {
|
|
1268
|
-
min-height: '6rem';
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
.cm-header {
|
|
1272
|
-
color: ${tokens.gray900};
|
|
1273
|
-
}
|
|
1274
|
-
span.cm-variable-2 {
|
|
1275
|
-
color: ${tokens.gray700};
|
|
1276
|
-
}
|
|
1277
|
-
.cm-header-1 {
|
|
1278
|
-
font-size: 1.9em;
|
|
1279
|
-
}
|
|
1280
|
-
.cm-header-2 {
|
|
1281
|
-
font-size: 1.75em;
|
|
1282
|
-
}
|
|
1283
|
-
.cm-header-3 {
|
|
1284
|
-
font-size: 1.6em;
|
|
1285
|
-
}
|
|
1286
|
-
.cm-header-4 {
|
|
1287
|
-
font-size: 1.45em;
|
|
1288
|
-
}
|
|
1289
|
-
.cm-header-5 {
|
|
1290
|
-
font-size: 1.3em;
|
|
1291
|
-
}
|
|
1292
|
-
.cm-header-6 {
|
|
1293
|
-
font-size: 1.15em;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
span.cm-tag,
|
|
1297
|
-
span.cm-string,
|
|
1298
|
-
span.cm-attribute {
|
|
1299
|
-
color: ${tokens.red600};
|
|
1300
|
-
}
|
|
1301
|
-
span.cm-string {
|
|
1302
|
-
text-decoration: none !important;
|
|
1303
|
-
}
|
|
1304
|
-
span.cm-quote,
|
|
1305
|
-
span.cm-comment {
|
|
1306
|
-
color: ${tokens.gray600};
|
|
1307
|
-
}
|
|
1308
|
-
span.cm-link,
|
|
1309
|
-
span.cm-url {
|
|
1310
|
-
color: ${tokens.blue500} !important;
|
|
1311
|
-
}
|
|
1312
|
-
span.cm-link {
|
|
1313
|
-
text-decoration: underline;
|
|
1314
|
-
}
|
|
1315
|
-
`,
|
|
1316
|
-
framed: /*#__PURE__*/emotion.css({
|
|
1317
|
-
'.CodeMirror': {
|
|
1318
|
-
maxHeight: '500px'
|
|
1319
|
-
}
|
|
1320
|
-
}),
|
|
1321
|
-
zen: /*#__PURE__*/emotion.css({
|
|
1322
|
-
border: 'none !important',
|
|
1323
|
-
'.CodeMirror-lines': {
|
|
1324
|
-
maxWidth: '650px',
|
|
1325
|
-
margin: '0 auto'
|
|
1326
|
-
}
|
|
1327
|
-
}),
|
|
1328
|
-
disabled: emotion.css`
|
|
1329
|
-
.CodeMirror {
|
|
1330
|
-
background: ${tokens.gray100};
|
|
1331
|
-
cursor: 'not-allowed';
|
|
1332
|
-
}
|
|
1333
|
-
.CodeMirror-cursors {
|
|
1334
|
-
visibility: hidden !important;
|
|
1335
|
-
}
|
|
1336
|
-
.CodeMirror-scroll,
|
|
1337
|
-
.CodeMirror-sizer,
|
|
1338
|
-
.CodeMirror-lines {
|
|
1339
|
-
cursor: not-allowed;
|
|
1340
|
-
}
|
|
1341
|
-
`
|
|
1342
|
-
};
|
|
1343
|
-
const MarkdownTextarea = /*#__PURE__*/React__default.memo(props => {
|
|
1344
|
-
const hostRef = React.useRef(null);
|
|
1345
|
-
const [editor, setEditor] = React.useState(null);
|
|
1346
|
-
React.useEffect(() => {
|
|
1347
|
-
if (hostRef.current) {
|
|
1348
|
-
setEditor(createMarkdownEditor(hostRef.current, Object.assign({}, {
|
|
1349
|
-
direction: props.direction,
|
|
1350
|
-
readOnly: true
|
|
1351
|
-
}, props.mode === 'zen' ? {
|
|
1352
|
-
fixedHeight: true,
|
|
1353
|
-
height: '100%'
|
|
1354
|
-
} : {}, props.minHeight !== undefined ? {
|
|
1355
|
-
height: props.minHeight
|
|
1356
|
-
} : {})));
|
|
1357
|
-
} // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
1358
|
-
|
|
1359
|
-
}, []);
|
|
1360
|
-
React.useEffect(() => {
|
|
1361
|
-
if (editor) {
|
|
1362
|
-
props.onReady(editor);
|
|
1363
|
-
} // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
1364
|
-
|
|
1365
|
-
}, [editor]);
|
|
1366
|
-
const className = emotion.cx(styles$4.root, props.minHeight !== undefined ? emotion.css({
|
|
1367
|
-
minHeight: props.minHeight
|
|
1368
|
-
}) : undefined, props.mode === 'default' ? styles$4.framed : styles$4.zen, props.disabled && styles$4.disabled);
|
|
1369
|
-
return React__default.createElement("div", {
|
|
1370
|
-
className: className,
|
|
1371
|
-
ref: hostRef,
|
|
1372
|
-
"data-test-id": "markdown-textarea",
|
|
1373
|
-
style: {
|
|
1374
|
-
display: props.visible ? 'block' : 'none'
|
|
1375
|
-
}
|
|
1376
|
-
});
|
|
1377
|
-
});
|
|
1378
|
-
MarkdownTextarea.displayName = 'MarkdownTextarea';
|
|
1379
|
-
|
|
1380
|
-
const HeadingSelector = props => {
|
|
1381
|
-
const handleMenuClick = heading => {
|
|
1382
|
-
props.onSelect(heading);
|
|
1383
|
-
};
|
|
1384
|
-
|
|
1385
|
-
return React__default.createElement(f36Components.Menu, null, React__default.createElement(f36Components.Menu.Trigger, null, props.children), React__default.createElement(f36Components.Menu.List, null, React__default.createElement(f36Components.Menu.Item, {
|
|
1386
|
-
testId: "markdown-action-button-heading-h1",
|
|
1387
|
-
onClick: () => handleMenuClick('h1')
|
|
1388
|
-
}, "Heading 1"), React__default.createElement(f36Components.Menu.Item, {
|
|
1389
|
-
testId: "markdown-action-button-heading-h2",
|
|
1390
|
-
onClick: () => handleMenuClick('h2')
|
|
1391
|
-
}, "Heading 2"), React__default.createElement(f36Components.Menu.Item, {
|
|
1392
|
-
testId: "markdown-action-button-heading-h3",
|
|
1393
|
-
onClick: () => handleMenuClick('h3')
|
|
1394
|
-
}, "Heading 3")));
|
|
1395
|
-
};
|
|
1396
|
-
|
|
1397
|
-
const srOnly = /*#__PURE__*/emotion.css({
|
|
1398
|
-
position: 'absolute',
|
|
1399
|
-
width: '1px',
|
|
1400
|
-
height: '1px',
|
|
1401
|
-
padding: '0',
|
|
1402
|
-
margin: '-1px',
|
|
1403
|
-
overflow: 'hidden',
|
|
1404
|
-
clip: 'rect(0, 0, 0, 0)',
|
|
1405
|
-
border: '0'
|
|
1406
|
-
});
|
|
1407
|
-
const Zen = ({
|
|
1408
|
-
label,
|
|
1409
|
-
...rest
|
|
1410
|
-
}) => React__default.createElement("svg", {
|
|
1411
|
-
width: 14,
|
|
1412
|
-
height: 14,
|
|
1413
|
-
viewBox: "0 0 1792 1792",
|
|
1414
|
-
...rest
|
|
1415
|
-
}, React__default.createElement("path", {
|
|
1416
|
-
d: "M1411 541l-355 355 355 355 144-144q29-31 70-14 39 17 39 59v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l144-144-355-355-355 355 144 144q31 30 14 69-17 40-59 40H192q-26 0-45-19t-19-45v-448q0-42 40-59 39-17 69 14l144 144 355-355-355-355-144 144q-19 19-45 19-12 0-24-5-40-17-40-59V192q0-26 19-45t45-19h448q42 0 59 40 17 39-14 69L541 381l355 355 355-355-144-144q-31-30-14-69 17-40 59-40h448q26 0 45 19t19 45v448q0 42-39 59-13 5-25 5-26 0-45-19z"
|
|
1417
|
-
}), React__default.createElement("span", {
|
|
1418
|
-
className: srOnly
|
|
1419
|
-
}, label));
|
|
1420
|
-
const Strikethrough = ({
|
|
1421
|
-
label,
|
|
1422
|
-
...rest
|
|
1423
|
-
}) => React__default.createElement("svg", {
|
|
1424
|
-
width: 14,
|
|
1425
|
-
height: 14,
|
|
1426
|
-
viewBox: "0 0 1792 1792",
|
|
1427
|
-
...rest
|
|
1428
|
-
}, React__default.createElement("path", {
|
|
1429
|
-
d: "M1760 896q14 0 23 9t9 23v64q0 14-9 23t-23 9H32q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h1728zM483 832q-28-35-51-80-48-98-48-188 0-181 134-309 133-127 393-127 50 0 167 19 66 12 177 48 10 38 21 118 14 123 14 183 0 18-5 45l-12 3-84-6-14-2q-50-149-103-205-88-91-210-91-114 0-182 59-67 58-67 146 0 73 66 140t279 129q69 20 173 66 58 28 95 52H483zm507 256h411q7 39 7 92 0 111-41 212-23 56-71 104-37 35-109 81-80 48-153 66-80 21-203 21-114 0-195-23l-140-40q-57-16-72-28-8-8-8-22v-13q0-108-2-156-1-30 0-68l2-37v-44l102-2q15 34 30 71t22.5 56 12.5 27q35 57 80 94 43 36 105 57 59 22 132 22 64 0 139-27 77-26 122-86 47-61 47-129 0-84-81-157-34-29-137-71z"
|
|
1430
|
-
}), React__default.createElement("span", {
|
|
1431
|
-
className: srOnly
|
|
1432
|
-
}, label));
|
|
1433
|
-
const Indent = ({
|
|
1434
|
-
label,
|
|
1435
|
-
...rest
|
|
1436
|
-
}) => React__default.createElement("svg", {
|
|
1437
|
-
width: 14,
|
|
1438
|
-
height: 14,
|
|
1439
|
-
viewBox: "0 0 1792 1792",
|
|
1440
|
-
...rest
|
|
1441
|
-
}, React__default.createElement("path", {
|
|
1442
|
-
d: "M352 832q0 14-9 23L55 1143q-9 9-23 9-13 0-22.5-9.5T0 1120V544q0-13 9.5-22.5T32 512q14 0 23 9l288 288q9 9 9 23zm1440 480v192q0 13-9.5 22.5t-22.5 9.5H32q-13 0-22.5-9.5T0 1504v-192q0-13 9.5-22.5T32 1280h1728q13 0 22.5 9.5t9.5 22.5zm0-384v192q0 13-9.5 22.5t-22.5 9.5H672q-13 0-22.5-9.5T640 1120V928q0-13 9.5-22.5T672 896h1088q13 0 22.5 9.5t9.5 22.5zm0-384v192q0 13-9.5 22.5T1760 768H672q-13 0-22.5-9.5T640 736V544q0-13 9.5-22.5T672 512h1088q13 0 22.5 9.5t9.5 22.5zm0-384v192q0 13-9.5 22.5T1760 384H32q-13 0-22.5-9.5T0 352V160q0-13 9.5-22.5T32 128h1728q13 0 22.5 9.5t9.5 22.5z"
|
|
1443
|
-
}), React__default.createElement("span", {
|
|
1444
|
-
className: srOnly
|
|
1445
|
-
}, label));
|
|
1446
|
-
const Dedent = ({
|
|
1447
|
-
label,
|
|
1448
|
-
...rest
|
|
1449
|
-
}) => React__default.createElement("svg", {
|
|
1450
|
-
width: 14,
|
|
1451
|
-
height: 14,
|
|
1452
|
-
viewBox: "0 0 1792 1792",
|
|
1453
|
-
...rest
|
|
1454
|
-
}, React__default.createElement("path", {
|
|
1455
|
-
d: "M384 544v576q0 13-9.5 22.5T352 1152q-14 0-23-9L41 855q-9-9-9-23t9-23l288-288q9-9 23-9 13 0 22.5 9.5T384 544zm1408 768v192q0 13-9.5 22.5t-22.5 9.5H32q-13 0-22.5-9.5T0 1504v-192q0-13 9.5-22.5T32 1280h1728q13 0 22.5 9.5t9.5 22.5zm0-384v192q0 13-9.5 22.5t-22.5 9.5H672q-13 0-22.5-9.5T640 1120V928q0-13 9.5-22.5T672 896h1088q13 0 22.5 9.5t9.5 22.5zm0-384v192q0 13-9.5 22.5T1760 768H672q-13 0-22.5-9.5T640 736V544q0-13 9.5-22.5T672 512h1088q13 0 22.5 9.5t9.5 22.5zm0-384v192q0 13-9.5 22.5T1760 384H32q-13 0-22.5-9.5T0 352V160q0-13 9.5-22.5T32 128h1728q13 0 22.5 9.5t9.5 22.5z"
|
|
1456
|
-
}), React__default.createElement("span", {
|
|
1457
|
-
className: srOnly
|
|
1458
|
-
}, label));
|
|
1459
|
-
const Cubes = ({
|
|
1460
|
-
label,
|
|
1461
|
-
...rest
|
|
1462
|
-
}) => React__default.createElement("svg", {
|
|
1463
|
-
width: 18,
|
|
1464
|
-
height: 14,
|
|
1465
|
-
viewBox: "0 0 2304 1792",
|
|
1466
|
-
...rest
|
|
1467
|
-
}, React__default.createElement("path", {
|
|
1468
|
-
d: "M640 1632l384-192v-314l-384 164v342zm-64-454l404-173-404-173-404 173zm1088 454l384-192v-314l-384 164v342zm-64-454l404-173-404-173-404 173zm-448-293l384-165V454l-384 164v267zm-64-379l441-189-441-189-441 189zm1088 518v416q0 36-19 67t-52 47l-448 224q-25 14-57 14t-57-14l-448-224q-4-2-7-4-2 2-7 4l-448 224q-25 14-57 14t-57-14L71 1554q-33-16-52-47t-19-67v-416q0-38 21.5-70T78 906l434-186V320q0-38 21.5-70t56.5-48l448-192q23-10 50-10t50 10l448 192q35 16 56.5 48t21.5 70v400l434 186q36 16 57 48t21 70z"
|
|
1469
|
-
}), React__default.createElement("span", {
|
|
1470
|
-
className: srOnly
|
|
1471
|
-
}, label));
|
|
1472
|
-
const Table = ({
|
|
1473
|
-
label,
|
|
1474
|
-
...rest
|
|
1475
|
-
}) => React__default.createElement("svg", {
|
|
1476
|
-
width: 14,
|
|
1477
|
-
height: 14,
|
|
1478
|
-
viewBox: "0 0 1792 1792",
|
|
1479
|
-
...rest
|
|
1480
|
-
}, React__default.createElement("path", {
|
|
1481
|
-
d: "M576 1376v-192q0-14-9-23t-23-9H224q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm0-384V800q0-14-9-23t-23-9H224q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm512 384v-192q0-14-9-23t-23-9H736q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zM576 608V416q0-14-9-23t-23-9H224q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm512 384V800q0-14-9-23t-23-9H736q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm512 384v-192q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm-512-768V416q0-14-9-23t-23-9H736q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm512 384V800q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm0-384V416q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v192q0 14 9 23t23 9h320q14 0 23-9t9-23zm128-320v1088q0 66-47 113t-113 47H224q-66 0-113-47t-47-113V288q0-66 47-113t113-47h1344q66 0 113 47t47 113z"
|
|
1482
|
-
}), React__default.createElement("span", {
|
|
1483
|
-
className: srOnly
|
|
1484
|
-
}, label));
|
|
1485
|
-
const SpecialChar = ({
|
|
1486
|
-
label,
|
|
1487
|
-
...rest
|
|
1488
|
-
}) => React__default.createElement("svg", {
|
|
1489
|
-
width: 14,
|
|
1490
|
-
height: 14,
|
|
1491
|
-
viewBox: "0 0 1792 1792",
|
|
1492
|
-
...rest
|
|
1493
|
-
}, React__default.createElement("path", {
|
|
1494
|
-
d: "M1360 1307l35 159q3 12-3 22.5t-17 14.5l-5 1q-4 2-10.5 3.5t-16 4.5-21.5 5.5-25.5 5-30 5-33.5 4.5-36.5 3-38.5 1q-234 0-409-130.5T511 1054h-95q-13 0-22.5-9.5T384 1022V909q0-13 9.5-22.5T416 877h66q-2-57 1-105h-67q-14 0-23-9t-9-23V626q0-14 9-23t23-9h98q67-210 243.5-338T1158 128q102 0 194 23 11 3 20 15 6 11 3 24l-43 159q-3 13-14 19.5t-24 2.5l-4-1q-4-1-11.5-2.5L1261 364l-22.5-3.5-26-3-29-2.5-29.5-1q-126 0-226 64T778 594h468q16 0 25 12 10 12 7 26l-24 114q-5 26-32 26H734q-3 37 0 105h459q15 0 25 12 9 12 6 27l-24 112q-2 11-11 18.5t-20 7.5H782q48 117 149.5 185.5T1160 1308q18 0 36-1.5t33.5-3.5 29.5-4.5 24.5-5 18.5-4.5l12-3 5-2q13-5 26 2 12 7 15 21z"
|
|
1495
|
-
}), React__default.createElement("span", {
|
|
1496
|
-
className: srOnly
|
|
1497
|
-
}, label));
|
|
1498
|
-
const OrgLinks = ({
|
|
1499
|
-
label,
|
|
1500
|
-
...rest
|
|
1501
|
-
}) => React__default.createElement("svg", {
|
|
1502
|
-
width: 14,
|
|
1503
|
-
height: 14,
|
|
1504
|
-
viewBox: "0 0 1792 1792",
|
|
1505
|
-
...rest
|
|
1506
|
-
}, React__default.createElement("path", {
|
|
1507
|
-
d: "M1792 1248v320q0 40-28 68t-68 28h-320q-40 0-68-28t-28-68v-320q0-40 28-68t68-28h96V960H960v192h96q40 0 68 28t28 68v320q0 40-28 68t-68 28H736q-40 0-68-28t-28-68v-320q0-40 28-68t68-28h96V960H320v192h96q40 0 68 28t28 68v320q0 40-28 68t-68 28H96q-40 0-68-28t-28-68v-320q0-40 28-68t68-28h96V960q0-52 38-90t90-38h512V640h-96q-40 0-68-28t-28-68V224q0-40 28-68t68-28h320q40 0 68 28t28 68v320q0 40-28 68t-68 28h-96v192h512q52 0 90 38t38 90v192h96q40 0 68 28t28 68z"
|
|
1508
|
-
}), React__default.createElement("span", {
|
|
1509
|
-
className: srOnly
|
|
1510
|
-
}, label));
|
|
1511
|
-
const Undo = ({
|
|
1512
|
-
label,
|
|
1513
|
-
...rest
|
|
1514
|
-
}) => React__default.createElement("svg", {
|
|
1515
|
-
width: 14,
|
|
1516
|
-
height: 14,
|
|
1517
|
-
viewBox: "0 0 1792 1792",
|
|
1518
|
-
...rest
|
|
1519
|
-
}, React__default.createElement("path", {
|
|
1520
|
-
d: "M1664 896q0 156-61 298t-164 245-245 164-298 61q-172 0-327-72.5T305 1387q-7-10-6.5-22.5t8.5-20.5l137-138q10-9 25-9 16 2 23 12 73 95 179 147t225 52q104 0 198.5-40.5T1258 1258t109.5-163.5T1408 896t-40.5-198.5T1258 534t-163.5-109.5T896 384q-98 0-188 35.5T548 521l137 138q31 30 14 69-17 40-59 40H192q-26 0-45-19t-19-45V256q0-42 40-59 39-17 69 14l130 129q107-101 244.5-156.5T896 128q156 0 298 61t245 164 164 245 61 298z"
|
|
1521
|
-
}), React__default.createElement("span", {
|
|
1522
|
-
className: srOnly
|
|
1523
|
-
}, label));
|
|
1524
|
-
const Redo = ({
|
|
1525
|
-
label,
|
|
1526
|
-
...rest
|
|
1527
|
-
}) => React__default.createElement("svg", {
|
|
1528
|
-
width: 14,
|
|
1529
|
-
height: 14,
|
|
1530
|
-
viewBox: "0 0 1792 1792",
|
|
1531
|
-
...rest
|
|
1532
|
-
}, React__default.createElement("path", {
|
|
1533
|
-
d: "M1664 256v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l138-138q-148-137-349-137-104 0-198.5 40.5T534 534 424.5 697.5 384 896t40.5 198.5T534 1258t163.5 109.5T896 1408q119 0 225-52t179-147q7-10 23-12 15 0 25 9l137 138q9 8 9.5 20.5t-7.5 22.5q-109 132-264 204.5T896 1664q-156 0-298-61t-245-164-164-245-61-298 61-298 164-245 245-164 298-61q147 0 284.5 55.5T1425 340l130-129q29-31 70-14 39 17 39 59z"
|
|
1534
|
-
}), React__default.createElement("span", {
|
|
1535
|
-
className: srOnly
|
|
1536
|
-
}, label));
|
|
1537
|
-
|
|
1538
|
-
const InsertLinkSelector = props => {
|
|
1539
|
-
if (props.canAddNew) {
|
|
1540
|
-
return React__default.createElement(MultipleMediaContextMenu, { ...props
|
|
1541
|
-
});
|
|
1542
|
-
} else {
|
|
1543
|
-
return React__default.createElement(f36Components.Button, {
|
|
1544
|
-
isDisabled: props.disabled,
|
|
1545
|
-
startIcon: React__default.createElement(f36Icons.AssetIcon, null),
|
|
1546
|
-
testId: "markdownEditor.linkExistingAssets",
|
|
1547
|
-
size: "small",
|
|
1548
|
-
variant: "secondary",
|
|
1549
|
-
onClick: () => {
|
|
1550
|
-
props.onSelectExisting();
|
|
1551
|
-
}
|
|
1552
|
-
}, "Insert media");
|
|
1553
|
-
}
|
|
1554
|
-
};
|
|
1555
|
-
|
|
1556
|
-
const MultipleMediaContextMenu = props => {
|
|
1557
|
-
return React__default.createElement(f36Components.Menu, {
|
|
1558
|
-
placement: "bottom-end"
|
|
1559
|
-
}, React__default.createElement(f36Components.Menu.Trigger, null, React__default.createElement(f36Components.Button, {
|
|
1560
|
-
endIcon: React__default.createElement(f36Icons.ChevronDownIcon, null),
|
|
1561
|
-
isDisabled: props.disabled,
|
|
1562
|
-
startIcon: React__default.createElement(f36Icons.AssetIcon, null),
|
|
1563
|
-
testId: "markdownEditor.insertMediaDropdownTrigger",
|
|
1564
|
-
size: "small",
|
|
1565
|
-
variant: "secondary"
|
|
1566
|
-
}, "Insert media")), React__default.createElement(f36Components.Menu.List, null, React__default.createElement(f36Components.Menu.Item, {
|
|
1567
|
-
testId: "markdownEditor.uploadAssetsAndLink",
|
|
1568
|
-
onClick: () => props.onAddNew()
|
|
1569
|
-
}, "Add new media and link"), React__default.createElement(f36Components.Menu.Item, {
|
|
1570
|
-
testId: "markdownEditor.linkExistingAssets",
|
|
1571
|
-
onClick: () => props.onSelectExisting()
|
|
1572
|
-
}, "Link existing media")));
|
|
1573
|
-
};
|
|
1574
|
-
|
|
1575
|
-
/* eslint-disable react/prop-types */
|
|
1576
|
-
const styles$5 = {
|
|
1577
|
-
root: /*#__PURE__*/emotion.css({
|
|
1578
|
-
position: 'relative',
|
|
1579
|
-
zIndex: /*#__PURE__*/Number(tokens.zIndexWorkbenchHeader),
|
|
1580
|
-
border: `1px solid ${tokens.gray400}`,
|
|
1581
|
-
backgroundColor: tokens.gray100,
|
|
1582
|
-
padding: tokens.spacingXs,
|
|
1583
|
-
borderTopLeftRadius: tokens.borderRadiusSmall,
|
|
1584
|
-
overflow: 'hidden'
|
|
1585
|
-
}),
|
|
1586
|
-
button: /*#__PURE__*/emotion.css({
|
|
1587
|
-
height: '30px',
|
|
1588
|
-
width: '36px',
|
|
1589
|
-
marginLeft: tokens.spacing2Xs,
|
|
1590
|
-
marginRight: tokens.spacing2Xs
|
|
1591
|
-
}),
|
|
1592
|
-
icon: /*#__PURE__*/emotion.css({
|
|
1593
|
-
fill: tokens.gray700,
|
|
1594
|
-
verticalAlign: 'middle'
|
|
1595
|
-
}),
|
|
1596
|
-
zenButton: /*#__PURE__*/emotion.css({
|
|
1597
|
-
marginLeft: tokens.spacingXs
|
|
1598
|
-
}),
|
|
1599
|
-
zenButtonPressed: /*#__PURE__*/emotion.css({
|
|
1600
|
-
backgroundColor: tokens.gray400
|
|
1601
|
-
}),
|
|
1602
|
-
tooltip: /*#__PURE__*/emotion.css({
|
|
1603
|
-
zIndex: /*#__PURE__*/Number(tokens.zIndexTooltip)
|
|
1604
|
-
})
|
|
1605
|
-
};
|
|
1606
|
-
const ToolbarButton = /*#__PURE__*/React__default.forwardRef((props, ref) => {
|
|
1607
|
-
const {
|
|
1608
|
-
tooltip,
|
|
1609
|
-
onClick,
|
|
1610
|
-
children,
|
|
1611
|
-
className,
|
|
1612
|
-
variant = 'transparent',
|
|
1613
|
-
tooltipPlace = 'top',
|
|
1614
|
-
isDisabled = false,
|
|
1615
|
-
...otherProps
|
|
1616
|
-
} = props;
|
|
1617
|
-
return React__default.createElement(f36Components.Tooltip, {
|
|
1618
|
-
className: styles$5.tooltip,
|
|
1619
|
-
placement: tooltipPlace,
|
|
1620
|
-
content: tooltip
|
|
1621
|
-
}, React__default.createElement(f36Components.IconButton, { ...otherProps,
|
|
1622
|
-
ref: ref,
|
|
1623
|
-
className: emotion.cx(styles$5.button, className),
|
|
1624
|
-
isDisabled: isDisabled,
|
|
1625
|
-
onClick: onClick,
|
|
1626
|
-
variant: variant,
|
|
1627
|
-
size: "small",
|
|
1628
|
-
icon: children,
|
|
1629
|
-
"aria-label": tooltip
|
|
1630
|
-
}));
|
|
1631
|
-
});
|
|
1632
|
-
ToolbarButton.displayName = 'ToolbarButton';
|
|
1633
|
-
|
|
1634
|
-
function MainButtons(props) {
|
|
1635
|
-
const tooltipPlace = props.mode === 'zen' ? 'bottom' : 'top';
|
|
1636
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(HeadingSelector, {
|
|
1637
|
-
onSelect: heading => {
|
|
1638
|
-
if (heading && props.actions.headings[heading]) {
|
|
1639
|
-
props.actions.headings[heading]();
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
}, React__default.createElement(ToolbarButton, {
|
|
1643
|
-
isDisabled: props.disabled,
|
|
1644
|
-
testId: "markdown-action-button-heading",
|
|
1645
|
-
tooltip: "Headings",
|
|
1646
|
-
tooltipPlace: tooltipPlace
|
|
1647
|
-
}, React__default.createElement(f36Icons.HeadingIcon, {
|
|
1648
|
-
"aria-label": "Headings",
|
|
1649
|
-
className: styles$5.icon
|
|
1650
|
-
}))), React__default.createElement(ToolbarButton, {
|
|
1651
|
-
isDisabled: props.disabled,
|
|
1652
|
-
testId: "markdown-action-button-bold",
|
|
1653
|
-
tooltip: "Bold",
|
|
1654
|
-
tooltipPlace: tooltipPlace,
|
|
1655
|
-
onClick: props.actions.simple.bold
|
|
1656
|
-
}, React__default.createElement(f36Icons.FormatBoldIcon, {
|
|
1657
|
-
"aria-label": "Bold",
|
|
1658
|
-
className: styles$5.icon
|
|
1659
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1660
|
-
isDisabled: props.disabled,
|
|
1661
|
-
testId: "markdown-action-button-italic",
|
|
1662
|
-
tooltip: "Italic",
|
|
1663
|
-
tooltipPlace: tooltipPlace,
|
|
1664
|
-
onClick: props.actions.simple.italic
|
|
1665
|
-
}, React__default.createElement(f36Icons.FormatItalicIcon, {
|
|
1666
|
-
"aria-label": "Italic",
|
|
1667
|
-
className: styles$5.icon
|
|
1668
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1669
|
-
isDisabled: props.disabled,
|
|
1670
|
-
testId: "markdown-action-button-quote",
|
|
1671
|
-
tooltip: "Quote",
|
|
1672
|
-
tooltipPlace: tooltipPlace,
|
|
1673
|
-
onClick: props.actions.simple.quote
|
|
1674
|
-
}, React__default.createElement(f36Icons.QuoteIcon, {
|
|
1675
|
-
"aria-label": "Quote",
|
|
1676
|
-
className: styles$5.icon
|
|
1677
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1678
|
-
isDisabled: props.disabled,
|
|
1679
|
-
testId: "markdown-action-button-ul",
|
|
1680
|
-
tooltip: "Unordered list",
|
|
1681
|
-
tooltipPlace: tooltipPlace,
|
|
1682
|
-
onClick: props.actions.simple.ul
|
|
1683
|
-
}, React__default.createElement(f36Icons.ListBulletedIcon, {
|
|
1684
|
-
"aria-label": "Unordered list",
|
|
1685
|
-
className: styles$5.icon
|
|
1686
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1687
|
-
isDisabled: props.disabled,
|
|
1688
|
-
testId: "markdown-action-button-ol",
|
|
1689
|
-
tooltip: "Ordered list",
|
|
1690
|
-
tooltipPlace: tooltipPlace,
|
|
1691
|
-
onClick: props.actions.simple.ol
|
|
1692
|
-
}, React__default.createElement(f36Icons.ListNumberedIcon, {
|
|
1693
|
-
"aria-label": "Ordered list",
|
|
1694
|
-
className: styles$5.icon
|
|
1695
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1696
|
-
isDisabled: props.disabled,
|
|
1697
|
-
testId: "markdown-action-button-link",
|
|
1698
|
-
tooltip: "Link",
|
|
1699
|
-
tooltipPlace: tooltipPlace,
|
|
1700
|
-
onClick: props.actions.insertLink
|
|
1701
|
-
}, React__default.createElement(f36Icons.LinkIcon, {
|
|
1702
|
-
"aria-label": "Link",
|
|
1703
|
-
className: styles$5.icon
|
|
1704
|
-
})));
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
function AdditionalButtons(props) {
|
|
1708
|
-
const tooltipPlace = props.mode === 'zen' ? 'bottom' : 'top';
|
|
1709
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(ToolbarButton, {
|
|
1710
|
-
isDisabled: props.disabled,
|
|
1711
|
-
testId: "markdown-action-button-strike",
|
|
1712
|
-
tooltip: "Strike out",
|
|
1713
|
-
tooltipPlace: tooltipPlace,
|
|
1714
|
-
onClick: props.actions.simple.strike
|
|
1715
|
-
}, React__default.createElement(Strikethrough, {
|
|
1716
|
-
label: "Strike out",
|
|
1717
|
-
className: styles$5.icon
|
|
1718
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1719
|
-
isDisabled: props.disabled,
|
|
1720
|
-
testId: "markdown-action-button-code",
|
|
1721
|
-
tooltip: "Code block",
|
|
1722
|
-
tooltipPlace: tooltipPlace,
|
|
1723
|
-
onClick: props.actions.simple.code
|
|
1724
|
-
}, React__default.createElement(f36Icons.CodeIcon, {
|
|
1725
|
-
"aria-label": "Code block",
|
|
1726
|
-
className: styles$5.icon
|
|
1727
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1728
|
-
isDisabled: props.disabled,
|
|
1729
|
-
testId: "markdown-action-button-hr",
|
|
1730
|
-
tooltip: "Horizontal rule",
|
|
1731
|
-
tooltipPlace: tooltipPlace,
|
|
1732
|
-
onClick: props.actions.simple.hr
|
|
1733
|
-
}, React__default.createElement(f36Icons.HorizontalRuleIcon, {
|
|
1734
|
-
"aria-label": "Horizontal rule",
|
|
1735
|
-
className: styles$5.icon
|
|
1736
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1737
|
-
isDisabled: props.disabled,
|
|
1738
|
-
testId: "markdown-action-button-indent",
|
|
1739
|
-
tooltip: "Increase indentation",
|
|
1740
|
-
tooltipPlace: tooltipPlace,
|
|
1741
|
-
onClick: props.actions.simple.indent
|
|
1742
|
-
}, React__default.createElement(Indent, {
|
|
1743
|
-
label: "Increase indentation",
|
|
1744
|
-
className: styles$5.icon
|
|
1745
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1746
|
-
isDisabled: props.disabled,
|
|
1747
|
-
testId: "markdown-action-button-dedent",
|
|
1748
|
-
tooltip: "Decrease indentation",
|
|
1749
|
-
tooltipPlace: tooltipPlace,
|
|
1750
|
-
onClick: props.actions.simple.dedent
|
|
1751
|
-
}, React__default.createElement(Dedent, {
|
|
1752
|
-
label: "Decrease indentation",
|
|
1753
|
-
className: styles$5.icon
|
|
1754
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1755
|
-
isDisabled: props.disabled,
|
|
1756
|
-
testId: "markdown-action-button-embed",
|
|
1757
|
-
tooltip: "Embed external content",
|
|
1758
|
-
tooltipPlace: tooltipPlace,
|
|
1759
|
-
onClick: props.actions.embedExternalContent
|
|
1760
|
-
}, React__default.createElement(Cubes, {
|
|
1761
|
-
label: "Embed external content",
|
|
1762
|
-
className: styles$5.icon
|
|
1763
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1764
|
-
isDisabled: props.disabled,
|
|
1765
|
-
testId: "markdown-action-button-table",
|
|
1766
|
-
tooltip: "Insert table",
|
|
1767
|
-
tooltipPlace: tooltipPlace,
|
|
1768
|
-
onClick: props.actions.insertTable
|
|
1769
|
-
}, React__default.createElement(Table, {
|
|
1770
|
-
label: "Insert table",
|
|
1771
|
-
className: styles$5.icon
|
|
1772
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1773
|
-
isDisabled: props.disabled,
|
|
1774
|
-
testId: "markdown-action-button-special",
|
|
1775
|
-
tooltip: "Insert special character",
|
|
1776
|
-
tooltipPlace: tooltipPlace,
|
|
1777
|
-
onClick: props.actions.insertSpecialCharacter
|
|
1778
|
-
}, React__default.createElement(SpecialChar, {
|
|
1779
|
-
label: "Insert special character",
|
|
1780
|
-
className: styles$5.icon
|
|
1781
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1782
|
-
isDisabled: props.disabled,
|
|
1783
|
-
testId: "markdown-action-button-organizeLinks",
|
|
1784
|
-
tooltip: "Organize links",
|
|
1785
|
-
tooltipPlace: tooltipPlace,
|
|
1786
|
-
onClick: props.actions.organizeLinks
|
|
1787
|
-
}, React__default.createElement(OrgLinks, {
|
|
1788
|
-
label: "Organize links",
|
|
1789
|
-
className: styles$5.icon
|
|
1790
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1791
|
-
isDisabled: props.disabled,
|
|
1792
|
-
testId: "markdown-action-button-undo",
|
|
1793
|
-
tooltip: "Undo",
|
|
1794
|
-
tooltipPlace: tooltipPlace,
|
|
1795
|
-
onClick: props.actions.history.undo
|
|
1796
|
-
}, React__default.createElement(Undo, {
|
|
1797
|
-
label: "Undo",
|
|
1798
|
-
className: styles$5.icon
|
|
1799
|
-
})), React__default.createElement(ToolbarButton, {
|
|
1800
|
-
isDisabled: props.disabled,
|
|
1801
|
-
testId: "markdown-action-button-redo",
|
|
1802
|
-
tooltip: "Redo",
|
|
1803
|
-
tooltipPlace: tooltipPlace,
|
|
1804
|
-
onClick: props.actions.history.redo
|
|
1805
|
-
}, React__default.createElement(Redo, {
|
|
1806
|
-
label: "Redo",
|
|
1807
|
-
className: styles$5.icon
|
|
1808
|
-
})));
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
function DefaultMarkdownToolbar(props) {
|
|
1812
|
-
const [showAdditional, setShowAdditional] = React__default.useState(false);
|
|
1813
|
-
return React__default.createElement("div", {
|
|
1814
|
-
className: styles$5.root
|
|
1815
|
-
}, React__default.createElement(f36Components.Flex, {
|
|
1816
|
-
justifyContent: "space-between",
|
|
1817
|
-
flexWrap: "wrap"
|
|
1818
|
-
}, React__default.createElement(f36Components.Flex, {
|
|
1819
|
-
flexWrap: "wrap"
|
|
1820
|
-
}, React__default.createElement(MainButtons, { ...props
|
|
1821
|
-
}), React__default.createElement(ToolbarButton, {
|
|
1822
|
-
isDisabled: props.disabled,
|
|
1823
|
-
testId: "markdown-action-button-toggle-additional",
|
|
1824
|
-
tooltip: showAdditional ? 'Hide additional actions' : 'More actions',
|
|
1825
|
-
onClick: () => {
|
|
1826
|
-
setShowAdditional(!showAdditional);
|
|
1827
|
-
}
|
|
1828
|
-
}, React__default.createElement(f36Icons.MoreHorizontalIcon, {
|
|
1829
|
-
className: styles$5.icon
|
|
1830
|
-
}))), React__default.createElement(f36Components.Flex, null, React__default.createElement(InsertLinkSelector, {
|
|
1831
|
-
disabled: props.disabled,
|
|
1832
|
-
onSelectExisting: props.actions.linkExistingMedia,
|
|
1833
|
-
onAddNew: props.actions.addNewMedia,
|
|
1834
|
-
canAddNew: props.canUploadAssets
|
|
1835
|
-
}), React__default.createElement(ToolbarButton, {
|
|
1836
|
-
isDisabled: props.disabled,
|
|
1837
|
-
testId: "markdown-action-button-zen",
|
|
1838
|
-
variant: "secondary",
|
|
1839
|
-
onClick: props.actions.openZenMode,
|
|
1840
|
-
className: styles$5.zenButton,
|
|
1841
|
-
tooltip: "Expand"
|
|
1842
|
-
}, React__default.createElement(Zen, {
|
|
1843
|
-
label: "Expand",
|
|
1844
|
-
className: styles$5.icon
|
|
1845
|
-
})))), showAdditional && React__default.createElement(f36Components.Flex, {
|
|
1846
|
-
justifyContent: "space-between",
|
|
1847
|
-
marginTop: "spacingXs"
|
|
1848
|
-
}, React__default.createElement(f36Components.Flex, null, React__default.createElement(AdditionalButtons, { ...props
|
|
1849
|
-
}))));
|
|
1850
|
-
}
|
|
1851
|
-
function ZenMarkdownToolbar(props) {
|
|
1852
|
-
return React__default.createElement("div", {
|
|
1853
|
-
className: styles$5.root
|
|
1854
|
-
}, React__default.createElement(f36Components.Flex, {
|
|
1855
|
-
justifyContent: "space-between"
|
|
1856
|
-
}, React__default.createElement(f36Components.Flex, null, React__default.createElement(MainButtons, { ...props
|
|
1857
|
-
}), React__default.createElement(AdditionalButtons, { ...props
|
|
1858
|
-
})), React__default.createElement(f36Components.Flex, null, React__default.createElement(InsertLinkSelector, {
|
|
1859
|
-
disabled: props.disabled,
|
|
1860
|
-
onSelectExisting: props.actions.linkExistingMedia,
|
|
1861
|
-
onAddNew: props.actions.addNewMedia,
|
|
1862
|
-
canAddNew: props.canUploadAssets
|
|
1863
|
-
}), React__default.createElement(f36Components.IconButton, {
|
|
1864
|
-
testId: "markdown-action-button-zen-close",
|
|
1865
|
-
variant: "secondary",
|
|
1866
|
-
size: "small",
|
|
1867
|
-
className: emotion.cx(styles$5.zenButton, styles$5.zenButtonPressed),
|
|
1868
|
-
onClick: () => {
|
|
1869
|
-
props.actions.closeZenMode();
|
|
1870
|
-
},
|
|
1871
|
-
icon: React__default.createElement(Zen, {
|
|
1872
|
-
label: "Collapse",
|
|
1873
|
-
className: styles$5.icon
|
|
1874
|
-
}),
|
|
1875
|
-
"aria-label": "Collapse"
|
|
1876
|
-
}))));
|
|
1877
|
-
}
|
|
1878
|
-
const MarkdownToolbar = /*#__PURE__*/React__default.memo(props => {
|
|
1879
|
-
if (props.mode === 'zen') {
|
|
1880
|
-
return React__default.createElement(ZenMarkdownToolbar, { ...props
|
|
1881
|
-
});
|
|
1882
|
-
}
|
|
1883
|
-
|
|
1884
|
-
return React__default.createElement(DefaultMarkdownToolbar, { ...props
|
|
1885
|
-
});
|
|
1886
|
-
});
|
|
1887
|
-
MarkdownToolbar.displayName = 'MarkdownToolbar';
|
|
1888
|
-
|
|
1889
|
-
var MarkdownDialogType;
|
|
1890
|
-
|
|
1891
|
-
(function (MarkdownDialogType) {
|
|
1892
|
-
MarkdownDialogType["cheatsheet"] = "markdown-cheatsheet";
|
|
1893
|
-
MarkdownDialogType["insertLink"] = "markdown-insertLink";
|
|
1894
|
-
MarkdownDialogType["insertSpecialCharacter"] = "markdown-insertSpecialCharacter";
|
|
1895
|
-
MarkdownDialogType["insertTable"] = "markdown-insertTable";
|
|
1896
|
-
MarkdownDialogType["embedExternalContent"] = "markdown-embedExternalContent";
|
|
1897
|
-
MarkdownDialogType["confirmInsertAsset"] = "markdown-confirmInsertAsset";
|
|
1898
|
-
MarkdownDialogType["zenMode"] = "markdown-zenMode";
|
|
1899
|
-
})(MarkdownDialogType || (MarkdownDialogType = {}));
|
|
1900
|
-
|
|
1901
|
-
const styles$6 = {
|
|
1902
|
-
flexColumnContainer: /*#__PURE__*/emotion.css({
|
|
1903
|
-
display: 'flex',
|
|
1904
|
-
flexWrap: 'nowrap'
|
|
1905
|
-
}),
|
|
1906
|
-
flexColumn: /*#__PURE__*/emotion.css({
|
|
1907
|
-
flexGrow: 1
|
|
1908
|
-
}),
|
|
1909
|
-
verticalDivider: /*#__PURE__*/emotion.css({
|
|
1910
|
-
borderRight: `1px solid ${tokens.gray500}`,
|
|
1911
|
-
paddingRight: tokens.spacing3Xl,
|
|
1912
|
-
marginRight: tokens.spacing2Xl
|
|
1913
|
-
}),
|
|
1914
|
-
preview: /*#__PURE__*/emotion.css({
|
|
1915
|
-
display: 'inline-block',
|
|
1916
|
-
paddingRight: tokens.spacingL,
|
|
1917
|
-
width: '50%'
|
|
1918
|
-
}),
|
|
1919
|
-
unOrderedListPreview: /*#__PURE__*/emotion.css({
|
|
1920
|
-
listStyleType: 'disc',
|
|
1921
|
-
marginLeft: tokens.spacingS
|
|
1922
|
-
}),
|
|
1923
|
-
orderedListPreview: /*#__PURE__*/emotion.css({
|
|
1924
|
-
listStyleType: 'decimal',
|
|
1925
|
-
marginLeft: tokens.spacingS
|
|
1926
|
-
}),
|
|
1927
|
-
markup: /*#__PURE__*/emotion.css({
|
|
1928
|
-
display: 'inline-block',
|
|
1929
|
-
color: tokens.gray600,
|
|
1930
|
-
paddingLeft: tokens.spacingL,
|
|
1931
|
-
width: '50%'
|
|
1932
|
-
}),
|
|
1933
|
-
h1: /*#__PURE__*/emotion.css({
|
|
1934
|
-
fontSize: tokens.fontSize2Xl
|
|
1935
|
-
}),
|
|
1936
|
-
h2: /*#__PURE__*/emotion.css({
|
|
1937
|
-
fontSize: tokens.fontSizeXl
|
|
1938
|
-
}),
|
|
1939
|
-
h3: /*#__PURE__*/emotion.css({
|
|
1940
|
-
fontSize: tokens.fontSizeL
|
|
1941
|
-
}),
|
|
1942
|
-
helpItem: /*#__PURE__*/emotion.css({
|
|
1943
|
-
marginBottom: tokens.spacingS,
|
|
1944
|
-
display: 'flex',
|
|
1945
|
-
alignItems: 'flex-end',
|
|
1946
|
-
height: tokens.spacingXl
|
|
1947
|
-
}),
|
|
1948
|
-
helpLink: /*#__PURE__*/emotion.css({
|
|
1949
|
-
margin: 'auto'
|
|
1950
|
-
}),
|
|
1951
|
-
flexRowContainer: /*#__PURE__*/emotion.css({
|
|
1952
|
-
display: 'flex',
|
|
1953
|
-
width: '100%',
|
|
1954
|
-
justifyContent: 'center',
|
|
1955
|
-
marginTop: tokens.spacingXl
|
|
1956
|
-
})
|
|
1957
|
-
};
|
|
1958
|
-
const CheatsheetModalDialog = () => {
|
|
1959
|
-
return React__default.createElement(f36Components.ModalContent, {
|
|
1960
|
-
testId: "markdown-cheatsheet-dialog-content"
|
|
1961
|
-
}, React__default.createElement("div", {
|
|
1962
|
-
className: styles$6.flexColumnContainer
|
|
1963
|
-
}, React__default.createElement("div", {
|
|
1964
|
-
className: emotion.cx(styles$6.flexColumn, styles$6.verticalDivider)
|
|
1965
|
-
}, React__default.createElement("div", {
|
|
1966
|
-
className: styles$6.helpItem
|
|
1967
|
-
}, React__default.createElement(f36Components.Heading, {
|
|
1968
|
-
marginBottom: "none",
|
|
1969
|
-
as: "h1",
|
|
1970
|
-
className: emotion.cx(styles$6.preview, styles$6.h1)
|
|
1971
|
-
}, "H1"), React__default.createElement("div", {
|
|
1972
|
-
className: styles$6.markup
|
|
1973
|
-
}, "# heading")), React__default.createElement("div", {
|
|
1974
|
-
className: styles$6.helpItem
|
|
1975
|
-
}, React__default.createElement(f36Components.Heading, {
|
|
1976
|
-
marginBottom: "none",
|
|
1977
|
-
as: "h2",
|
|
1978
|
-
className: emotion.cx(styles$6.preview, styles$6.h2)
|
|
1979
|
-
}, "H2"), React__default.createElement("div", {
|
|
1980
|
-
className: styles$6.markup
|
|
1981
|
-
}, "## heading")), React__default.createElement("div", {
|
|
1982
|
-
className: styles$6.helpItem
|
|
1983
|
-
}, React__default.createElement(f36Components.Heading, {
|
|
1984
|
-
marginBottom: "none",
|
|
1985
|
-
as: "h3",
|
|
1986
|
-
className: emotion.cx(styles$6.preview, styles$6.h3)
|
|
1987
|
-
}, "H3"), React__default.createElement("div", {
|
|
1988
|
-
className: styles$6.markup
|
|
1989
|
-
}, "### heading")), React__default.createElement("div", {
|
|
1990
|
-
className: styles$6.helpItem
|
|
1991
|
-
}, React__default.createElement("strong", {
|
|
1992
|
-
className: styles$6.preview
|
|
1993
|
-
}, "bold"), React__default.createElement("div", {
|
|
1994
|
-
className: styles$6.markup
|
|
1995
|
-
}, "__text__")), React__default.createElement("div", {
|
|
1996
|
-
className: styles$6.helpItem
|
|
1997
|
-
}, React__default.createElement("em", {
|
|
1998
|
-
className: styles$6.preview
|
|
1999
|
-
}, "italic"), React__default.createElement("div", {
|
|
2000
|
-
className: styles$6.markup
|
|
2001
|
-
}, "*text*")), React__default.createElement("div", {
|
|
2002
|
-
className: styles$6.helpItem
|
|
2003
|
-
}, React__default.createElement("div", {
|
|
2004
|
-
className: styles$6.preview
|
|
2005
|
-
}, "strikethrough"), React__default.createElement("div", {
|
|
2006
|
-
className: styles$6.markup
|
|
2007
|
-
}, "~~text~~")), React__default.createElement("div", {
|
|
2008
|
-
className: styles$6.helpItem
|
|
2009
|
-
}, React__default.createElement(f36Components.TextLink, {
|
|
2010
|
-
as: "button",
|
|
2011
|
-
className: styles$6.preview
|
|
2012
|
-
}, "Link"), React__default.createElement("div", {
|
|
2013
|
-
className: styles$6.markup
|
|
2014
|
-
}, "[text](url)"))), React__default.createElement("div", {
|
|
2015
|
-
className: styles$6.flexColumn
|
|
2016
|
-
}, React__default.createElement("div", {
|
|
2017
|
-
className: styles$6.helpItem
|
|
2018
|
-
}, React__default.createElement("div", {
|
|
2019
|
-
className: styles$6.preview
|
|
2020
|
-
}, "Image"), React__default.createElement("div", {
|
|
2021
|
-
className: styles$6.markup
|
|
2022
|
-
}, "")), React__default.createElement("div", {
|
|
2023
|
-
className: styles$6.helpItem
|
|
2024
|
-
}, React__default.createElement("div", {
|
|
2025
|
-
className: styles$6.preview
|
|
2026
|
-
}, "Unordered list"), React__default.createElement("div", {
|
|
2027
|
-
className: styles$6.markup
|
|
2028
|
-
}, "* list item")), React__default.createElement("div", {
|
|
2029
|
-
className: styles$6.helpItem
|
|
2030
|
-
}, React__default.createElement("div", {
|
|
2031
|
-
className: styles$6.preview
|
|
2032
|
-
}, React__default.createElement("div", null, "Ordered list")), React__default.createElement("div", {
|
|
2033
|
-
className: styles$6.markup
|
|
2034
|
-
}, "1. list item")), React__default.createElement("div", {
|
|
2035
|
-
className: styles$6.helpItem
|
|
2036
|
-
}, React__default.createElement("div", {
|
|
2037
|
-
className: styles$6.preview
|
|
2038
|
-
}, React__default.createElement("div", null, "Blockquote")), React__default.createElement("div", {
|
|
2039
|
-
className: styles$6.markup
|
|
2040
|
-
}, "> quote")), React__default.createElement("div", {
|
|
2041
|
-
className: styles$6.helpItem
|
|
2042
|
-
}, React__default.createElement("div", {
|
|
2043
|
-
className: styles$6.preview
|
|
2044
|
-
}, "code span"), React__default.createElement("div", {
|
|
2045
|
-
className: styles$6.markup
|
|
2046
|
-
}, "`code here`")), React__default.createElement("div", {
|
|
2047
|
-
className: styles$6.helpItem
|
|
2048
|
-
}, React__default.createElement("div", {
|
|
2049
|
-
className: styles$6.preview
|
|
2050
|
-
}, "code block"), React__default.createElement("div", {
|
|
2051
|
-
className: styles$6.markup
|
|
2052
|
-
}, "```code here```")))), React__default.createElement("div", {
|
|
2053
|
-
className: styles$6.flexRowContainer
|
|
2054
|
-
}, React__default.createElement(f36Components.TextLink, {
|
|
2055
|
-
className: styles$6.helpLink,
|
|
2056
|
-
href: "https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax",
|
|
2057
|
-
target: "_blank",
|
|
2058
|
-
rel: "noopener noreferrer"
|
|
2059
|
-
}, "View the full GitHub-flavored Markdown syntax help (opens in a new window)")));
|
|
2060
|
-
};
|
|
2061
|
-
const openCheatsheetModal = dialogs => {
|
|
2062
|
-
return dialogs.openCurrent({
|
|
2063
|
-
title: 'Markdown formatting help',
|
|
2064
|
-
width: 'large',
|
|
2065
|
-
minHeight: '415px',
|
|
2066
|
-
shouldCloseOnEscapePress: true,
|
|
2067
|
-
shouldCloseOnOverlayClick: true,
|
|
2068
|
-
parameters: {
|
|
2069
|
-
type: MarkdownDialogType.cheatsheet
|
|
2070
|
-
}
|
|
2071
|
-
});
|
|
2072
|
-
};
|
|
2073
|
-
|
|
2074
|
-
const ConfirmInsertAssetModalDialog = ({
|
|
2075
|
-
onClose,
|
|
2076
|
-
assets,
|
|
2077
|
-
locale
|
|
2078
|
-
}) => {
|
|
2079
|
-
const localesNumber = assets.length;
|
|
2080
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(f36Components.ModalContent, {
|
|
2081
|
-
testId: "confirm-insert-asset"
|
|
2082
|
-
}, React__default.createElement(f36Components.Paragraph, null, localesNumber === 1 ? `Link asset with missing file for locale ${locale}` : `Link assets with missing files for locale ${locale}`), React__default.createElement(f36Components.Paragraph, null, localesNumber === 1 ? 'Do you want to link to the file in its fallback locale?' : 'Do you want to link to the files in their fallback locales?'), React__default.createElement(f36Components.EntityList, null, assets.map(({
|
|
2083
|
-
title,
|
|
2084
|
-
description,
|
|
2085
|
-
thumbnailUrl,
|
|
2086
|
-
thumbnailAltText
|
|
2087
|
-
}) => React__default.createElement(f36Components.EntityList.Item, {
|
|
2088
|
-
key: thumbnailUrl,
|
|
2089
|
-
title: title,
|
|
2090
|
-
thumbnailUrl: `${thumbnailUrl}?w=46&h=46&fit=thumb`,
|
|
2091
|
-
thumbnailAltText: thumbnailAltText,
|
|
2092
|
-
description: description
|
|
2093
|
-
})))), React__default.createElement(f36Components.ModalControls, null, React__default.createElement(f36Components.Button, {
|
|
2094
|
-
onClick: () => onClose(false),
|
|
2095
|
-
variant: "secondary",
|
|
2096
|
-
size: "small"
|
|
2097
|
-
}, "Cancel"), React__default.createElement(f36Components.Button, {
|
|
2098
|
-
testId: "confirm-insert-asset",
|
|
2099
|
-
onClick: () => onClose(true),
|
|
2100
|
-
variant: "positive",
|
|
2101
|
-
size: "small"
|
|
2102
|
-
}, "Confirm")));
|
|
2103
|
-
};
|
|
2104
|
-
const openConfirmInsertAsset = (dialogs, options) => {
|
|
2105
|
-
return dialogs.openCurrent({
|
|
2106
|
-
title: 'Confirm using fallback assets',
|
|
2107
|
-
width: 'medium',
|
|
2108
|
-
minHeight: '270px',
|
|
2109
|
-
shouldCloseOnEscapePress: true,
|
|
2110
|
-
shouldCloseOnOverlayClick: true,
|
|
2111
|
-
parameters: {
|
|
2112
|
-
type: MarkdownDialogType.confirmInsertAsset,
|
|
2113
|
-
...options
|
|
2114
|
-
}
|
|
2115
|
-
});
|
|
2116
|
-
};
|
|
2117
|
-
|
|
2118
|
-
const urlRegex = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?$/;
|
|
2119
|
-
function isValidUrl(value) {
|
|
2120
|
-
return urlRegex.test(value);
|
|
2121
|
-
}
|
|
2122
|
-
|
|
2123
|
-
const styles$7 = {
|
|
2124
|
-
widthFiledGroup: /*#__PURE__*/emotion.css({
|
|
2125
|
-
display: 'flex',
|
|
2126
|
-
flexWrap: 'nowrap',
|
|
2127
|
-
alignItems: 'flex-start'
|
|
2128
|
-
}),
|
|
2129
|
-
radioButtonGroup: /*#__PURE__*/emotion.css({
|
|
2130
|
-
display: 'inline-flex',
|
|
2131
|
-
alignItems: 'flex-start',
|
|
2132
|
-
paddingTop: tokens.spacingXl
|
|
2133
|
-
}),
|
|
2134
|
-
radioButton: /*#__PURE__*/emotion.css({
|
|
2135
|
-
marginLeft: tokens.spacingM
|
|
2136
|
-
})
|
|
2137
|
-
};
|
|
2138
|
-
|
|
2139
|
-
const makeEmbedlyLink = ({
|
|
2140
|
-
url,
|
|
2141
|
-
width,
|
|
2142
|
-
selectedUnit,
|
|
2143
|
-
attachSocial
|
|
2144
|
-
}) => {
|
|
2145
|
-
const s = {
|
|
2146
|
-
percent: '%',
|
|
2147
|
-
px: 'px'
|
|
2148
|
-
};
|
|
2149
|
-
return ['<a href="' + url + '" class="embedly-card" ', 'data-card-width="' + width + s[selectedUnit] + '" ', 'data-card-controls="' + (attachSocial ? '1' : '0') + '"', '>Embedded content: ' + url + '</a>'].join('');
|
|
2150
|
-
};
|
|
2151
|
-
|
|
2152
|
-
const isWidthValid = (width, unit) => unit === 'percent' ? width <= 100 : true;
|
|
2153
|
-
|
|
2154
|
-
const EmbedExternalContentModal = ({
|
|
2155
|
-
onClose
|
|
2156
|
-
}) => {
|
|
2157
|
-
const mainInputRef = React.useRef(null);
|
|
2158
|
-
const [url, setUrl] = React.useState('https://');
|
|
2159
|
-
const [selectedUnit, setUnit] = React.useState('percent');
|
|
2160
|
-
const [urlIsValid, setUrlValidity] = React.useState(true);
|
|
2161
|
-
const [width, setWidth] = React.useState('100');
|
|
2162
|
-
const [attachSocial, setAttachSocial] = React.useState(false);
|
|
2163
|
-
React.useEffect(() => {
|
|
2164
|
-
var _mainInputRef$current;
|
|
2165
|
-
|
|
2166
|
-
if ((_mainInputRef$current = mainInputRef.current) != null && _mainInputRef$current.focus) {
|
|
2167
|
-
mainInputRef.current.focus();
|
|
2168
|
-
}
|
|
2169
|
-
}, [mainInputRef]);
|
|
2170
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(f36Components.ModalContent, {
|
|
2171
|
-
testId: "embed-external-dialog"
|
|
2172
|
-
}, React__default.createElement(f36Components.Form, null, React__default.createElement(f36Components.FormControl, {
|
|
2173
|
-
id: "external-link-url-field",
|
|
2174
|
-
isRequired: true,
|
|
2175
|
-
isInvalid: !urlIsValid
|
|
2176
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Content URL"), React__default.createElement(f36Components.TextInput, {
|
|
2177
|
-
name: "external-link-url",
|
|
2178
|
-
value: url,
|
|
2179
|
-
onChange: e => {
|
|
2180
|
-
const value = e.target.value;
|
|
2181
|
-
setUrl(value);
|
|
2182
|
-
setUrlValidity(isValidUrl(value));
|
|
2183
|
-
},
|
|
2184
|
-
testId: "external-link-url-field",
|
|
2185
|
-
placeholder: "https://example.com",
|
|
2186
|
-
ref: mainInputRef
|
|
2187
|
-
}), React__default.createElement(f36Components.FormControl.HelpText, null, "Include protocol (e.g. https://)"), !urlIsValid && React__default.createElement(f36Components.FormControl.ValidationMessage, null, "URL is invalid")), React__default.createElement(f36Components.TextLink, {
|
|
2188
|
-
href: "http://embed.ly/providers",
|
|
2189
|
-
target: "_blank",
|
|
2190
|
-
rel: "noopener noreferrer"
|
|
2191
|
-
}, "Supported sources"), React__default.createElement("div", {
|
|
2192
|
-
className: styles$7.widthFiledGroup
|
|
2193
|
-
}, React__default.createElement(f36Components.FormControl, {
|
|
2194
|
-
id: "embedded-content-width",
|
|
2195
|
-
isRequired: true,
|
|
2196
|
-
isInvalid: !isWidthValid(Number(width), selectedUnit)
|
|
2197
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Width"), React__default.createElement(f36Components.TextInput, {
|
|
2198
|
-
value: width,
|
|
2199
|
-
name: "embedded-content-width",
|
|
2200
|
-
testId: "embedded-content-width",
|
|
2201
|
-
type: "number",
|
|
2202
|
-
width: "small",
|
|
2203
|
-
onChange: e => setWidth(e.target.value)
|
|
2204
|
-
}), !isWidthValid(Number(width), selectedUnit) && React__default.createElement(f36Components.FormControl.ValidationMessage, null, "Should be equal or less then 100")), React__default.createElement("div", {
|
|
2205
|
-
className: styles$7.radioButtonGroup
|
|
2206
|
-
}, React__default.createElement(f36Components.Radio, {
|
|
2207
|
-
id: "unit-option-percent",
|
|
2208
|
-
value: "percent",
|
|
2209
|
-
isChecked: selectedUnit === 'percent',
|
|
2210
|
-
onChange: () => setUnit('percent'),
|
|
2211
|
-
className: styles$7.radioButton
|
|
2212
|
-
}, "percent"), React__default.createElement(f36Components.Radio, {
|
|
2213
|
-
id: "unit-option-pixels",
|
|
2214
|
-
value: "pixels",
|
|
2215
|
-
isChecked: selectedUnit === 'px',
|
|
2216
|
-
onChange: () => setUnit('px'),
|
|
2217
|
-
className: styles$7.radioButton
|
|
2218
|
-
}, "pixels"))), React__default.createElement(f36Components.Checkbox, {
|
|
2219
|
-
id: "attach-social-checkbox",
|
|
2220
|
-
name: "attach-social-checkbox",
|
|
2221
|
-
value: "Yes",
|
|
2222
|
-
isChecked: attachSocial,
|
|
2223
|
-
onChange: () => setAttachSocial(!attachSocial),
|
|
2224
|
-
testId: "attach-social-checkbox"
|
|
2225
|
-
}, "Attach social sharing links to this element"), React__default.createElement(f36Components.Text, {
|
|
2226
|
-
as: "p",
|
|
2227
|
-
fontColor: "gray500",
|
|
2228
|
-
marginTop: "spacingXs"
|
|
2229
|
-
}, "To enable this embedded content in your application make sure to add the\u00A0", React__default.createElement(f36Components.TextLink, {
|
|
2230
|
-
href: "http://embed.ly/docs/products/cards",
|
|
2231
|
-
target: "_blank",
|
|
2232
|
-
rel: "noopener noreferrer"
|
|
2233
|
-
}, "Embedly's platform.js"), "\u00A0on your development environment"))), React__default.createElement(f36Components.ModalControls, null, React__default.createElement(f36Components.Button, {
|
|
2234
|
-
testId: "emded-external-cancel",
|
|
2235
|
-
onClick: () => onClose(false),
|
|
2236
|
-
variant: "secondary",
|
|
2237
|
-
size: "small"
|
|
2238
|
-
}, "Cancel"), React__default.createElement(f36Components.Button, {
|
|
2239
|
-
testId: "embed-external-confirm",
|
|
2240
|
-
onClick: () => onClose(makeEmbedlyLink({
|
|
2241
|
-
url,
|
|
2242
|
-
width: Number(width),
|
|
2243
|
-
selectedUnit,
|
|
2244
|
-
attachSocial
|
|
2245
|
-
})),
|
|
2246
|
-
variant: "positive",
|
|
2247
|
-
size: "small"
|
|
2248
|
-
}, "Insert")));
|
|
2249
|
-
};
|
|
2250
|
-
const openEmbedExternalContentDialog = dialogs => {
|
|
2251
|
-
return dialogs.openCurrent({
|
|
2252
|
-
title: 'Embed external content',
|
|
2253
|
-
width: 'large',
|
|
2254
|
-
minHeight: '435px',
|
|
2255
|
-
shouldCloseOnEscapePress: true,
|
|
2256
|
-
shouldCloseOnOverlayClick: true,
|
|
2257
|
-
parameters: {
|
|
2258
|
-
type: MarkdownDialogType.embedExternalContent
|
|
2259
|
-
}
|
|
2260
|
-
});
|
|
2261
|
-
};
|
|
2262
|
-
|
|
2263
|
-
const InsertLinkModal = ({
|
|
2264
|
-
selectedText,
|
|
2265
|
-
onClose
|
|
2266
|
-
}) => {
|
|
2267
|
-
const mainInputRef = React.useRef(null);
|
|
2268
|
-
const [text, setText] = React.useState(selectedText || '');
|
|
2269
|
-
const [url, setUrl] = React.useState('');
|
|
2270
|
-
const [touched, setTouched] = React.useState(false);
|
|
2271
|
-
const [title, setTitle] = React.useState('');
|
|
2272
|
-
|
|
2273
|
-
const onInsert = values => onClose(values);
|
|
2274
|
-
|
|
2275
|
-
const urlIsValid = isValidUrl(url);
|
|
2276
|
-
React.useEffect(() => {
|
|
2277
|
-
var _mainInputRef$current;
|
|
2278
|
-
|
|
2279
|
-
if (mainInputRef != null && (_mainInputRef$current = mainInputRef.current) != null && _mainInputRef$current.focus) {
|
|
2280
|
-
mainInputRef.current.focus();
|
|
2281
|
-
}
|
|
2282
|
-
}, [mainInputRef]);
|
|
2283
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(f36Components.ModalContent, {
|
|
2284
|
-
testId: "insert-link-modal"
|
|
2285
|
-
}, React__default.createElement(f36Components.Form, {
|
|
2286
|
-
onSubmit: () => onInsert({
|
|
2287
|
-
url,
|
|
2288
|
-
text,
|
|
2289
|
-
title
|
|
2290
|
-
})
|
|
2291
|
-
}, React__default.createElement(f36Components.FormControl, {
|
|
2292
|
-
id: "link-text-field",
|
|
2293
|
-
isDisabled: Boolean(selectedText)
|
|
2294
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Link text"), React__default.createElement(f36Components.TextInput, {
|
|
2295
|
-
name: "link-text",
|
|
2296
|
-
value: text,
|
|
2297
|
-
onChange: e => {
|
|
2298
|
-
setText(e.target.value);
|
|
2299
|
-
},
|
|
2300
|
-
testId: "link-text-field"
|
|
2301
|
-
})), React__default.createElement(f36Components.FormControl, {
|
|
2302
|
-
id: "target-url-field",
|
|
2303
|
-
isInvalid: touched && !urlIsValid
|
|
2304
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Target URL"), React__default.createElement(f36Components.TextInput, {
|
|
2305
|
-
name: "target-url",
|
|
2306
|
-
value: url,
|
|
2307
|
-
onChange: e => {
|
|
2308
|
-
setUrl(e.target.value);
|
|
2309
|
-
setTouched(true);
|
|
2310
|
-
},
|
|
2311
|
-
placeholder: "https://",
|
|
2312
|
-
maxLength: 2100,
|
|
2313
|
-
testId: "target-url-field",
|
|
2314
|
-
ref: mainInputRef
|
|
2315
|
-
}), React__default.createElement(f36Components.FormControl.HelpText, null, "Include protocol (e.g. https://)"), touched && !urlIsValid && React__default.createElement(f36Components.FormControl.ValidationMessage, null, "Invalid URL")), React__default.createElement(f36Components.FormControl, {
|
|
2316
|
-
id: "link-title-field"
|
|
2317
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Link title"), React__default.createElement(f36Components.TextInput, {
|
|
2318
|
-
name: "link-title",
|
|
2319
|
-
value: title,
|
|
2320
|
-
onChange: e => {
|
|
2321
|
-
setTitle(e.target.value);
|
|
2322
|
-
},
|
|
2323
|
-
testId: "link-title-field"
|
|
2324
|
-
}), React__default.createElement(f36Components.FormControl.HelpText, null, "Extra link information, usually shown as a tooltip on mouse hover")))), React__default.createElement(f36Components.ModalControls, null, React__default.createElement(f36Components.Button, {
|
|
2325
|
-
testId: "insert-link-cancel",
|
|
2326
|
-
onClick: () => onClose(false),
|
|
2327
|
-
variant: "secondary",
|
|
2328
|
-
size: "small"
|
|
2329
|
-
}, "Cancel"), React__default.createElement(f36Components.Button, {
|
|
2330
|
-
testId: "insert-link-confirm",
|
|
2331
|
-
onClick: () => {
|
|
2332
|
-
onInsert({
|
|
2333
|
-
url,
|
|
2334
|
-
text,
|
|
2335
|
-
title
|
|
2336
|
-
});
|
|
2337
|
-
},
|
|
2338
|
-
isDisabled: !urlIsValid,
|
|
2339
|
-
variant: "positive",
|
|
2340
|
-
size: "small"
|
|
2341
|
-
}, "Insert")));
|
|
2342
|
-
};
|
|
2343
|
-
const openInsertLinkDialog = (dialogs, params) => {
|
|
2344
|
-
return dialogs.openCurrent({
|
|
2345
|
-
title: 'Insert link',
|
|
2346
|
-
width: 'large',
|
|
2347
|
-
minHeight: '410px',
|
|
2348
|
-
shouldCloseOnEscapePress: true,
|
|
2349
|
-
shouldCloseOnOverlayClick: true,
|
|
2350
|
-
parameters: {
|
|
2351
|
-
type: MarkdownDialogType.insertLink,
|
|
2352
|
-
...params
|
|
2353
|
-
}
|
|
2354
|
-
});
|
|
2355
|
-
};
|
|
2356
|
-
|
|
2357
|
-
const InsertTableModal = ({
|
|
2358
|
-
onClose
|
|
2359
|
-
}) => {
|
|
2360
|
-
const mainInputRef = React.useRef(null);
|
|
2361
|
-
const [rows, setRows] = React.useState(2);
|
|
2362
|
-
const [cols, setColumns] = React.useState(1);
|
|
2363
|
-
const rowsAreValid = inRange(rows, 2, 100);
|
|
2364
|
-
const colsAreValid = inRange(cols, 1, 100);
|
|
2365
|
-
React.useEffect(() => {
|
|
2366
|
-
var _mainInputRef$current;
|
|
2367
|
-
|
|
2368
|
-
if ((_mainInputRef$current = mainInputRef.current) != null && _mainInputRef$current.focus) {
|
|
2369
|
-
mainInputRef.current.focus();
|
|
2370
|
-
}
|
|
2371
|
-
}, [mainInputRef]);
|
|
2372
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(f36Components.ModalContent, {
|
|
2373
|
-
testId: "insert-table-modal"
|
|
2374
|
-
}, React__default.createElement(f36Components.Form, null, React__default.createElement(f36Components.FormControl, {
|
|
2375
|
-
id: "insert-table-rows-number-field",
|
|
2376
|
-
isRequired: true,
|
|
2377
|
-
isInvalid: !rowsAreValid
|
|
2378
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Number of rows"), React__default.createElement(f36Components.TextInput, {
|
|
2379
|
-
name: "rows",
|
|
2380
|
-
value: rows.toString(),
|
|
2381
|
-
onChange: e => setRows(Number(e.target.value)),
|
|
2382
|
-
testId: "insert-table-rows-number-field",
|
|
2383
|
-
min: 2,
|
|
2384
|
-
max: 100,
|
|
2385
|
-
pattern: "[1-9][0-9]*",
|
|
2386
|
-
type: "number",
|
|
2387
|
-
width: "small",
|
|
2388
|
-
autoComplete: "off",
|
|
2389
|
-
ref: mainInputRef
|
|
2390
|
-
}), !rowsAreValid && React__default.createElement(f36Components.FormControl.ValidationMessage, null, "Should be between 2 and 100")), React__default.createElement(f36Components.FormControl, {
|
|
2391
|
-
id: "insert-table-columns-number-field",
|
|
2392
|
-
isRequired: true,
|
|
2393
|
-
isInvalid: !colsAreValid
|
|
2394
|
-
}, React__default.createElement(f36Components.FormControl.Label, null, "Number of columns"), React__default.createElement(f36Components.TextInput, {
|
|
2395
|
-
name: "columns",
|
|
2396
|
-
value: cols.toString(),
|
|
2397
|
-
onChange: e => setColumns(Number(e.target.value)),
|
|
2398
|
-
testId: "insert-table-columns-number-field",
|
|
2399
|
-
min: 1,
|
|
2400
|
-
max: 100,
|
|
2401
|
-
pattern: "[1-9][0-9]*",
|
|
2402
|
-
type: "number",
|
|
2403
|
-
width: "small",
|
|
2404
|
-
autoComplete: "off"
|
|
2405
|
-
}), !colsAreValid && React__default.createElement(f36Components.FormControl.ValidationMessage, null, "Should be between 1 and 100")))), React__default.createElement(f36Components.ModalControls, null, React__default.createElement(f36Components.Button, {
|
|
2406
|
-
testId: "insert-table-cancel",
|
|
2407
|
-
onClick: () => onClose(false),
|
|
2408
|
-
variant: "secondary",
|
|
2409
|
-
size: "small"
|
|
2410
|
-
}, "Cancel"), React__default.createElement(f36Components.Button, {
|
|
2411
|
-
testId: "insert-table-confirm",
|
|
2412
|
-
onClick: () => onClose({
|
|
2413
|
-
rows,
|
|
2414
|
-
cols
|
|
2415
|
-
}),
|
|
2416
|
-
variant: "positive",
|
|
2417
|
-
size: "small",
|
|
2418
|
-
isDisabled: !rowsAreValid || !colsAreValid
|
|
2419
|
-
}, "Insert")));
|
|
2420
|
-
};
|
|
2421
|
-
const openInsertTableDialog = dialogs => {
|
|
2422
|
-
return dialogs.openCurrent({
|
|
2423
|
-
title: 'Insert table',
|
|
2424
|
-
width: 'medium',
|
|
2425
|
-
minHeight: '260px',
|
|
2426
|
-
shouldCloseOnEscapePress: true,
|
|
2427
|
-
shouldCloseOnOverlayClick: true,
|
|
2428
|
-
parameters: {
|
|
2429
|
-
type: MarkdownDialogType.insertTable
|
|
2430
|
-
}
|
|
2431
|
-
});
|
|
2432
|
-
};
|
|
2433
|
-
|
|
2434
|
-
const specialCharacters = [{
|
|
2435
|
-
code: 180,
|
|
2436
|
-
desc: 'acute accent'
|
|
2437
|
-
}, {
|
|
2438
|
-
code: 38,
|
|
2439
|
-
desc: 'ampersand'
|
|
2440
|
-
}, {
|
|
2441
|
-
code: 166,
|
|
2442
|
-
desc: 'broken vertical bar'
|
|
2443
|
-
}, {
|
|
2444
|
-
code: 8226,
|
|
2445
|
-
desc: 'bullet'
|
|
2446
|
-
}, {
|
|
2447
|
-
code: 184,
|
|
2448
|
-
desc: 'cedilla'
|
|
2449
|
-
}, {
|
|
2450
|
-
code: 162,
|
|
2451
|
-
desc: 'cent'
|
|
2452
|
-
}, {
|
|
2453
|
-
code: 169,
|
|
2454
|
-
desc: 'copyright'
|
|
2455
|
-
}, {
|
|
2456
|
-
code: 176,
|
|
2457
|
-
desc: 'degree'
|
|
2458
|
-
}, {
|
|
2459
|
-
code: 247,
|
|
2460
|
-
desc: 'division'
|
|
2461
|
-
}, {
|
|
2462
|
-
code: 189,
|
|
2463
|
-
desc: 'fraction half'
|
|
2464
|
-
}, {
|
|
2465
|
-
code: 188,
|
|
2466
|
-
desc: 'fraction quarter'
|
|
2467
|
-
}, {
|
|
2468
|
-
code: 190,
|
|
2469
|
-
desc: 'fraction three quarters'
|
|
2470
|
-
}, {
|
|
2471
|
-
code: 62,
|
|
2472
|
-
desc: 'greater than'
|
|
2473
|
-
}, {
|
|
2474
|
-
code: 161,
|
|
2475
|
-
desc: 'inverted exclamation mark'
|
|
2476
|
-
}, {
|
|
2477
|
-
code: 191,
|
|
2478
|
-
desc: 'inverted question mark'
|
|
2479
|
-
}, {
|
|
2480
|
-
code: 171,
|
|
2481
|
-
desc: 'left-pointing double angle quotation mark'
|
|
2482
|
-
}, {
|
|
2483
|
-
code: 60,
|
|
2484
|
-
desc: 'less than'
|
|
2485
|
-
}, {
|
|
2486
|
-
code: 175,
|
|
2487
|
-
desc: 'macron'
|
|
2488
|
-
}, {
|
|
2489
|
-
code: 181,
|
|
2490
|
-
desc: 'micro'
|
|
2491
|
-
}, {
|
|
2492
|
-
code: 160,
|
|
2493
|
-
desc: 'non-breaking space'
|
|
2494
|
-
}, {
|
|
2495
|
-
code: 172,
|
|
2496
|
-
desc: 'not'
|
|
2497
|
-
}, {
|
|
2498
|
-
code: 182,
|
|
2499
|
-
desc: 'paragraph'
|
|
2500
|
-
}, {
|
|
2501
|
-
code: 177,
|
|
2502
|
-
desc: 'plus-minus'
|
|
2503
|
-
}, {
|
|
2504
|
-
code: 34,
|
|
2505
|
-
desc: 'quotation mark'
|
|
2506
|
-
}, {
|
|
2507
|
-
code: 174,
|
|
2508
|
-
desc: 'registered'
|
|
2509
|
-
}, {
|
|
2510
|
-
code: 187,
|
|
2511
|
-
desc: 'right-pointing double angle quotation mark'
|
|
2512
|
-
}, {
|
|
2513
|
-
code: 167,
|
|
2514
|
-
desc: 'section'
|
|
2515
|
-
}, {
|
|
2516
|
-
code: 168,
|
|
2517
|
-
desc: 'umlaut/diaeresis'
|
|
2518
|
-
}, {
|
|
2519
|
-
code: 215,
|
|
2520
|
-
desc: 'multiplication'
|
|
2521
|
-
}, {
|
|
2522
|
-
code: 8482,
|
|
2523
|
-
desc: 'trade mark'
|
|
2524
|
-
}, {
|
|
2525
|
-
code: 8364,
|
|
2526
|
-
desc: 'euro'
|
|
2527
|
-
}, {
|
|
2528
|
-
code: 163,
|
|
2529
|
-
desc: 'pound'
|
|
2530
|
-
}, {
|
|
2531
|
-
code: 165,
|
|
2532
|
-
desc: 'yen'
|
|
2533
|
-
}, {
|
|
2534
|
-
code: 8222,
|
|
2535
|
-
desc: 'double low-9 quotation mark'
|
|
2536
|
-
}, {
|
|
2537
|
-
code: 710,
|
|
2538
|
-
desc: 'modifier circumflex accent'
|
|
2539
|
-
}, {
|
|
2540
|
-
code: 8224,
|
|
2541
|
-
desc: 'dagger'
|
|
2542
|
-
}, {
|
|
2543
|
-
code: 8225,
|
|
2544
|
-
desc: 'double dagger'
|
|
2545
|
-
}, {
|
|
2546
|
-
code: 8230,
|
|
2547
|
-
desc: 'horizontal ellipsis'
|
|
2548
|
-
}, {
|
|
2549
|
-
code: 8220,
|
|
2550
|
-
desc: 'left double quotation mark'
|
|
2551
|
-
}, {
|
|
2552
|
-
code: 8249,
|
|
2553
|
-
desc: 'single left-pointing angle quotation mark'
|
|
2554
|
-
}, {
|
|
2555
|
-
code: 8216,
|
|
2556
|
-
desc: 'left single quotation mark'
|
|
2557
|
-
}, {
|
|
2558
|
-
code: 183,
|
|
2559
|
-
desc: 'middle dot'
|
|
2560
|
-
}, {
|
|
2561
|
-
code: 8212,
|
|
2562
|
-
desc: 'em dash'
|
|
2563
|
-
}, {
|
|
2564
|
-
code: 8211,
|
|
2565
|
-
desc: 'en dash'
|
|
2566
|
-
}, {
|
|
2567
|
-
code: 8240,
|
|
2568
|
-
desc: 'per mille'
|
|
2569
|
-
}, {
|
|
2570
|
-
code: 8250,
|
|
2571
|
-
desc: 'single right-pointing angle quotation mark'
|
|
2572
|
-
}, {
|
|
2573
|
-
code: 8217,
|
|
2574
|
-
desc: 'right single quotation mark'
|
|
2575
|
-
}, {
|
|
2576
|
-
code: 8218,
|
|
2577
|
-
desc: 'single low-9 quotation mark'
|
|
2578
|
-
}, {
|
|
2579
|
-
code: 170,
|
|
2580
|
-
desc: 'feminine ordinal indicator'
|
|
2581
|
-
}, {
|
|
2582
|
-
code: 186,
|
|
2583
|
-
desc: 'masculine ordinal indicator'
|
|
2584
|
-
}, {
|
|
2585
|
-
code: 8221,
|
|
2586
|
-
desc: 'right double quotation mark'
|
|
2587
|
-
}, {
|
|
2588
|
-
code: 732,
|
|
2589
|
-
desc: 'small tilde'
|
|
2590
|
-
}, {
|
|
2591
|
-
code: 9829,
|
|
2592
|
-
desc: 'black heart'
|
|
2593
|
-
}, {
|
|
2594
|
-
code: 9830,
|
|
2595
|
-
desc: 'diamond'
|
|
2596
|
-
}];
|
|
2597
|
-
|
|
2598
|
-
const styles$8 = {
|
|
2599
|
-
buttonPanel: /*#__PURE__*/emotion.css({
|
|
2600
|
-
display: 'flex',
|
|
2601
|
-
flexWrap: 'wrap'
|
|
2602
|
-
}),
|
|
2603
|
-
charButton: /*#__PURE__*/emotion.css({
|
|
2604
|
-
border: `1px solid ${tokens.gray500}`,
|
|
2605
|
-
width: '4.1rem',
|
|
2606
|
-
height: '4.1rem',
|
|
2607
|
-
fontSize: tokens.fontSizeXl,
|
|
2608
|
-
marginTop: tokens.spacing2Xs,
|
|
2609
|
-
marginRight: tokens.spacing2Xs
|
|
2610
|
-
}),
|
|
2611
|
-
selectedCharButton: /*#__PURE__*/emotion.css({
|
|
2612
|
-
backgroundColor: tokens.gray100
|
|
2613
|
-
}),
|
|
2614
|
-
tooltip: /*#__PURE__*/emotion.css({
|
|
2615
|
-
zIndex: 1000
|
|
2616
|
-
}),
|
|
2617
|
-
button: /*#__PURE__*/emotion.css({
|
|
2618
|
-
marginTop: tokens.spacingM,
|
|
2619
|
-
marginRight: tokens.spacingS
|
|
2620
|
-
})
|
|
2621
|
-
};
|
|
2622
|
-
const SpecialCharacterModalDialog = ({
|
|
2623
|
-
onClose
|
|
2624
|
-
}) => {
|
|
2625
|
-
const [selectedCharacter, setSelectedCharacter] = React.useState(specialCharacters[0]);
|
|
2626
|
-
return React__default.createElement(React__default.Fragment, null, React__default.createElement(f36Components.ModalContent, {
|
|
2627
|
-
testId: "insert-special-character-modal"
|
|
2628
|
-
}, React__default.createElement(f36Components.Flex, {
|
|
2629
|
-
flexDirection: "column",
|
|
2630
|
-
alignItems: "center"
|
|
2631
|
-
}, React__default.createElement(f36Components.Text, {
|
|
2632
|
-
as: "div",
|
|
2633
|
-
lineHeight: "lineHeight3Xl",
|
|
2634
|
-
fontSize: "fontSize3Xl",
|
|
2635
|
-
marginBottom: "spacingS"
|
|
2636
|
-
}, String.fromCharCode(selectedCharacter.code)), React__default.createElement(f36Components.Text, {
|
|
2637
|
-
as: "div",
|
|
2638
|
-
marginBottom: "spacingS"
|
|
2639
|
-
}, selectedCharacter.desc)), React__default.createElement("div", {
|
|
2640
|
-
className: styles$8.buttonPanel
|
|
2641
|
-
}, specialCharacters.map(char => React__default.createElement("div", {
|
|
2642
|
-
key: char.code
|
|
2643
|
-
}, React__default.createElement(f36Components.Tooltip, {
|
|
2644
|
-
className: styles$8.tooltip,
|
|
2645
|
-
content: char.desc
|
|
2646
|
-
}, React__default.createElement(f36Components.Button, {
|
|
2647
|
-
testId: "special-character-button",
|
|
2648
|
-
isActive: char.code === selectedCharacter.code,
|
|
2649
|
-
className: styles$8.charButton,
|
|
2650
|
-
variant: "transparent",
|
|
2651
|
-
onClick: () => setSelectedCharacter(char)
|
|
2652
|
-
}, String.fromCharCode(char.code))))))), React__default.createElement(f36Components.ModalControls, null, React__default.createElement(f36Components.Button, {
|
|
2653
|
-
testId: "insert-character-cancel",
|
|
2654
|
-
className: styles$8.button,
|
|
2655
|
-
onClick: () => onClose(false),
|
|
2656
|
-
variant: "secondary",
|
|
2657
|
-
size: "small"
|
|
2658
|
-
}, "Cancel"), React__default.createElement(f36Components.Button, {
|
|
2659
|
-
className: styles$8.button,
|
|
2660
|
-
testId: "insert-character-confirm",
|
|
2661
|
-
onClick: () => onClose(String.fromCharCode(selectedCharacter.code)),
|
|
2662
|
-
variant: "positive",
|
|
2663
|
-
size: "small"
|
|
2664
|
-
}, "Insert selected")));
|
|
2665
|
-
};
|
|
2666
|
-
const openInsertSpecialCharacter = dialogs => {
|
|
2667
|
-
return dialogs.openCurrent({
|
|
2668
|
-
title: 'Insert special character',
|
|
2669
|
-
width: 'large',
|
|
2670
|
-
minHeight: '600px',
|
|
2671
|
-
shouldCloseOnEscapePress: true,
|
|
2672
|
-
shouldCloseOnOverlayClick: true,
|
|
2673
|
-
parameters: {
|
|
2674
|
-
type: MarkdownDialogType.insertSpecialCharacter
|
|
2675
|
-
}
|
|
2676
|
-
});
|
|
2677
|
-
};
|
|
2678
|
-
|
|
2679
|
-
const styles$9 = {
|
|
2680
|
-
root: /*#__PURE__*/emotion.css({
|
|
2681
|
-
position: 'fixed',
|
|
2682
|
-
left: 0,
|
|
2683
|
-
right: 0,
|
|
2684
|
-
top: 0,
|
|
2685
|
-
bottom: 0
|
|
2686
|
-
}),
|
|
2687
|
-
topSplit: /*#__PURE__*/emotion.css({
|
|
2688
|
-
position: 'fixed',
|
|
2689
|
-
top: 0,
|
|
2690
|
-
height: '48px',
|
|
2691
|
-
left: 0,
|
|
2692
|
-
right: 0
|
|
2693
|
-
}),
|
|
2694
|
-
bottomSplit: /*#__PURE__*/emotion.css({
|
|
2695
|
-
position: 'fixed',
|
|
2696
|
-
bottom: 0,
|
|
2697
|
-
left: 0,
|
|
2698
|
-
right: 0,
|
|
2699
|
-
height: '36px'
|
|
2700
|
-
}),
|
|
2701
|
-
editorSplit: /*#__PURE__*/emotion.css({
|
|
2702
|
-
width: '50%',
|
|
2703
|
-
position: 'fixed',
|
|
2704
|
-
top: '48px',
|
|
2705
|
-
left: 0,
|
|
2706
|
-
bottom: '36px',
|
|
2707
|
-
overflowX: 'hidden',
|
|
2708
|
-
overflowY: 'scroll'
|
|
2709
|
-
}),
|
|
2710
|
-
editorSplitFullscreen: /*#__PURE__*/emotion.css({
|
|
2711
|
-
left: 0,
|
|
2712
|
-
right: 0,
|
|
2713
|
-
width: '100%'
|
|
2714
|
-
}),
|
|
2715
|
-
previewSplit: /*#__PURE__*/emotion.css({
|
|
2716
|
-
width: '50%',
|
|
2717
|
-
position: 'fixed',
|
|
2718
|
-
top: '48px',
|
|
2719
|
-
right: 0,
|
|
2720
|
-
bottom: '36px',
|
|
2721
|
-
overflowX: 'hidden',
|
|
2722
|
-
overflowY: 'scroll'
|
|
2723
|
-
}),
|
|
2724
|
-
separator: /*#__PURE__*/emotion.css({
|
|
2725
|
-
position: 'fixed',
|
|
2726
|
-
top: '48px',
|
|
2727
|
-
bottom: '36px',
|
|
2728
|
-
width: '1px',
|
|
2729
|
-
background: tokens.gray400,
|
|
2730
|
-
left: '50%'
|
|
2731
|
-
}),
|
|
2732
|
-
button: /*#__PURE__*/emotion.css({
|
|
2733
|
-
position: 'fixed',
|
|
2734
|
-
cursor: 'pointer',
|
|
2735
|
-
zIndex: 105,
|
|
2736
|
-
top: '49%',
|
|
2737
|
-
height: '30px',
|
|
2738
|
-
backgroundColor: tokens.gray100,
|
|
2739
|
-
border: `1px solid ${tokens.gray400}`,
|
|
2740
|
-
padding: 0
|
|
2741
|
-
}),
|
|
2742
|
-
hideButton: /*#__PURE__*/emotion.css({
|
|
2743
|
-
left: '50%'
|
|
2744
|
-
}),
|
|
2745
|
-
showButton: /*#__PURE__*/emotion.css({
|
|
2746
|
-
right: 0,
|
|
2747
|
-
borderRightWidth: 0
|
|
2748
|
-
}),
|
|
2749
|
-
icon: /*#__PURE__*/emotion.css({
|
|
2750
|
-
verticalAlign: 'middle'
|
|
2751
|
-
})
|
|
2752
|
-
};
|
|
2753
|
-
const ZenModeModalDialog = props => {
|
|
2754
|
-
const [currentValue, setCurrentValue] = React__default.useState(props.initialValue ?? '');
|
|
2755
|
-
const [showPreview, setShowPreview] = React__default.useState(true);
|
|
2756
|
-
const [editor, setEditor] = React__default.useState(null);
|
|
2757
|
-
React__default.useEffect(() => {
|
|
2758
|
-
var _props$sdk, _props$sdk$window;
|
|
2759
|
-
|
|
2760
|
-
// eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/no-explicit-any
|
|
2761
|
-
(_props$sdk = props.sdk) == null ? void 0 : (_props$sdk$window = _props$sdk.window) == null ? void 0 : _props$sdk$window.updateHeight('100%'); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
2762
|
-
}, []); // refresh editor right after dialog is opened to avoid disappearing effect
|
|
2763
|
-
|
|
2764
|
-
React__default.useEffect(() => {
|
|
2765
|
-
setTimeout(() => {
|
|
2766
|
-
editor == null ? void 0 : editor.setFullsize();
|
|
2767
|
-
editor == null ? void 0 : editor.refresh();
|
|
2768
|
-
}, 150);
|
|
2769
|
-
}, [editor]);
|
|
2770
|
-
const actions = React__default.useMemo(() => {
|
|
2771
|
-
return createMarkdownActions({
|
|
2772
|
-
sdk: props.sdk,
|
|
2773
|
-
editor,
|
|
2774
|
-
locale: props.locale
|
|
2775
|
-
}); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
2776
|
-
}, [editor]);
|
|
2777
|
-
|
|
2778
|
-
actions.closeZenMode = () => {
|
|
2779
|
-
props.onClose({
|
|
2780
|
-
value: currentValue,
|
|
2781
|
-
cursor: editor == null ? void 0 : editor.getCursor()
|
|
2782
|
-
});
|
|
2783
|
-
};
|
|
2784
|
-
|
|
2785
|
-
const direction = props.sdk.locales.direction[props.locale] ?? 'ltr';
|
|
2786
|
-
return React__default.createElement("div", {
|
|
2787
|
-
className: styles$9.root,
|
|
2788
|
-
"data-test-id": "zen-mode-markdown-editor"
|
|
2789
|
-
}, React__default.createElement("div", {
|
|
2790
|
-
className: styles$9.topSplit
|
|
2791
|
-
}, React__default.createElement(MarkdownToolbar, {
|
|
2792
|
-
mode: "zen",
|
|
2793
|
-
disabled: false,
|
|
2794
|
-
canUploadAssets: false,
|
|
2795
|
-
actions: actions
|
|
2796
|
-
})), React__default.createElement("div", {
|
|
2797
|
-
className: emotion.cx(styles$9.editorSplit, {
|
|
2798
|
-
[styles$9.editorSplitFullscreen]: showPreview === false
|
|
2799
|
-
})
|
|
2800
|
-
}, React__default.createElement(MarkdownTextarea, {
|
|
2801
|
-
mode: "zen",
|
|
2802
|
-
visible: true,
|
|
2803
|
-
disabled: false,
|
|
2804
|
-
direction: direction,
|
|
2805
|
-
onReady: editor => {
|
|
2806
|
-
editor.setContent(props.initialValue ?? '');
|
|
2807
|
-
editor.setReadOnly(false);
|
|
2808
|
-
setEditor(editor);
|
|
2809
|
-
editor.focus();
|
|
2810
|
-
editor.events.onChange(value => {
|
|
2811
|
-
setCurrentValue(value);
|
|
2812
|
-
props.saveValueToSDK(value);
|
|
2813
|
-
});
|
|
2814
|
-
}
|
|
2815
|
-
})), showPreview && React__default.createElement("div", {
|
|
2816
|
-
className: styles$9.previewSplit
|
|
2817
|
-
}, React__default.createElement(MarkdownPreview, {
|
|
2818
|
-
direction: direction,
|
|
2819
|
-
mode: "zen",
|
|
2820
|
-
value: currentValue,
|
|
2821
|
-
previewComponents: props.previewComponents
|
|
2822
|
-
})), showPreview && React__default.createElement("div", {
|
|
2823
|
-
className: styles$9.separator
|
|
2824
|
-
}), showPreview && React__default.createElement("button", {
|
|
2825
|
-
className: emotion.cx(styles$9.button, styles$9.hideButton),
|
|
2826
|
-
"aria-label": "Hide preview",
|
|
2827
|
-
onClick: () => {
|
|
2828
|
-
setShowPreview(false);
|
|
2829
|
-
}
|
|
2830
|
-
}, React__default.createElement(f36Icons.ChevronRightIcon, {
|
|
2831
|
-
variant: "muted",
|
|
2832
|
-
size: "tiny",
|
|
2833
|
-
className: styles$9.icon
|
|
2834
|
-
})), !showPreview && React__default.createElement("button", {
|
|
2835
|
-
className: emotion.cx(styles$9.button, styles$9.showButton),
|
|
2836
|
-
"aria-label": "Show preview",
|
|
2837
|
-
onClick: () => {
|
|
2838
|
-
setShowPreview(true);
|
|
2839
|
-
}
|
|
2840
|
-
}, React__default.createElement(f36Icons.ChevronLeftIcon, {
|
|
2841
|
-
variant: "muted",
|
|
2842
|
-
size: "tiny",
|
|
2843
|
-
className: styles$9.icon
|
|
2844
|
-
})), React__default.createElement("div", {
|
|
2845
|
-
className: styles$9.bottomSplit
|
|
2846
|
-
}, React__default.createElement(MarkdownBottomBar, null, React__default.createElement(MarkdownHelp, {
|
|
2847
|
-
onClick: () => {
|
|
2848
|
-
openCheatsheetModal(props.sdk.dialogs);
|
|
2849
|
-
}
|
|
2850
|
-
}))));
|
|
2851
|
-
};
|
|
2852
|
-
const openZenMode = (dialogs, options) => {
|
|
2853
|
-
return dialogs.openCurrent({
|
|
2854
|
-
width: 'zen',
|
|
2855
|
-
shouldCloseOnEscapePress: false,
|
|
2856
|
-
minHeight: '100vh',
|
|
2857
|
-
shouldCloseOnOverlayClick: false,
|
|
2858
|
-
parameters: {
|
|
2859
|
-
type: MarkdownDialogType.zenMode,
|
|
2860
|
-
initialValue: options.initialValue,
|
|
2861
|
-
locale: options.locale
|
|
2862
|
-
}
|
|
2863
|
-
});
|
|
2864
|
-
};
|
|
2865
|
-
|
|
2866
|
-
function normalizeWhiteSpace(str) {
|
|
2867
|
-
if (str) {
|
|
2868
|
-
return str.trim().replace(/\s{2,}/g, ' ');
|
|
2869
|
-
} else {
|
|
2870
|
-
return str;
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
|
|
2874
|
-
function removeExtension(str) {
|
|
2875
|
-
return str.replace(/\.\w+$/g, '');
|
|
2876
|
-
}
|
|
2877
|
-
|
|
2878
|
-
function fileNameToTitle(str) {
|
|
2879
|
-
return normalizeWhiteSpace(removeExtension(str).replace(/_/g, ' '));
|
|
2880
|
-
}
|
|
2881
|
-
|
|
2882
|
-
function replaceAssetDomain(fileUrl) {
|
|
2883
|
-
const assetDomainMap = {
|
|
2884
|
-
images: 'images.ctfassets.net',
|
|
2885
|
-
assets: 'assets.ctfassets.net',
|
|
2886
|
-
downloads: 'downloads.ctfassets.net',
|
|
2887
|
-
videos: 'videos.ctfassets.net'
|
|
2888
|
-
};
|
|
2889
|
-
return fileUrl.replace(/(images|assets|downloads|videos).contentful.com/, (_, p1) => {
|
|
2890
|
-
return assetDomainMap[p1];
|
|
2891
|
-
});
|
|
2892
|
-
}
|
|
2893
|
-
|
|
2894
|
-
function makeAssetLink(asset, {
|
|
2895
|
-
localeCode,
|
|
2896
|
-
fallbackCode,
|
|
2897
|
-
defaultLocaleCode
|
|
2898
|
-
}) {
|
|
2899
|
-
const localizedFile = get(asset, ['fields', 'file', localeCode]);
|
|
2900
|
-
const fallbackFile = fallbackCode ? get(asset, ['fields', 'file', fallbackCode]) : null;
|
|
2901
|
-
const defaultFile = get(asset, ['fields', 'file', defaultLocaleCode]);
|
|
2902
|
-
const file = localizedFile || fallbackFile || defaultFile;
|
|
2903
|
-
|
|
2904
|
-
if (isObject(file) && file.url) {
|
|
2905
|
-
const title = get(asset, ['fields', 'title', localeCode]) || get(asset, ['fields', 'title', fallbackCode || '']) || get(asset, ['fields', 'title', defaultLocaleCode]) || fileNameToTitle(file.fileName);
|
|
2906
|
-
const fileUrl = replaceAssetDomain(file.url);
|
|
2907
|
-
return {
|
|
2908
|
-
title,
|
|
2909
|
-
asset,
|
|
2910
|
-
url: fileUrl,
|
|
2911
|
-
// is normally localized and we should not warn about this file
|
|
2912
|
-
isLocalized: Boolean(localizedFile),
|
|
2913
|
-
// was fallback value used
|
|
2914
|
-
// if it was not localized normally, and we did not used a fallback
|
|
2915
|
-
// it means we used a default locale - we filter empty values
|
|
2916
|
-
isFallback: Boolean(fallbackFile),
|
|
2917
|
-
// todo: tranform using fromHostname
|
|
2918
|
-
asMarkdown: ``
|
|
2919
|
-
};
|
|
2920
|
-
} else {
|
|
2921
|
-
return null;
|
|
2922
|
-
}
|
|
2923
|
-
}
|
|
2924
|
-
|
|
2925
|
-
async function insertAssetLinks(assets, locales) {
|
|
2926
|
-
// check whether do we have some assets, which don't have
|
|
2927
|
-
// a version in this field's locale
|
|
2928
|
-
const otherLocales = assets.filter(asset => {
|
|
2929
|
-
return !get(asset, ['fields', 'file', locales.localeCode]);
|
|
2930
|
-
});
|
|
2931
|
-
const linksWithMeta = assets.map(asset => makeAssetLink(asset, locales)) // remove empty links
|
|
2932
|
-
.filter(asset => asset !== null); // if there have values from fallback/default locales, we need to
|
|
2933
|
-
// provide user a warning so we show him modal
|
|
2934
|
-
|
|
2935
|
-
if (otherLocales.length > 0) {
|
|
2936
|
-
const fallbackAssets = linksWithMeta // we don't want to warn about normally localized files
|
|
2937
|
-
.filter(({
|
|
2938
|
-
isLocalized
|
|
2939
|
-
}) => !isLocalized).map(({
|
|
2940
|
-
title,
|
|
2941
|
-
isFallback,
|
|
2942
|
-
asset
|
|
2943
|
-
}) => {
|
|
2944
|
-
const code = isFallback ? locales.fallbackCode : locales.defaultLocaleCode;
|
|
2945
|
-
return {
|
|
2946
|
-
title,
|
|
2947
|
-
thumbnailUrl: asset.fields.file[code].url,
|
|
2948
|
-
thumbnailAltText: title,
|
|
2949
|
-
description: isFallback ? `Fallback locale (${code})` : `Default locale (${code})`,
|
|
2950
|
-
asset: asset
|
|
2951
|
-
};
|
|
2952
|
-
});
|
|
2953
|
-
return {
|
|
2954
|
-
fallbacks: fallbackAssets,
|
|
2955
|
-
links: linksWithMeta
|
|
2956
|
-
};
|
|
2957
|
-
}
|
|
2958
|
-
|
|
2959
|
-
return {
|
|
2960
|
-
links: linksWithMeta
|
|
2961
|
-
};
|
|
2962
|
-
}
|
|
2963
|
-
|
|
2964
|
-
/* eslint-disable @typescript-eslint/no-use-before-define, @typescript-eslint/no-explicit-any */
|
|
2965
|
-
|
|
2966
|
-
function extractTitle(title) {
|
|
2967
|
-
title = title || '';
|
|
2968
|
-
title = title.replace(/^ *('|"|\()*/, '');
|
|
2969
|
-
title = title.replace(/('|"|\))* *$/, '');
|
|
2970
|
-
return title;
|
|
2971
|
-
}
|
|
2972
|
-
|
|
2973
|
-
function head(text) {
|
|
2974
|
-
return text.split(' ').shift();
|
|
2975
|
-
}
|
|
2976
|
-
|
|
2977
|
-
function tail(text) {
|
|
2978
|
-
const segments = text.split(' ');
|
|
2979
|
-
segments.shift();
|
|
2980
|
-
return segments.join(' ');
|
|
2981
|
-
}
|
|
2982
|
-
|
|
2983
|
-
const PROCESSORS = {
|
|
2984
|
-
inline: function (match) {
|
|
2985
|
-
return {
|
|
2986
|
-
match: match[0],
|
|
2987
|
-
text: match[1],
|
|
2988
|
-
href: head(match[2]),
|
|
2989
|
-
title: extractTitle(tail(match[2]))
|
|
2990
|
-
};
|
|
2991
|
-
},
|
|
2992
|
-
ref: function (match) {
|
|
2993
|
-
return {
|
|
2994
|
-
match: match[0],
|
|
2995
|
-
text: match[1],
|
|
2996
|
-
id: match[2]
|
|
2997
|
-
};
|
|
2998
|
-
},
|
|
2999
|
-
label: function (match) {
|
|
3000
|
-
return {
|
|
3001
|
-
match: match[0],
|
|
3002
|
-
id: match[1],
|
|
3003
|
-
href: head(match[2]),
|
|
3004
|
-
title: extractTitle(tail(match[2]))
|
|
3005
|
-
};
|
|
3006
|
-
}
|
|
3007
|
-
};
|
|
3008
|
-
const REGEXS = {
|
|
3009
|
-
inline: /\[([^\r\n[\]]+)]\(([^\r\n)]+)\)/,
|
|
3010
|
-
ref: /\[([^\r\n[\]]+)] ?\[([^\r\n[\]]+)]/,
|
|
3011
|
-
label: /^ {0,3}\[([^\r\n[\]]+)]:\s+(.+)$/
|
|
3012
|
-
};
|
|
3013
|
-
const findInline = /*#__PURE__*/makeFinder('inline');
|
|
3014
|
-
const findRefs = /*#__PURE__*/makeFinder('ref');
|
|
3015
|
-
const findLabels = /*#__PURE__*/makeFinder('label');
|
|
3016
|
-
function convertInlineToRef(text) {
|
|
3017
|
-
let id = findMaxLabelId(text);
|
|
3018
|
-
forEach(findInline(text), inline => {
|
|
3019
|
-
id += 1;
|
|
3020
|
-
text = text.replace(inline.match, buildRef(inline, id));
|
|
3021
|
-
text += '\n' + buildLabel(inline, id);
|
|
3022
|
-
});
|
|
3023
|
-
return text;
|
|
3024
|
-
}
|
|
3025
|
-
|
|
3026
|
-
function mergeLabels(text) {
|
|
3027
|
-
const byHref = {};
|
|
3028
|
-
const byOldId = {};
|
|
3029
|
-
forEach(findLabels(text), label => {
|
|
3030
|
-
const alreadyAdded = byHref[label.href];
|
|
3031
|
-
const current = extend({}, label);
|
|
3032
|
-
|
|
3033
|
-
if (!alreadyAdded) {
|
|
3034
|
-
byHref[current.href] = current;
|
|
3035
|
-
} else if (hasTitle(current) && !hasTitle(alreadyAdded)) {
|
|
3036
|
-
alreadyAdded.title = current.title;
|
|
3037
|
-
}
|
|
3038
|
-
|
|
3039
|
-
byOldId[current.id] = alreadyAdded || current;
|
|
3040
|
-
});
|
|
3041
|
-
return {
|
|
3042
|
-
byHref: byHref,
|
|
3043
|
-
byOldId: byOldId
|
|
3044
|
-
};
|
|
3045
|
-
}
|
|
3046
|
-
|
|
3047
|
-
function rewriteRefs(text) {
|
|
3048
|
-
const merged = mergeLabels(text);
|
|
3049
|
-
const hrefToRefId = {};
|
|
3050
|
-
const labels = [];
|
|
3051
|
-
const rewrites = [];
|
|
3052
|
-
let i = 1; // 1. compose list of labels with new ids, in order
|
|
3053
|
-
|
|
3054
|
-
forEach(findRefs(text), ref => {
|
|
3055
|
-
const oldLabel = merged.byOldId[ref.id];
|
|
3056
|
-
|
|
3057
|
-
if (!oldLabel) {
|
|
3058
|
-
return;
|
|
3059
|
-
}
|
|
3060
|
-
|
|
3061
|
-
const href = oldLabel.href;
|
|
3062
|
-
let newRefId = hrefToRefId[href];
|
|
3063
|
-
|
|
3064
|
-
if (!newRefId) {
|
|
3065
|
-
hrefToRefId[href] = newRefId = i;
|
|
3066
|
-
i += 1;
|
|
3067
|
-
labels.push(extend({
|
|
3068
|
-
newId: newRefId
|
|
3069
|
-
}, oldLabel));
|
|
3070
|
-
} // 1b. prepare rewrites to be applied, with new label ids
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
rewrites.push(extend({
|
|
3074
|
-
newId: newRefId
|
|
3075
|
-
}, ref));
|
|
3076
|
-
}); // 2. remove all labels!
|
|
3077
|
-
|
|
3078
|
-
forEach(findLabels(text), label => {
|
|
3079
|
-
text = text.replace(label.match, '');
|
|
3080
|
-
}); // 3. remove whitespace from the end of text
|
|
3081
|
-
|
|
3082
|
-
text = text.replace(/[\r\n\s]*$/, '');
|
|
3083
|
-
text += '\n\n'; // 4. apply rewrites
|
|
3084
|
-
|
|
3085
|
-
forEach(rewrites, ref => {
|
|
3086
|
-
text = text.replace(ref.match, buildRef(ref, ref.newId));
|
|
3087
|
-
}); // 5. print new labels at the end of text
|
|
3088
|
-
|
|
3089
|
-
forEach(labels, label => {
|
|
3090
|
-
text += '\n' + buildLabel(label, label.newId);
|
|
3091
|
-
});
|
|
3092
|
-
return text;
|
|
3093
|
-
}
|
|
3094
|
-
/**
|
|
3095
|
-
* Finding stuff
|
|
3096
|
-
*/
|
|
3097
|
-
|
|
3098
|
-
function makeFinder(type) {
|
|
3099
|
-
return text => findAll(text, type).map(PROCESSORS[type]);
|
|
3100
|
-
}
|
|
3101
|
-
|
|
3102
|
-
function findMaxLabelId(textOrLabels) {
|
|
3103
|
-
if (isString(textOrLabels)) {
|
|
3104
|
-
textOrLabels = findLabels(textOrLabels);
|
|
3105
|
-
}
|
|
3106
|
-
|
|
3107
|
-
const ids = textOrLabels.map(x => x.id).map(x => parseInt(x, 10)).filter(x => isFinite(x) && x > 0);
|
|
3108
|
-
return ids.length > 0 ? max(ids) || 0 : 0;
|
|
3109
|
-
}
|
|
3110
|
-
|
|
3111
|
-
function findAll(text, type) {
|
|
3112
|
-
const flags = 'g' + (type === 'label' ? 'm' : '');
|
|
3113
|
-
const matches = [];
|
|
3114
|
-
const re = new RegExp(REGEXS[type].source, flags);
|
|
3115
|
-
let found = re.exec(text);
|
|
3116
|
-
|
|
3117
|
-
while (found) {
|
|
3118
|
-
matches.push(found);
|
|
3119
|
-
re.lastIndex = found.index + found[0].length;
|
|
3120
|
-
found = re.exec(text);
|
|
3121
|
-
}
|
|
3122
|
-
|
|
3123
|
-
return matches;
|
|
3124
|
-
}
|
|
3125
|
-
/**
|
|
3126
|
-
* Other utilities
|
|
3127
|
-
*/
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
function hasTitle(link) {
|
|
3131
|
-
return isObject(link) && isString(link.title) && link.title.length > 0;
|
|
3132
|
-
}
|
|
3133
|
-
|
|
3134
|
-
function buildLabel(link, id) {
|
|
3135
|
-
let markup = '[' + id + ']: ' + link.href;
|
|
3136
|
-
|
|
3137
|
-
if (hasTitle(link)) {
|
|
3138
|
-
markup += ' "' + link.title + '"';
|
|
3139
|
-
}
|
|
3140
|
-
|
|
3141
|
-
return markup;
|
|
3142
|
-
}
|
|
3143
|
-
|
|
3144
|
-
function buildRef(link, id) {
|
|
3145
|
-
return '[' + link.text + '][' + id + ']';
|
|
3146
|
-
}
|
|
3147
|
-
|
|
3148
|
-
function createMarkdownActions(props) {
|
|
3149
|
-
const {
|
|
3150
|
-
sdk,
|
|
3151
|
-
editor,
|
|
3152
|
-
locale
|
|
3153
|
-
} = props; // eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/ban-types
|
|
3154
|
-
|
|
3155
|
-
const insertAssetsWithConfirmation = async assets => {
|
|
3156
|
-
if (assets) {
|
|
3157
|
-
const {
|
|
3158
|
-
links,
|
|
3159
|
-
fallbacks
|
|
3160
|
-
} = await insertAssetLinks(assets, {
|
|
3161
|
-
localeCode: locale,
|
|
3162
|
-
defaultLocaleCode: sdk.locales.default,
|
|
3163
|
-
fallbackCode: sdk.locales.fallbacks[locale]
|
|
3164
|
-
});
|
|
3165
|
-
|
|
3166
|
-
if (links && links.length > 0) {
|
|
3167
|
-
if (fallbacks) {
|
|
3168
|
-
const insertAnyway = await openConfirmInsertAsset(sdk.dialogs, {
|
|
3169
|
-
locale: locale,
|
|
3170
|
-
assets: fallbacks
|
|
3171
|
-
});
|
|
3172
|
-
|
|
3173
|
-
if (!insertAnyway) {
|
|
3174
|
-
throw Error('User decided to not use fallbacks');
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
|
|
3178
|
-
return links.map(link => link.asMarkdown).join('\n\n');
|
|
3179
|
-
}
|
|
3180
|
-
}
|
|
3181
|
-
|
|
3182
|
-
return '';
|
|
3183
|
-
};
|
|
3184
|
-
|
|
3185
|
-
return {
|
|
3186
|
-
headings: {
|
|
3187
|
-
h1: () => {
|
|
3188
|
-
editor == null ? void 0 : editor.actions.h1();
|
|
3189
|
-
},
|
|
3190
|
-
h2: () => {
|
|
3191
|
-
editor == null ? void 0 : editor.actions.h2();
|
|
3192
|
-
},
|
|
3193
|
-
h3: () => {
|
|
3194
|
-
editor == null ? void 0 : editor.actions.h3();
|
|
3195
|
-
}
|
|
3196
|
-
},
|
|
3197
|
-
simple: {
|
|
3198
|
-
italic: () => {
|
|
3199
|
-
editor == null ? void 0 : editor.actions.italic();
|
|
3200
|
-
},
|
|
3201
|
-
bold: () => {
|
|
3202
|
-
editor == null ? void 0 : editor.actions.bold();
|
|
3203
|
-
},
|
|
3204
|
-
quote: () => {
|
|
3205
|
-
editor == null ? void 0 : editor.actions.quote();
|
|
3206
|
-
},
|
|
3207
|
-
ol: () => {
|
|
3208
|
-
editor == null ? void 0 : editor.actions.ol();
|
|
3209
|
-
},
|
|
3210
|
-
ul: () => {
|
|
3211
|
-
editor == null ? void 0 : editor.actions.ul();
|
|
3212
|
-
},
|
|
3213
|
-
strike: () => {
|
|
3214
|
-
editor == null ? void 0 : editor.actions.strike();
|
|
3215
|
-
},
|
|
3216
|
-
code: () => {
|
|
3217
|
-
editor == null ? void 0 : editor.actions.code();
|
|
3218
|
-
},
|
|
3219
|
-
hr: () => {
|
|
3220
|
-
editor == null ? void 0 : editor.actions.hr();
|
|
3221
|
-
},
|
|
3222
|
-
indent: () => {
|
|
3223
|
-
editor == null ? void 0 : editor.actions.indent();
|
|
3224
|
-
},
|
|
3225
|
-
dedent: () => {
|
|
3226
|
-
editor == null ? void 0 : editor.actions.dedent();
|
|
3227
|
-
}
|
|
3228
|
-
},
|
|
3229
|
-
history: {
|
|
3230
|
-
undo: () => {
|
|
3231
|
-
editor == null ? void 0 : editor.actions.undo();
|
|
3232
|
-
},
|
|
3233
|
-
redo: () => {
|
|
3234
|
-
editor == null ? void 0 : editor.actions.redo();
|
|
3235
|
-
}
|
|
3236
|
-
},
|
|
3237
|
-
insertLink: async () => {
|
|
3238
|
-
if (!editor) {
|
|
3239
|
-
return;
|
|
3240
|
-
}
|
|
3241
|
-
|
|
3242
|
-
editor.usePrimarySelection();
|
|
3243
|
-
const selectedText = editor.getSelectedText();
|
|
3244
|
-
const result = await openInsertLinkDialog(sdk.dialogs, {
|
|
3245
|
-
selectedText
|
|
3246
|
-
});
|
|
3247
|
-
|
|
3248
|
-
if (result) {
|
|
3249
|
-
editor.actions.link(result.url, selectedText || result.text, result.title);
|
|
3250
|
-
}
|
|
3251
|
-
},
|
|
3252
|
-
insertSpecialCharacter: async () => {
|
|
3253
|
-
if (!editor) {
|
|
3254
|
-
return;
|
|
3255
|
-
}
|
|
3256
|
-
|
|
3257
|
-
const result = await openInsertSpecialCharacter(sdk.dialogs);
|
|
3258
|
-
|
|
3259
|
-
if (result) {
|
|
3260
|
-
editor.insert(result);
|
|
3261
|
-
}
|
|
3262
|
-
},
|
|
3263
|
-
insertTable: async () => {
|
|
3264
|
-
if (!editor) {
|
|
3265
|
-
return;
|
|
3266
|
-
}
|
|
3267
|
-
|
|
3268
|
-
const result = await openInsertTableDialog(sdk.dialogs);
|
|
3269
|
-
|
|
3270
|
-
if (result) {
|
|
3271
|
-
editor.actions.table(result);
|
|
3272
|
-
}
|
|
3273
|
-
},
|
|
3274
|
-
organizeLinks: () => {
|
|
3275
|
-
if (!editor) {
|
|
3276
|
-
return;
|
|
3277
|
-
}
|
|
3278
|
-
|
|
3279
|
-
let text = editor.getContent();
|
|
3280
|
-
|
|
3281
|
-
if (!text) {
|
|
3282
|
-
return;
|
|
3283
|
-
}
|
|
3284
|
-
|
|
3285
|
-
text = convertInlineToRef(text);
|
|
3286
|
-
text = rewriteRefs(text);
|
|
3287
|
-
editor.setContent(text);
|
|
3288
|
-
sdk.notifier.success('All your links are now references at the bottom of your document.');
|
|
3289
|
-
},
|
|
3290
|
-
embedExternalContent: async () => {
|
|
3291
|
-
if (!editor) {
|
|
3292
|
-
return;
|
|
3293
|
-
}
|
|
3294
|
-
|
|
3295
|
-
const result = await openEmbedExternalContentDialog(sdk.dialogs);
|
|
3296
|
-
|
|
3297
|
-
if (result) {
|
|
3298
|
-
editor.insert(result);
|
|
3299
|
-
}
|
|
3300
|
-
},
|
|
3301
|
-
addNewMedia: async () => {
|
|
3302
|
-
if (!editor) {
|
|
3303
|
-
return;
|
|
3304
|
-
}
|
|
3305
|
-
|
|
3306
|
-
try {
|
|
3307
|
-
const {
|
|
3308
|
-
entity: asset
|
|
3309
|
-
} = await sdk.navigator.openNewAsset({
|
|
3310
|
-
slideIn: {
|
|
3311
|
-
waitForClose: true
|
|
3312
|
-
}
|
|
3313
|
-
}); // eslint-disable-line -- TODO: describe this disable @typescript-eslint/no-explicit-any
|
|
3314
|
-
|
|
3315
|
-
const markdownLinks = await insertAssetsWithConfirmation([asset]);
|
|
3316
|
-
editor.insert(markdownLinks);
|
|
3317
|
-
} finally {
|
|
3318
|
-
editor.focus();
|
|
3319
|
-
}
|
|
3320
|
-
},
|
|
3321
|
-
linkExistingMedia: async () => {
|
|
3322
|
-
if (!editor) {
|
|
3323
|
-
return;
|
|
3324
|
-
}
|
|
3325
|
-
|
|
3326
|
-
try {
|
|
3327
|
-
const assets = await sdk.dialogs.selectMultipleAssets({
|
|
3328
|
-
locale: locale
|
|
3329
|
-
});
|
|
3330
|
-
const markdownLinks = await insertAssetsWithConfirmation(assets);
|
|
3331
|
-
editor.insert(markdownLinks);
|
|
3332
|
-
} finally {
|
|
3333
|
-
editor.focus();
|
|
3334
|
-
}
|
|
3335
|
-
},
|
|
3336
|
-
openZenMode: async () => {
|
|
3337
|
-
if (!editor) {
|
|
3338
|
-
return;
|
|
3339
|
-
}
|
|
3340
|
-
|
|
3341
|
-
const result = await openZenMode(sdk.dialogs, {
|
|
3342
|
-
initialValue: editor.getContent(),
|
|
3343
|
-
locale: props.locale
|
|
3344
|
-
});
|
|
3345
|
-
editor.setContent(result.value);
|
|
3346
|
-
|
|
3347
|
-
if (result.cursor) {
|
|
3348
|
-
editor.setCursor(result.cursor);
|
|
3349
|
-
}
|
|
3350
|
-
|
|
3351
|
-
editor.focus();
|
|
3352
|
-
},
|
|
3353
|
-
closeZenMode: () => {// do nothing
|
|
3354
|
-
// this method is overwritten in dialog app
|
|
3355
|
-
}
|
|
3356
|
-
};
|
|
3357
|
-
}
|
|
3358
|
-
|
|
3359
|
-
const styles$a = {
|
|
3360
|
-
container: /*#__PURE__*/emotion.css({
|
|
3361
|
-
display: 'flex',
|
|
3362
|
-
flexDirection: 'column',
|
|
3363
|
-
fontFamily: tokens.fontStackPrimary
|
|
3364
|
-
})
|
|
3365
|
-
};
|
|
3366
|
-
function MarkdownEditor(props) {
|
|
3367
|
-
const [currentValue, setCurrentValue] = React__default.useState(props.initialValue ?? '');
|
|
3368
|
-
const [selectedTab, setSelectedTab] = React__default.useState('editor');
|
|
3369
|
-
const [editor, setEditor] = React__default.useState(null);
|
|
3370
|
-
const [canUploadAssets, setCanUploadAssets] = React__default.useState(false);
|
|
3371
|
-
React__default.useEffect(() => {
|
|
3372
|
-
if (editor && props.onReady) {
|
|
3373
|
-
props.onReady(editor); // fix: http://codemirror.977696.n3.nabble.com/codemirror-content-not-visible-in-bootstrap-modal-td4026988.html
|
|
3374
|
-
|
|
3375
|
-
setTimeout(() => {
|
|
3376
|
-
editor.refresh();
|
|
3377
|
-
}, 1);
|
|
3378
|
-
} // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
3379
|
-
|
|
3380
|
-
}, [editor]);
|
|
3381
|
-
React__default.useEffect(() => {
|
|
3382
|
-
props.sdk.access.can('create', 'Asset').then(value => {
|
|
3383
|
-
setCanUploadAssets(value);
|
|
3384
|
-
}); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
3385
|
-
}, []);
|
|
3386
|
-
React__default.useEffect(() => {
|
|
3387
|
-
if (editor) {
|
|
3388
|
-
editor.setReadOnly(props.disabled);
|
|
3389
|
-
}
|
|
3390
|
-
}, [editor, props.disabled]);
|
|
3391
|
-
const isActionDisabled = editor === null || props.disabled || selectedTab !== 'editor';
|
|
3392
|
-
const direction = props.sdk.locales.direction[props.sdk.field.locale] ?? 'ltr';
|
|
3393
|
-
const actions = React__default.useMemo(() => {
|
|
3394
|
-
return createMarkdownActions({
|
|
3395
|
-
sdk: props.sdk,
|
|
3396
|
-
editor,
|
|
3397
|
-
locale: props.sdk.field.locale
|
|
3398
|
-
}); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
3399
|
-
}, [editor]);
|
|
3400
|
-
const openMarkdownHelp = React__default.useCallback(() => {
|
|
3401
|
-
openCheatsheetModal(props.sdk.dialogs); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
3402
|
-
}, []);
|
|
3403
|
-
return React__default.createElement("div", {
|
|
3404
|
-
className: styles$a.container,
|
|
3405
|
-
"data-test-id": "markdown-editor"
|
|
3406
|
-
}, React__default.createElement(MarkdownTabs, {
|
|
3407
|
-
active: selectedTab,
|
|
3408
|
-
onSelect: tab => {
|
|
3409
|
-
setSelectedTab(tab);
|
|
3410
|
-
}
|
|
3411
|
-
}), React__default.createElement(MarkdownToolbar, {
|
|
3412
|
-
mode: "default",
|
|
3413
|
-
disabled: isActionDisabled,
|
|
3414
|
-
canUploadAssets: canUploadAssets,
|
|
3415
|
-
actions: actions
|
|
3416
|
-
}), React__default.createElement(MarkdownTextarea, {
|
|
3417
|
-
minHeight: props.minHeight,
|
|
3418
|
-
mode: "default",
|
|
3419
|
-
visible: selectedTab === 'editor',
|
|
3420
|
-
disabled: isActionDisabled,
|
|
3421
|
-
direction: direction,
|
|
3422
|
-
onReady: editor => {
|
|
3423
|
-
editor.setContent(props.initialValue ?? '');
|
|
3424
|
-
editor.setReadOnly(props.disabled);
|
|
3425
|
-
setEditor(editor);
|
|
3426
|
-
editor.events.onChange(value => {
|
|
3427
|
-
// Trim empty lines
|
|
3428
|
-
const trimmedValue = value.replace(/^\s+$/gm, '');
|
|
3429
|
-
props.saveValueToSDK(trimmedValue);
|
|
3430
|
-
setCurrentValue(value);
|
|
3431
|
-
});
|
|
3432
|
-
}
|
|
3433
|
-
}), selectedTab === 'preview' && React__default.createElement(MarkdownPreview, {
|
|
3434
|
-
direction: direction,
|
|
3435
|
-
minHeight: props.minHeight,
|
|
3436
|
-
mode: "default",
|
|
3437
|
-
value: currentValue,
|
|
3438
|
-
previewComponents: props.previewComponents
|
|
3439
|
-
}), React__default.createElement(MarkdownBottomBar, null, React__default.createElement(MarkdownHelp, {
|
|
3440
|
-
onClick: openMarkdownHelp
|
|
3441
|
-
})), React__default.createElement(MarkdownConstraints, {
|
|
3442
|
-
sdk: props.sdk,
|
|
3443
|
-
value: currentValue
|
|
3444
|
-
}));
|
|
3445
|
-
}
|
|
3446
|
-
function MarkdownEditorConnected(props) {
|
|
3447
|
-
return React__default.createElement(fieldEditorShared.FieldConnector, {
|
|
3448
|
-
throttle: 300,
|
|
3449
|
-
field: props.sdk.field,
|
|
3450
|
-
isInitiallyDisabled: props.isInitiallyDisabled
|
|
3451
|
-
}, ({
|
|
3452
|
-
value,
|
|
3453
|
-
disabled,
|
|
3454
|
-
setValue,
|
|
3455
|
-
externalReset
|
|
3456
|
-
}) => {
|
|
3457
|
-
// on external change reset component completely and init with initial value again
|
|
3458
|
-
return React__default.createElement(MarkdownEditor, { ...props,
|
|
3459
|
-
key: `markdown-editor-${externalReset}`,
|
|
3460
|
-
initialValue: value,
|
|
3461
|
-
disabled: disabled,
|
|
3462
|
-
saveValueToSDK: setValue
|
|
3463
|
-
});
|
|
3464
|
-
});
|
|
3465
|
-
}
|
|
3466
|
-
|
|
3467
|
-
const openMarkdownDialog = (sdk, previewComponents) => options => {
|
|
3468
|
-
var _options$parameters, _options$parameters2, _options$parameters3, _options$parameters4, _options$parameters5, _options$parameters6, _options$parameters7;
|
|
3469
|
-
|
|
3470
|
-
if (((_options$parameters = options.parameters) == null ? void 0 : _options$parameters.type) === MarkdownDialogType.cheatsheet) {
|
|
3471
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, () => {
|
|
3472
|
-
return React__default.createElement(CheatsheetModalDialog, null);
|
|
3473
|
-
});
|
|
3474
|
-
} else if (((_options$parameters2 = options.parameters) == null ? void 0 : _options$parameters2.type) === MarkdownDialogType.insertLink) {
|
|
3475
|
-
const selectedText = options.parameters.selectedText;
|
|
3476
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, ({
|
|
3477
|
-
onClose
|
|
3478
|
-
}) => {
|
|
3479
|
-
return React__default.createElement(InsertLinkModal, {
|
|
3480
|
-
selectedText: selectedText,
|
|
3481
|
-
onClose: onClose
|
|
3482
|
-
});
|
|
3483
|
-
});
|
|
3484
|
-
} else if (((_options$parameters3 = options.parameters) == null ? void 0 : _options$parameters3.type) === MarkdownDialogType.insertSpecialCharacter) {
|
|
3485
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, ({
|
|
3486
|
-
onClose
|
|
3487
|
-
}) => {
|
|
3488
|
-
return React__default.createElement(SpecialCharacterModalDialog, {
|
|
3489
|
-
onClose: onClose
|
|
3490
|
-
});
|
|
3491
|
-
});
|
|
3492
|
-
} else if (((_options$parameters4 = options.parameters) == null ? void 0 : _options$parameters4.type) === MarkdownDialogType.insertTable) {
|
|
3493
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, ({
|
|
3494
|
-
onClose
|
|
3495
|
-
}) => {
|
|
3496
|
-
return React__default.createElement(InsertTableModal, {
|
|
3497
|
-
onClose: onClose
|
|
3498
|
-
});
|
|
3499
|
-
});
|
|
3500
|
-
} else if (((_options$parameters5 = options.parameters) == null ? void 0 : _options$parameters5.type) === MarkdownDialogType.embedExternalContent) {
|
|
3501
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, ({
|
|
3502
|
-
onClose
|
|
3503
|
-
}) => {
|
|
3504
|
-
return React__default.createElement(EmbedExternalContentModal, {
|
|
3505
|
-
onClose: onClose
|
|
3506
|
-
});
|
|
3507
|
-
});
|
|
3508
|
-
} else if (((_options$parameters6 = options.parameters) == null ? void 0 : _options$parameters6.type) === MarkdownDialogType.confirmInsertAsset) {
|
|
3509
|
-
const locale = options.parameters.locale;
|
|
3510
|
-
const assets = options.parameters.assets;
|
|
3511
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, ({
|
|
3512
|
-
onClose
|
|
3513
|
-
}) => {
|
|
3514
|
-
return React__default.createElement(ConfirmInsertAssetModalDialog, {
|
|
3515
|
-
onClose: onClose,
|
|
3516
|
-
locale: locale,
|
|
3517
|
-
assets: assets
|
|
3518
|
-
});
|
|
3519
|
-
});
|
|
3520
|
-
} else if (((_options$parameters7 = options.parameters) == null ? void 0 : _options$parameters7.type) === MarkdownDialogType.zenMode) {
|
|
3521
|
-
const initialValue = options.parameters.initialValue;
|
|
3522
|
-
const locale = options.parameters.locale;
|
|
3523
|
-
return fieldEditorShared.ModalDialogLauncher.openDialog(options, ({
|
|
3524
|
-
onClose
|
|
3525
|
-
}) => {
|
|
3526
|
-
return React__default.createElement(ZenModeModalDialog, {
|
|
3527
|
-
saveValueToSDK: value => {
|
|
3528
|
-
var _sdk$field2;
|
|
3529
|
-
|
|
3530
|
-
if (value) {
|
|
3531
|
-
var _sdk$field;
|
|
3532
|
-
|
|
3533
|
-
return sdk == null ? void 0 : (_sdk$field = sdk.field) == null ? void 0 : _sdk$field.setValue(value);
|
|
3534
|
-
}
|
|
3535
|
-
|
|
3536
|
-
return sdk == null ? void 0 : (_sdk$field2 = sdk.field) == null ? void 0 : _sdk$field2.removeValue();
|
|
3537
|
-
},
|
|
3538
|
-
onClose: onClose,
|
|
3539
|
-
initialValue: initialValue,
|
|
3540
|
-
locale: locale,
|
|
3541
|
-
sdk: sdk,
|
|
3542
|
-
previewComponents: previewComponents
|
|
3543
|
-
});
|
|
3544
|
-
});
|
|
3545
|
-
}
|
|
3546
|
-
|
|
3547
|
-
return Promise.reject();
|
|
3548
|
-
};
|
|
3549
|
-
|
|
3550
|
-
const renderMarkdownDialog = sdk => {
|
|
3551
|
-
const parameters = sdk.parameters.invocation;
|
|
3552
|
-
|
|
3553
|
-
if (parameters.type === MarkdownDialogType.cheatsheet) {
|
|
3554
|
-
sdk.window.startAutoResizer();
|
|
3555
|
-
return React__default.createElement(CheatsheetModalDialog, null);
|
|
3556
|
-
} else if (parameters.type === MarkdownDialogType.insertLink) {
|
|
3557
|
-
const selectedText = parameters.selectedText;
|
|
3558
|
-
sdk.window.startAutoResizer();
|
|
3559
|
-
return React__default.createElement(InsertLinkModal, {
|
|
3560
|
-
selectedText: selectedText,
|
|
3561
|
-
onClose: sdk.close
|
|
3562
|
-
});
|
|
3563
|
-
} else if (parameters.type === MarkdownDialogType.insertSpecialCharacter) {
|
|
3564
|
-
sdk.window.startAutoResizer();
|
|
3565
|
-
return React__default.createElement(SpecialCharacterModalDialog, {
|
|
3566
|
-
onClose: sdk.close
|
|
3567
|
-
});
|
|
3568
|
-
} else if (parameters.type === MarkdownDialogType.insertTable) {
|
|
3569
|
-
sdk.window.startAutoResizer();
|
|
3570
|
-
return React__default.createElement(InsertTableModal, {
|
|
3571
|
-
onClose: sdk.close
|
|
3572
|
-
});
|
|
3573
|
-
} else if (parameters.type === MarkdownDialogType.embedExternalContent) {
|
|
3574
|
-
sdk.window.startAutoResizer();
|
|
3575
|
-
return React__default.createElement(EmbedExternalContentModal, {
|
|
3576
|
-
onClose: sdk.close
|
|
3577
|
-
});
|
|
3578
|
-
} else if (parameters.type === MarkdownDialogType.confirmInsertAsset) {
|
|
3579
|
-
const locale = parameters.locale;
|
|
3580
|
-
const assets = parameters.assets;
|
|
3581
|
-
sdk.window.startAutoResizer();
|
|
3582
|
-
return React__default.createElement(ConfirmInsertAssetModalDialog, {
|
|
3583
|
-
onClose: sdk.close,
|
|
3584
|
-
locale: locale,
|
|
3585
|
-
assets: assets
|
|
3586
|
-
});
|
|
3587
|
-
} else if (parameters.type === MarkdownDialogType.zenMode) {
|
|
3588
|
-
const locale = parameters.locale;
|
|
3589
|
-
const initialValue = parameters.initialValue; // eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/no-explicit-any
|
|
3590
|
-
|
|
3591
|
-
sdk.window.updateHeight('100%');
|
|
3592
|
-
return React__default.createElement(ZenModeModalDialog, {
|
|
3593
|
-
onClose: sdk.close,
|
|
3594
|
-
saveValueToSDK: () => {// don't save changes in dialog mode
|
|
3595
|
-
},
|
|
3596
|
-
initialValue: initialValue,
|
|
3597
|
-
locale: locale,
|
|
3598
|
-
sdk: sdk
|
|
3599
|
-
});
|
|
3600
|
-
}
|
|
3601
|
-
|
|
3602
|
-
return React__default.createElement("div", null);
|
|
3603
|
-
};
|
|
3604
|
-
|
|
3605
|
-
exports.MarkdownEditor = MarkdownEditorConnected;
|
|
3606
|
-
exports.MarkdownPreview = MarkdownPreview;
|
|
3607
|
-
exports.openMarkdownDialog = openMarkdownDialog;
|
|
3608
|
-
exports.renderMarkdownDialog = renderMarkdownDialog;
|
|
3609
|
-
//# sourceMappingURL=field-editor-markdown.cjs.development.js.map
|