@liveblocks/react-ui 3.3.4 → 3.4.0-alpha1
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/_private/index.d.cts +3 -4
- package/dist/_private/index.d.ts +3 -4
- package/dist/components/AiChat.cjs +3 -2
- package/dist/components/AiChat.cjs.map +1 -1
- package/dist/components/AiChat.js +3 -2
- package/dist/components/AiChat.js.map +1 -1
- package/dist/components/AiTool.cjs +15 -6
- package/dist/components/AiTool.cjs.map +1 -1
- package/dist/components/AiTool.js +15 -6
- package/dist/components/AiTool.js.map +1 -1
- package/dist/components/Thread.cjs +1 -2
- package/dist/components/Thread.cjs.map +1 -1
- package/dist/components/Thread.js +2 -3
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.cjs +1 -0
- package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.js +1 -0
- package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
- package/dist/components/internal/AiChatUserMessage.cjs +16 -14
- package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatUserMessage.js +16 -14
- package/dist/components/internal/AiChatUserMessage.js.map +1 -1
- package/dist/components/internal/CodeBlock.cjs +1 -1
- package/dist/components/internal/CodeBlock.cjs.map +1 -1
- package/dist/components/internal/CodeBlock.js +1 -1
- package/dist/components/internal/CodeBlock.js.map +1 -1
- package/dist/components/internal/Prose.cjs +3 -1
- package/dist/components/internal/Prose.cjs.map +1 -1
- package/dist/components/internal/Prose.js +3 -1
- package/dist/components/internal/Prose.js.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/primitives/AiMessage/tool-invocation.cjs +5 -2
- package/dist/primitives/AiMessage/tool-invocation.cjs.map +1 -1
- package/dist/primitives/AiMessage/tool-invocation.js +5 -2
- package/dist/primitives/AiMessage/tool-invocation.js.map +1 -1
- package/dist/primitives/Composer/slate/plugins/custom-links.cjs +2 -9
- package/dist/primitives/Composer/slate/plugins/custom-links.cjs.map +1 -1
- package/dist/primitives/Composer/slate/plugins/custom-links.js +1 -8
- package/dist/primitives/Composer/slate/plugins/custom-links.js.map +1 -1
- package/dist/primitives/Markdown.cjs +409 -61
- package/dist/primitives/Markdown.cjs.map +1 -1
- package/dist/primitives/Markdown.js +410 -62
- package/dist/primitives/Markdown.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +4 -4
- package/src/styles/dark/index.css +26 -0
- package/src/styles/index.css +174 -45
- package/styles/dark/attributes.css +1 -1
- package/styles/dark/attributes.css.map +1 -1
- package/styles/dark/media-query.css +1 -1
- package/styles/dark/media-query.css.map +1 -1
- package/styles.css +1 -1
- package/styles.css.map +1 -1
- package/dist/utils/find-last-index.cjs +0 -16
- package/dist/utils/find-last-index.cjs.map +0 -1
- package/dist/utils/find-last-index.js +0 -14
- package/dist/utils/find-last-index.js.map +0 -1
|
@@ -6,6 +6,19 @@ var reactSlot = require('@radix-ui/react-slot');
|
|
|
6
6
|
var marked = require('marked');
|
|
7
7
|
var react = require('react');
|
|
8
8
|
|
|
9
|
+
const LIST_ITEM_CHECKBOX_REGEX = /^\[\s?(x)?\]?$/i;
|
|
10
|
+
const PARTIAL_LINK_IMAGE_REGEX = /(?<!\\)(?<image>!)?\[(?!\^)(?<text>[^\]]*)(?:\](?:\((?<url>[^)]*)?)?)?$/;
|
|
11
|
+
const PARTIAL_TABLE_HEADER_REGEX = /^\s*\|(?:[^|\n]+(?:\|[^|\n]+)*?)?\|?\s*(?:\n\s*\|\s*[-:|\s]*\s*)?$/;
|
|
12
|
+
const PARTIAL_EMOJI_REGEX = /(?:\u200D|\uFE0F|\u20E3|\p{Regional_Indicator}|\p{Emoji_Presentation}|\p{Emoji_Modifier_Base}|\p{Emoji_Modifier})+$/u;
|
|
13
|
+
const TRAILING_NON_WHITESPACE_REGEX = /^\S*/;
|
|
14
|
+
const WHITESPACE_REGEX = /\s/;
|
|
15
|
+
const NEWLINE_REGEX = /\r\n?/g;
|
|
16
|
+
const BUFFERED_CHARACTERS_REGEX = /(?<!\\)((\*+|_+|~+|`+|\++|-{0,2}|={0,2}|\\|!|<\/?)\s*)$/;
|
|
17
|
+
const SINGLE_CHARACTER_REGEX = /^\s*(\S\s*)$/;
|
|
18
|
+
const LEFT_ANGLE_BRACKET_REGEX = /</g;
|
|
19
|
+
const RIGHT_ANGLE_BRACKET_REGEX = />/g;
|
|
20
|
+
const AMPERSAND_REGEX = /&(?!#?[0-9A-Za-z]+;)/g;
|
|
21
|
+
const DEFAULT_PARTIAL_LINK_URL = "#";
|
|
9
22
|
const defaultComponents = {
|
|
10
23
|
Paragraph: ({ children }) => {
|
|
11
24
|
return /* @__PURE__ */ jsxRuntime.jsx("p", {
|
|
@@ -101,20 +114,8 @@ const defaultComponents = {
|
|
|
101
114
|
const List = type === "ordered" ? "ol" : "ul";
|
|
102
115
|
return /* @__PURE__ */ jsxRuntime.jsx(List, {
|
|
103
116
|
start: start === 1 ? void 0 : start,
|
|
104
|
-
children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.
|
|
105
|
-
children:
|
|
106
|
-
item.checked !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
107
|
-
children: [
|
|
108
|
-
/* @__PURE__ */ jsxRuntime.jsx("input", {
|
|
109
|
-
type: "checkbox",
|
|
110
|
-
disabled: true,
|
|
111
|
-
checked: item.checked
|
|
112
|
-
}),
|
|
113
|
-
" "
|
|
114
|
-
]
|
|
115
|
-
}),
|
|
116
|
-
item.children
|
|
117
|
-
]
|
|
117
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx("li", {
|
|
118
|
+
children: item.children
|
|
118
119
|
}, index))
|
|
119
120
|
});
|
|
120
121
|
},
|
|
@@ -123,18 +124,22 @@ const defaultComponents = {
|
|
|
123
124
|
}
|
|
124
125
|
};
|
|
125
126
|
const Markdown = react.forwardRef(
|
|
126
|
-
({ content, components, asChild, ...props }, forwardedRef) => {
|
|
127
|
+
({ content, partial, components, asChild, ...props }, forwardedRef) => {
|
|
127
128
|
const Component = asChild ? reactSlot.Slot : "div";
|
|
128
129
|
const tokens = react.useMemo(() => {
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
if (!content) {
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
return partial ? tokenizePartial(content) : tokenize(content);
|
|
134
|
+
}, [content, partial]);
|
|
131
135
|
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
132
136
|
...props,
|
|
133
137
|
ref: forwardedRef,
|
|
134
138
|
children: tokens.map((token, index) => {
|
|
135
139
|
return /* @__PURE__ */ jsxRuntime.jsx(MemoizedMarkdownToken, {
|
|
136
140
|
token,
|
|
137
|
-
components
|
|
141
|
+
components,
|
|
142
|
+
partial
|
|
138
143
|
}, index);
|
|
139
144
|
})
|
|
140
145
|
});
|
|
@@ -153,22 +158,25 @@ const MemoizedMarkdownToken = react.memo(
|
|
|
153
158
|
(previousProps, nextProps) => {
|
|
154
159
|
const previousToken = previousProps.token;
|
|
155
160
|
const nextToken = nextProps.token;
|
|
156
|
-
if (previousToken.
|
|
161
|
+
if (previousToken.type !== nextToken.type || previousProps.partial !== nextProps.partial) {
|
|
157
162
|
return false;
|
|
158
163
|
}
|
|
159
|
-
|
|
164
|
+
let previousContent = previousToken.raw;
|
|
165
|
+
let nextContent = nextToken.raw;
|
|
166
|
+
if ("text" in previousToken && "text" in nextToken) {
|
|
167
|
+
previousContent = previousToken.text;
|
|
168
|
+
nextContent = nextToken.text;
|
|
169
|
+
}
|
|
170
|
+
if (previousContent.length !== nextContent.length) {
|
|
160
171
|
return false;
|
|
161
172
|
}
|
|
162
|
-
return
|
|
173
|
+
return previousContent === nextContent;
|
|
163
174
|
}
|
|
164
175
|
);
|
|
165
176
|
function MarkdownToken({
|
|
166
177
|
token,
|
|
167
178
|
components
|
|
168
179
|
}) {
|
|
169
|
-
if (!isMarkedToken(token)) {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
180
|
switch (token.type) {
|
|
173
181
|
case "escape": {
|
|
174
182
|
return token.text;
|
|
@@ -266,12 +274,12 @@ function MarkdownToken({
|
|
|
266
274
|
case "code": {
|
|
267
275
|
let language = void 0;
|
|
268
276
|
if (token.lang !== void 0) {
|
|
269
|
-
language = token.lang.match(
|
|
277
|
+
language = token.lang.match(TRAILING_NON_WHITESPACE_REGEX)?.[0] ?? void 0;
|
|
270
278
|
}
|
|
271
279
|
const CodeBlock = components?.CodeBlock ?? defaultComponents.CodeBlock;
|
|
272
280
|
return /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, {
|
|
273
281
|
language,
|
|
274
|
-
code: token.text
|
|
282
|
+
code: token.text || " "
|
|
275
283
|
});
|
|
276
284
|
}
|
|
277
285
|
case "blockquote": {
|
|
@@ -287,12 +295,23 @@ function MarkdownToken({
|
|
|
287
295
|
case "list": {
|
|
288
296
|
const List = components?.List ?? defaultComponents.List;
|
|
289
297
|
const items = token.items.map((item) => {
|
|
298
|
+
let tokens = item.tokens;
|
|
299
|
+
if (item.task) {
|
|
300
|
+
tokens = [
|
|
301
|
+
{
|
|
302
|
+
type: "checkbox",
|
|
303
|
+
checked: Boolean(item.checked),
|
|
304
|
+
raw: `[${item.checked ? "x" : " "}]`
|
|
305
|
+
},
|
|
306
|
+
...tokens
|
|
307
|
+
];
|
|
308
|
+
}
|
|
290
309
|
return {
|
|
291
310
|
checked: item.task ? item.checked : void 0,
|
|
292
311
|
children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownTokens, {
|
|
293
|
-
tokens
|
|
312
|
+
tokens,
|
|
294
313
|
components,
|
|
295
|
-
normalizeToBlockTokens: item.loose
|
|
314
|
+
normalizeToBlockTokens: item.tokens.length > 0 ? item.loose : false
|
|
296
315
|
})
|
|
297
316
|
};
|
|
298
317
|
});
|
|
@@ -301,6 +320,18 @@ function MarkdownToken({
|
|
|
301
320
|
...props
|
|
302
321
|
});
|
|
303
322
|
}
|
|
323
|
+
case "checkbox": {
|
|
324
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
325
|
+
children: [
|
|
326
|
+
/* @__PURE__ */ jsxRuntime.jsx("input", {
|
|
327
|
+
type: "checkbox",
|
|
328
|
+
disabled: true,
|
|
329
|
+
checked: token.checked
|
|
330
|
+
}),
|
|
331
|
+
" "
|
|
332
|
+
]
|
|
333
|
+
});
|
|
334
|
+
}
|
|
304
335
|
case "table": {
|
|
305
336
|
const Table = components?.Table ?? defaultComponents.Table;
|
|
306
337
|
const headings = token.header.map(
|
|
@@ -342,7 +373,9 @@ function MarkdownToken({
|
|
|
342
373
|
const Separator = components?.Separator ?? defaultComponents.Separator;
|
|
343
374
|
return /* @__PURE__ */ jsxRuntime.jsx(Separator, {});
|
|
344
375
|
}
|
|
345
|
-
case "html":
|
|
376
|
+
case "html": {
|
|
377
|
+
return parseHtmlEntities(token.text);
|
|
378
|
+
}
|
|
346
379
|
default: {
|
|
347
380
|
return null;
|
|
348
381
|
}
|
|
@@ -353,64 +386,379 @@ function MarkdownTokens({
|
|
|
353
386
|
components,
|
|
354
387
|
normalizeToBlockTokens = false
|
|
355
388
|
}) {
|
|
356
|
-
|
|
389
|
+
assertTokens(tokens);
|
|
390
|
+
let normalizedTokens = [];
|
|
357
391
|
if (normalizeToBlockTokens) {
|
|
392
|
+
let leadingCheckboxToken = tokens[0]?.type === "checkbox" ? tokens[0] : null;
|
|
358
393
|
for (let i = 0; i < tokens.length; i++) {
|
|
359
394
|
const token = tokens[i];
|
|
360
395
|
switch (token.type) {
|
|
361
396
|
case "text": {
|
|
362
|
-
const
|
|
397
|
+
const paragraphTextTokens = [token];
|
|
363
398
|
while (i + 1 < tokens.length && tokens[i + 1].type === "text") {
|
|
364
399
|
i++;
|
|
365
|
-
|
|
400
|
+
paragraphTextTokens.push(tokens[i]);
|
|
366
401
|
}
|
|
402
|
+
const paragraphRaw = paragraphTextTokens.map((text) => text.raw).join("");
|
|
403
|
+
const paragraphText = paragraphTextTokens.map((text) => text.text).join("");
|
|
367
404
|
normalizedTokens.push({
|
|
368
405
|
type: "paragraph",
|
|
369
|
-
tokens:
|
|
370
|
-
raw:
|
|
371
|
-
text:
|
|
406
|
+
tokens: leadingCheckboxToken ? [leadingCheckboxToken, ...paragraphTextTokens] : paragraphTextTokens,
|
|
407
|
+
raw: paragraphRaw,
|
|
408
|
+
text: paragraphText
|
|
372
409
|
});
|
|
410
|
+
leadingCheckboxToken = null;
|
|
373
411
|
break;
|
|
374
412
|
}
|
|
413
|
+
case "checkbox":
|
|
414
|
+
break;
|
|
375
415
|
default: {
|
|
376
416
|
normalizedTokens.push(token);
|
|
377
417
|
}
|
|
378
418
|
}
|
|
379
419
|
}
|
|
420
|
+
} else {
|
|
421
|
+
normalizedTokens = tokens;
|
|
380
422
|
}
|
|
381
|
-
return
|
|
423
|
+
return normalizedTokens.map((token, index) => /* @__PURE__ */ jsxRuntime.jsx(MarkdownToken, {
|
|
382
424
|
token,
|
|
383
425
|
components
|
|
384
426
|
}, index));
|
|
385
427
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
"
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
428
|
+
function assertTokens(_) {
|
|
429
|
+
}
|
|
430
|
+
function isBlockToken(token) {
|
|
431
|
+
return token.type === "paragraph" || token.type === "heading" || token.type === "blockquote" || token.type === "list_item";
|
|
432
|
+
}
|
|
433
|
+
function tokenize(markdown) {
|
|
434
|
+
return new marked.Lexer().lex(markdown);
|
|
435
|
+
}
|
|
436
|
+
function tokenizePartial(markdown) {
|
|
437
|
+
const preprocessedContent = trimPartialMarkdown(normalizeNewlines(markdown));
|
|
438
|
+
const tokens = tokenize(preprocessedContent);
|
|
439
|
+
try {
|
|
440
|
+
return completePartialTokens(tokens);
|
|
441
|
+
} catch {
|
|
442
|
+
return tokens;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function findPotentiallyPartialToken(tokens, parentToken) {
|
|
446
|
+
if (tokens.length === 0) {
|
|
447
|
+
return parentToken;
|
|
448
|
+
}
|
|
449
|
+
assertTokens(tokens);
|
|
450
|
+
const lastIndex = tokens.length - 1;
|
|
451
|
+
let lastToken = tokens[lastIndex];
|
|
452
|
+
if (lastToken.type === "space") {
|
|
453
|
+
const penultimateToken = tokens[lastIndex - 1];
|
|
454
|
+
if (!penultimateToken) {
|
|
455
|
+
return parentToken;
|
|
456
|
+
}
|
|
457
|
+
lastToken = penultimateToken;
|
|
458
|
+
}
|
|
459
|
+
if (lastToken.type === "list") {
|
|
460
|
+
const listToken = lastToken;
|
|
461
|
+
const lastListItem = listToken.items[listToken.items.length - 1];
|
|
462
|
+
if (!lastListItem) {
|
|
463
|
+
return parentToken;
|
|
464
|
+
}
|
|
465
|
+
const lastListItemTokens = lastListItem.tokens;
|
|
466
|
+
if (lastListItemTokens.some((token) => token.type === "space") && lastListItemTokens.length > 0) {
|
|
467
|
+
const lastListItemLastToken = lastListItemTokens[lastListItemTokens.length - 1];
|
|
468
|
+
if (lastListItemLastToken) {
|
|
469
|
+
if (lastListItemLastToken.type === "text") {
|
|
470
|
+
return lastListItemLastToken;
|
|
471
|
+
}
|
|
472
|
+
if (isBlockToken(lastListItemLastToken)) {
|
|
473
|
+
return findPotentiallyPartialToken(
|
|
474
|
+
lastListItemLastToken.tokens,
|
|
475
|
+
lastListItemLastToken
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
return void 0;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return findPotentiallyPartialToken(lastListItem.tokens, lastListItem);
|
|
482
|
+
}
|
|
483
|
+
if (lastToken.type === "table") {
|
|
484
|
+
const tableToken = lastToken;
|
|
485
|
+
const lastTableRow = tableToken.rows[tableToken.rows.length - 1];
|
|
486
|
+
if (!lastTableRow) {
|
|
487
|
+
return parentToken;
|
|
488
|
+
}
|
|
489
|
+
const firstEmptyTableCellIndex = lastTableRow.findIndex(
|
|
490
|
+
(cell) => cell.tokens.length === 0
|
|
491
|
+
);
|
|
492
|
+
const lastNonEmptyTableCell = firstEmptyTableCellIndex === -1 ? void 0 : firstEmptyTableCellIndex === 0 ? lastTableRow[firstEmptyTableCellIndex] : lastTableRow[firstEmptyTableCellIndex - 1];
|
|
493
|
+
if (!lastNonEmptyTableCell) {
|
|
494
|
+
return parentToken;
|
|
495
|
+
}
|
|
496
|
+
return findPotentiallyPartialToken(
|
|
497
|
+
lastNonEmptyTableCell.tokens,
|
|
498
|
+
lastNonEmptyTableCell
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
if (isBlockToken(lastToken)) {
|
|
502
|
+
return findPotentiallyPartialToken(lastToken.tokens, lastToken);
|
|
503
|
+
}
|
|
504
|
+
return parentToken;
|
|
505
|
+
}
|
|
506
|
+
function normalizeNewlines(string) {
|
|
507
|
+
return string.replace(NEWLINE_REGEX, "\n");
|
|
508
|
+
}
|
|
509
|
+
function trimPartialMarkdown(markdown) {
|
|
510
|
+
const lines = markdown.split("\n");
|
|
511
|
+
if (lines.length === 0) {
|
|
512
|
+
return markdown;
|
|
513
|
+
}
|
|
514
|
+
const [singleCharacterMatch] = lines[lines.length - 1].match(SINGLE_CHARACTER_REGEX) ?? [];
|
|
515
|
+
if (singleCharacterMatch) {
|
|
516
|
+
lines[lines.length - 1] = lines[lines.length - 1].slice(
|
|
517
|
+
0,
|
|
518
|
+
-singleCharacterMatch.length
|
|
519
|
+
);
|
|
520
|
+
return lines.join("\n");
|
|
521
|
+
}
|
|
522
|
+
const [bufferedCharactersMatch] = lines[lines.length - 1].match(BUFFERED_CHARACTERS_REGEX) ?? [];
|
|
523
|
+
if (bufferedCharactersMatch) {
|
|
524
|
+
lines[lines.length - 1] = lines[lines.length - 1].slice(
|
|
525
|
+
0,
|
|
526
|
+
-bufferedCharactersMatch.length
|
|
527
|
+
);
|
|
528
|
+
return lines.join("\n");
|
|
529
|
+
}
|
|
530
|
+
return markdown;
|
|
531
|
+
}
|
|
532
|
+
function completePartialInlineMarkdown(markdown, options = {}) {
|
|
533
|
+
const stack = [];
|
|
534
|
+
const allowLinksImages = options.allowLinksImages ?? true;
|
|
535
|
+
let completedMarkdown = markdown;
|
|
536
|
+
const partialEmojiMatch = completedMarkdown.match(PARTIAL_EMOJI_REGEX);
|
|
537
|
+
if (partialEmojiMatch) {
|
|
538
|
+
const partialEmoji = partialEmojiMatch[0];
|
|
539
|
+
completedMarkdown = completedMarkdown.slice(0, -partialEmoji.length);
|
|
540
|
+
if (partialEmoji.includes("\uFE0F") || partialEmoji.includes("\u20E3")) {
|
|
541
|
+
const codepoints = Array.from(completedMarkdown);
|
|
542
|
+
if (codepoints.length > 0) {
|
|
543
|
+
completedMarkdown = codepoints.slice(0, -1).join("");
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
for (let i = 0; i < completedMarkdown.length; i++) {
|
|
548
|
+
const character = completedMarkdown[i];
|
|
549
|
+
const isEscaped = i > 0 ? completedMarkdown[i - 1] === "\\" : false;
|
|
550
|
+
if (isEscaped) {
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
if (character === "`") {
|
|
554
|
+
const lastDelimiter = stack[stack.length - 1];
|
|
555
|
+
const isClosingPreviousDelimiter = lastDelimiter?.string === "`" && i > lastDelimiter.index;
|
|
556
|
+
if (isClosingPreviousDelimiter) {
|
|
557
|
+
stack.pop();
|
|
558
|
+
} else {
|
|
559
|
+
const characterAfterDelimiter = completedMarkdown[i + 1];
|
|
560
|
+
if (characterAfterDelimiter && !WHITESPACE_REGEX.test(characterAfterDelimiter)) {
|
|
561
|
+
stack.push({ string: "`", length: 1, index: i });
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
if (character === "*" || character === "_" || character === "~") {
|
|
567
|
+
const isInsideInlineCode = stack[stack.length - 1]?.string === "`";
|
|
568
|
+
let j = i;
|
|
569
|
+
while (j < completedMarkdown.length && completedMarkdown[j] === character) {
|
|
570
|
+
j++;
|
|
571
|
+
}
|
|
572
|
+
const consecutiveDelimiterCharacters = j - i;
|
|
573
|
+
if (isInsideInlineCode) {
|
|
574
|
+
i += consecutiveDelimiterCharacters - 1;
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
let remainingConsecutiveDelimiterCharacters = consecutiveDelimiterCharacters;
|
|
578
|
+
let consecutiveDelimiterCharacterIndex = 0;
|
|
579
|
+
while (remainingConsecutiveDelimiterCharacters > 0) {
|
|
580
|
+
const lastDelimiter = stack[stack.length - 1];
|
|
581
|
+
if (!lastDelimiter || lastDelimiter.string[0] !== character) {
|
|
582
|
+
break;
|
|
583
|
+
}
|
|
584
|
+
if (remainingConsecutiveDelimiterCharacters >= lastDelimiter.length) {
|
|
585
|
+
stack.pop();
|
|
586
|
+
remainingConsecutiveDelimiterCharacters -= lastDelimiter.length;
|
|
587
|
+
consecutiveDelimiterCharacterIndex += lastDelimiter.length;
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
if (remainingConsecutiveDelimiterCharacters > 0) {
|
|
593
|
+
if (i + consecutiveDelimiterCharacters >= completedMarkdown.length) {
|
|
594
|
+
completedMarkdown = completedMarkdown.slice(
|
|
595
|
+
0,
|
|
596
|
+
completedMarkdown.length - remainingConsecutiveDelimiterCharacters
|
|
597
|
+
);
|
|
598
|
+
break;
|
|
599
|
+
}
|
|
600
|
+
const characterAfterDelimiters = completedMarkdown[i + consecutiveDelimiterCharacters];
|
|
601
|
+
if (characterAfterDelimiters && !WHITESPACE_REGEX.test(characterAfterDelimiters)) {
|
|
602
|
+
let delimiterStartIndex = i + consecutiveDelimiterCharacterIndex;
|
|
603
|
+
if (remainingConsecutiveDelimiterCharacters % 2 === 1) {
|
|
604
|
+
stack.push({
|
|
605
|
+
string: character,
|
|
606
|
+
length: 1,
|
|
607
|
+
index: delimiterStartIndex
|
|
608
|
+
});
|
|
609
|
+
delimiterStartIndex += 1;
|
|
610
|
+
remainingConsecutiveDelimiterCharacters -= 1;
|
|
611
|
+
}
|
|
612
|
+
while (remainingConsecutiveDelimiterCharacters >= 2) {
|
|
613
|
+
stack.push({
|
|
614
|
+
string: character + character,
|
|
615
|
+
length: 2,
|
|
616
|
+
index: delimiterStartIndex
|
|
617
|
+
});
|
|
618
|
+
delimiterStartIndex += 2;
|
|
619
|
+
remainingConsecutiveDelimiterCharacters -= 2;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
i += consecutiveDelimiterCharacters - 1;
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (allowLinksImages) {
|
|
628
|
+
const partialLinkImageMatch = completedMarkdown.match(
|
|
629
|
+
PARTIAL_LINK_IMAGE_REGEX
|
|
630
|
+
);
|
|
631
|
+
if (partialLinkImageMatch) {
|
|
632
|
+
const linkImageStartIndex = partialLinkImageMatch.index;
|
|
633
|
+
const linkImageEndIndex = linkImageStartIndex + partialLinkImageMatch[0].length;
|
|
634
|
+
const isInsideInlineCode = stack.some(
|
|
635
|
+
(delimiter) => delimiter.string === "`" && delimiter.index < linkImageStartIndex
|
|
636
|
+
);
|
|
637
|
+
if (!isInsideInlineCode) {
|
|
638
|
+
const partialLinkImageContent = partialLinkImageMatch[0];
|
|
639
|
+
const {
|
|
640
|
+
text: partialLinkText,
|
|
641
|
+
url: partialLinkUrl,
|
|
642
|
+
image: isImage
|
|
643
|
+
} = partialLinkImageMatch.groups;
|
|
644
|
+
if (isImage) {
|
|
645
|
+
completedMarkdown = completedMarkdown.slice(
|
|
646
|
+
0,
|
|
647
|
+
-partialLinkImageContent.length
|
|
648
|
+
);
|
|
649
|
+
} else {
|
|
650
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
651
|
+
const delimiter = stack[i];
|
|
652
|
+
if (delimiter.index >= linkImageStartIndex && delimiter.index < linkImageEndIndex) {
|
|
653
|
+
stack.splice(i, 1);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
const completedLinkText = partialLinkText ? partialLinkUrl ? partialLinkText : completePartialInlineMarkdown(partialLinkText, {
|
|
657
|
+
allowLinksImages: false
|
|
658
|
+
}) : "";
|
|
659
|
+
const completedLinkUrl = partialLinkUrl && !WHITESPACE_REGEX.test(partialLinkUrl) && core.isUrl(partialLinkUrl) ? partialLinkUrl : DEFAULT_PARTIAL_LINK_URL;
|
|
660
|
+
const completedLink = `[${completedLinkText}](${completedLinkUrl})`;
|
|
661
|
+
completedMarkdown = completedMarkdown.slice(
|
|
662
|
+
0,
|
|
663
|
+
-partialLinkImageContent.length
|
|
664
|
+
);
|
|
665
|
+
completedMarkdown += completedLink;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
671
|
+
const delimiter = stack[i];
|
|
672
|
+
if (delimiter.index + delimiter.length >= completedMarkdown.length) {
|
|
673
|
+
completedMarkdown = completedMarkdown.slice(0, delimiter.index);
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
if (delimiter.string !== "`") {
|
|
677
|
+
completedMarkdown = completedMarkdown.trimEnd();
|
|
678
|
+
}
|
|
679
|
+
completedMarkdown += delimiter.string;
|
|
680
|
+
}
|
|
681
|
+
return completedMarkdown;
|
|
682
|
+
}
|
|
683
|
+
function completePartialTableMarkdown(markdown) {
|
|
684
|
+
const tableLines = markdown.split("\n");
|
|
685
|
+
if (tableLines.length === 0) {
|
|
686
|
+
return void 0;
|
|
687
|
+
}
|
|
688
|
+
const tableHeader = tableLines[0];
|
|
689
|
+
if (tableHeader === "|") {
|
|
690
|
+
return void 0;
|
|
691
|
+
}
|
|
692
|
+
const tableHeadings = tableHeader.split("|").map((cell) => cell.trim()).filter((cell) => cell !== "");
|
|
693
|
+
if (tableHeadings.length === 0) {
|
|
694
|
+
return void 0;
|
|
695
|
+
}
|
|
696
|
+
if (!tableHeader.endsWith("|")) {
|
|
697
|
+
const lastTableHeading = tableHeadings[tableHeadings.length - 1];
|
|
698
|
+
const completedLastTableHeading = completePartialInlineMarkdown(lastTableHeading);
|
|
699
|
+
tableHeadings[tableHeadings.length - 1] = completedLastTableHeading;
|
|
700
|
+
}
|
|
701
|
+
return `| ${tableHeadings.join(" | ")} |
|
|
702
|
+
| ${tableHeadings.map(() => "---").join(" | ")} |`;
|
|
703
|
+
}
|
|
704
|
+
function completePartialTokens(tokens) {
|
|
705
|
+
const potentiallyPartialToken = findPotentiallyPartialToken(tokens);
|
|
706
|
+
if (!potentiallyPartialToken) {
|
|
707
|
+
return tokens;
|
|
708
|
+
}
|
|
709
|
+
if (potentiallyPartialToken.type === "paragraph" || potentiallyPartialToken.type === "text") {
|
|
710
|
+
if (PARTIAL_TABLE_HEADER_REGEX.test(potentiallyPartialToken.raw)) {
|
|
711
|
+
const completedTableMarkdown = completePartialTableMarkdown(
|
|
712
|
+
potentiallyPartialToken.raw
|
|
713
|
+
);
|
|
714
|
+
if (completedTableMarkdown) {
|
|
715
|
+
const completedTable = tokenize(completedTableMarkdown)[0];
|
|
716
|
+
if (completedTable) {
|
|
717
|
+
const table = potentiallyPartialToken;
|
|
718
|
+
table.type = "table";
|
|
719
|
+
table.header = completedTable.header;
|
|
720
|
+
table.align = completedTable.align;
|
|
721
|
+
table.rows = completedTable.rows;
|
|
722
|
+
return tokens;
|
|
723
|
+
}
|
|
724
|
+
} else {
|
|
725
|
+
potentiallyPartialToken.text = "";
|
|
726
|
+
potentiallyPartialToken.tokens = [];
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (potentiallyPartialToken.type === "list_item") {
|
|
731
|
+
const listItem = potentiallyPartialToken;
|
|
732
|
+
const listItemTokens = listItem.tokens;
|
|
733
|
+
if (!listItem.task && listItemTokens.length === 1 && listItemTokens[0].type === "text") {
|
|
734
|
+
const listItemText = listItemTokens[0];
|
|
735
|
+
const checkboxMatch = listItemText.text.match(LIST_ITEM_CHECKBOX_REGEX);
|
|
736
|
+
if (checkboxMatch) {
|
|
737
|
+
listItem.task = true;
|
|
738
|
+
if (checkboxMatch[1] === "x") {
|
|
739
|
+
listItem.checked = true;
|
|
740
|
+
} else {
|
|
741
|
+
listItem.checked = false;
|
|
742
|
+
}
|
|
743
|
+
listItem.text = "";
|
|
744
|
+
listItem.tokens = [];
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
if (potentiallyPartialToken.text.length === 0) {
|
|
749
|
+
return tokens;
|
|
750
|
+
}
|
|
751
|
+
const completedMarkdown = completePartialInlineMarkdown(
|
|
752
|
+
potentiallyPartialToken.text
|
|
753
|
+
);
|
|
754
|
+
const completedMarkdownTokens = tokenize(completedMarkdown)[0]?.tokens ?? [];
|
|
755
|
+
potentiallyPartialToken.text = completedMarkdown;
|
|
756
|
+
potentiallyPartialToken.tokens = completedMarkdownTokens;
|
|
757
|
+
return tokens;
|
|
410
758
|
}
|
|
411
759
|
function parseHtmlEntities(input) {
|
|
412
760
|
const document = new DOMParser().parseFromString(
|
|
413
|
-
`<!doctype html><body>${input}`,
|
|
761
|
+
`<!doctype html><body>${input.replace(AMPERSAND_REGEX, "&").replace(LEFT_ANGLE_BRACKET_REGEX, "<").replace(RIGHT_ANGLE_BRACKET_REGEX, ">")}`,
|
|
414
762
|
"text/html"
|
|
415
763
|
);
|
|
416
764
|
return document.body.textContent;
|