@liveblocks/react-ui 3.3.3 → 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.
Files changed (61) hide show
  1. package/dist/_private/index.d.cts +3 -4
  2. package/dist/_private/index.d.ts +3 -4
  3. package/dist/components/AiChat.cjs +3 -2
  4. package/dist/components/AiChat.cjs.map +1 -1
  5. package/dist/components/AiChat.js +3 -2
  6. package/dist/components/AiChat.js.map +1 -1
  7. package/dist/components/AiTool.cjs +15 -6
  8. package/dist/components/AiTool.cjs.map +1 -1
  9. package/dist/components/AiTool.js +15 -6
  10. package/dist/components/AiTool.js.map +1 -1
  11. package/dist/components/Thread.cjs +1 -2
  12. package/dist/components/Thread.cjs.map +1 -1
  13. package/dist/components/Thread.js +2 -3
  14. package/dist/components/Thread.js.map +1 -1
  15. package/dist/components/internal/AiChatAssistantMessage.cjs +1 -0
  16. package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
  17. package/dist/components/internal/AiChatAssistantMessage.js +1 -0
  18. package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
  19. package/dist/components/internal/AiChatUserMessage.cjs +16 -14
  20. package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
  21. package/dist/components/internal/AiChatUserMessage.js +16 -14
  22. package/dist/components/internal/AiChatUserMessage.js.map +1 -1
  23. package/dist/components/internal/CodeBlock.cjs +1 -1
  24. package/dist/components/internal/CodeBlock.cjs.map +1 -1
  25. package/dist/components/internal/CodeBlock.js +1 -1
  26. package/dist/components/internal/CodeBlock.js.map +1 -1
  27. package/dist/components/internal/Prose.cjs +3 -1
  28. package/dist/components/internal/Prose.cjs.map +1 -1
  29. package/dist/components/internal/Prose.js +3 -1
  30. package/dist/components/internal/Prose.js.map +1 -1
  31. package/dist/index.d.cts +4 -3
  32. package/dist/index.d.ts +4 -3
  33. package/dist/primitives/AiMessage/tool-invocation.cjs +5 -2
  34. package/dist/primitives/AiMessage/tool-invocation.cjs.map +1 -1
  35. package/dist/primitives/AiMessage/tool-invocation.js +5 -2
  36. package/dist/primitives/AiMessage/tool-invocation.js.map +1 -1
  37. package/dist/primitives/Composer/slate/plugins/custom-links.cjs +2 -9
  38. package/dist/primitives/Composer/slate/plugins/custom-links.cjs.map +1 -1
  39. package/dist/primitives/Composer/slate/plugins/custom-links.js +1 -8
  40. package/dist/primitives/Composer/slate/plugins/custom-links.js.map +1 -1
  41. package/dist/primitives/Markdown.cjs +409 -61
  42. package/dist/primitives/Markdown.cjs.map +1 -1
  43. package/dist/primitives/Markdown.js +410 -62
  44. package/dist/primitives/Markdown.js.map +1 -1
  45. package/dist/version.cjs +1 -1
  46. package/dist/version.cjs.map +1 -1
  47. package/dist/version.js +1 -1
  48. package/dist/version.js.map +1 -1
  49. package/package.json +9 -9
  50. package/src/styles/dark/index.css +26 -0
  51. package/src/styles/index.css +174 -45
  52. package/styles/dark/attributes.css +1 -1
  53. package/styles/dark/attributes.css.map +1 -1
  54. package/styles/dark/media-query.css +1 -1
  55. package/styles/dark/media-query.css.map +1 -1
  56. package/styles.css +1 -1
  57. package/styles.css.map +1 -1
  58. package/dist/utils/find-last-index.cjs +0 -16
  59. package/dist/utils/find-last-index.cjs.map +0 -1
  60. package/dist/utils/find-last-index.js +0 -14
  61. 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.jsxs("li", {
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
- return new marked.Lexer().lex(content);
130
- }, [content]);
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.raw.length !== nextToken.raw.length) {
161
+ if (previousToken.type !== nextToken.type || previousProps.partial !== nextProps.partial) {
157
162
  return false;
158
163
  }
159
- if (previousToken.type !== nextToken.type) {
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 previousToken.raw === nextToken.raw;
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(/^\S*/)?.[0] ?? void 0;
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: item.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
- const normalizedTokens = [];
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 texts = [token];
397
+ const paragraphTextTokens = [token];
363
398
  while (i + 1 < tokens.length && tokens[i + 1].type === "text") {
364
399
  i++;
365
- texts.push(tokens[i]);
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: texts,
370
- raw: texts.map((text) => text.raw).join(""),
371
- text: texts.map((text) => text.text).join("")
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 tokens.map((token, index) => /* @__PURE__ */ jsxRuntime.jsx(MarkdownToken, {
423
+ return normalizedTokens.map((token, index) => /* @__PURE__ */ jsxRuntime.jsx(MarkdownToken, {
382
424
  token,
383
425
  components
384
426
  }, index));
385
427
  }
386
- const markedTokenTypes = [
387
- "blockquote",
388
- "br",
389
- "code",
390
- "codespan",
391
- "def",
392
- "del",
393
- "em",
394
- "escape",
395
- "heading",
396
- "hr",
397
- "html",
398
- "image",
399
- "link",
400
- "list",
401
- "list_item",
402
- "paragraph",
403
- "space",
404
- "strong",
405
- "table",
406
- "text"
407
- ];
408
- function isMarkedToken(token) {
409
- return typeof token === "object" && token !== null && "type" in token && markedTokenTypes.includes(token.type);
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, "&amp;").replace(LEFT_ANGLE_BRACKET_REGEX, "&lt;").replace(RIGHT_ANGLE_BRACKET_REGEX, "&gt;")}`,
414
762
  "text/html"
415
763
  );
416
764
  return document.body.textContent;