lexxy 0.9.19.alpha.3 → 0.9.19

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf2150a951764595691835dfe6bb97aa8a0bf4be41600e611f94156646aaba51
4
- data.tar.gz: f24a3dc76fec3b0d924b3f9cd2839c1faa747ff9a051e5c57075530c6ca0abbd
3
+ metadata.gz: b6868388203b7cfd6a7026208872b75268aafab61e5e29abc57ed35825dfdb8d
4
+ data.tar.gz: cdbb2c3702b5d204c2820a8a0fdf5c2c851c4d8272b1aa32e9dd8680adae409d
5
5
  SHA512:
6
- metadata.gz: 9e1e04f1e9bd1f32513f1c64efbd69ca49519307906851d6c11958232a3a0307a0dd31f512007df583bee752c52e97dac2fa87be8bc13dcd2d1d7ef57aa0dc06
7
- data.tar.gz: 231f6d4ad4a687800ac5ed43941af7cdea2386549cbc26c3df538db628a6847406013065f0c452c0bc2acfa093afa759a7007cce0639ecbdd9953ecd727da77f
6
+ metadata.gz: 6a0ced04355235c795d5329b620f75e39ead9abfb64e4111939c2ce40c0a099b6d8aeed6222105d9e17aa909be1cc1e7a83037b2b9ff2fc8c49849f61f21a346
7
+ data.tar.gz: 26d5669519354092c672bc86bfe37f0939c16bc24336f3242e87ef4d9a5e7416bd856b275238c1bca32b5dd20a98f2c20784aee6c064a86033cc6edb34ced695
@@ -7650,7 +7650,8 @@ class CustomActionTextAttachmentNode extends Ji {
7650
7650
  }
7651
7651
 
7652
7652
  createDOM() {
7653
- const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true });
7653
+ const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true, draggable: true });
7654
+ figure.dataset.lexicalNodeKey = this.__key;
7654
7655
 
7655
7656
  figure.insertAdjacentHTML("beforeend", sanitize(this.innerHtml));
7656
7657
 
@@ -7703,6 +7704,10 @@ class CustomActionTextAttachmentNode extends Ji {
7703
7704
  }
7704
7705
  }
7705
7706
 
7707
+ function $isCustomActionTextAttachmentNode(node) {
7708
+ return node instanceof CustomActionTextAttachmentNode
7709
+ }
7710
+
7706
7711
  function dasherize(value) {
7707
7712
  return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`)
7708
7713
  }
@@ -10254,7 +10259,7 @@ class CommandDispatcher {
10254
10259
  }
10255
10260
 
10256
10261
  #isInternalDrag(event) {
10257
- return event.dataTransfer?.types.includes("application/x-lexxy-node-key")
10262
+ return event.dataTransfer?.types.some((type) => type.startsWith("application/x-lexxy-"))
10258
10263
  }
10259
10264
 
10260
10265
  #handleTabKey(event) {
@@ -10308,14 +10313,14 @@ class Selection {
10308
10313
  }
10309
10314
 
10310
10315
  get cursorPosition() {
10311
- let position = { x: 0, y: 0 };
10316
+ let position = null;
10312
10317
 
10313
10318
  this.editor.getEditorState().read(() => {
10314
10319
  const range = this.#getValidSelectionRange();
10315
10320
  if (!range) return
10316
10321
 
10317
10322
  const rect = this.#getReliableRectFromRange(range);
10318
- if (!rect) return
10323
+ if (this.#isRectUnreliable(rect)) return
10319
10324
 
10320
10325
  position = this.#calculateCursorPosition(rect, range);
10321
10326
  });
@@ -11885,7 +11890,7 @@ class ShadowRootNodeInserter extends BaseNodeInserter {
11885
11890
 
11886
11891
  class NodeSelectionNodeInserter extends BaseNodeInserter {
11887
11892
  static handles(selection) {
11888
- return Ir(selection)
11893
+ return Ir(selection) && selection.getNodes().length > 0
11889
11894
  }
11890
11895
 
11891
11896
  insertNodes(nodes) {
@@ -12083,8 +12088,15 @@ class Contents {
12083
12088
  }, { tag });
12084
12089
  }
12085
12090
 
12091
+ insertText(text, { tag } = {}) {
12092
+ this.editor.update(() => {
12093
+ const paragraph = eo().append(kr(text));
12094
+ this.insertAtCursor(paragraph);
12095
+ }, { tag });
12096
+ }
12097
+
12086
12098
  insertAtCursor(...nodes) {
12087
- const selection = Qr() ?? Zo().selectEnd();
12099
+ const selection = this.#insertableSelection();
12088
12100
  const inserter = BaseNodeInserter.for(selection);
12089
12101
 
12090
12102
  inserter.insertNodes(nodes);
@@ -12278,14 +12290,13 @@ class Contents {
12278
12290
  replaceTextBackUntil(stringToReplace, replacementNodes) {
12279
12291
  replacementNodes = Array.isArray(replacementNodes) ? replacementNodes : [ replacementNodes ];
12280
12292
 
12281
- const selection = Qr();
12282
12293
  const { anchorNode, offset } = this.#getTextAnchorData();
12283
12294
  if (!anchorNode) return
12284
12295
 
12285
12296
  const lastIndex = this.#findReplacementStart(anchorNode, offset, stringToReplace);
12286
12297
  if (lastIndex === -1) return
12287
12298
 
12288
- this.#performTextReplacement(anchorNode, selection, lastIndex, stringToReplace, replacementNodes);
12299
+ this.#performTextReplacement(anchorNode, lastIndex, stringToReplace, replacementNodes);
12289
12300
  }
12290
12301
 
12291
12302
  uploadFiles(files, { selectLast } = {}) {
@@ -12425,6 +12436,15 @@ class Contents {
12425
12436
  });
12426
12437
  }
12427
12438
 
12439
+ #insertableSelection() {
12440
+ const selection = Qr();
12441
+ if (Ir(selection) && selection.getNodes().length === 0) {
12442
+ return Zo().selectEnd()
12443
+ }
12444
+
12445
+ return selection ?? Zo().selectEnd()
12446
+ }
12447
+
12428
12448
  #formatPastedDOM(doc) {
12429
12449
  new PastedContentFormatter(doc).format();
12430
12450
  }
@@ -12608,13 +12628,13 @@ class Contents {
12608
12628
  }
12609
12629
  }
12610
12630
 
12611
- #performTextReplacement(anchorNode, selection, startIndex, stringToReplace, replacementNodes) {
12631
+ #performTextReplacement(anchorNode, startIndex, stringToReplace, replacementNodes) {
12612
12632
  const fullText = anchorNode.getTextContent();
12613
12633
  const textBeforeString = fullText.slice(0, startIndex);
12614
12634
  const textAfterString = fullText.slice(startIndex + stringToReplace.length);
12615
12635
 
12616
- const textNodeBefore = this.#cloneTextNodeFormatting(anchorNode, selection, textBeforeString);
12617
- const textNodeAfter = this.#cloneTextNodeFormatting(anchorNode, selection, textAfterString || " ");
12636
+ const textNodeBefore = this.#cloneTextNodeFormatting(anchorNode, textBeforeString);
12637
+ const textNodeAfter = this.#cloneTextNodeFormatting(anchorNode, textAfterString || " ");
12618
12638
 
12619
12639
  anchorNode.replace(textNodeBefore);
12620
12640
 
@@ -12626,18 +12646,12 @@ class Contents {
12626
12646
  textNodeAfter.select(cursorOffset, cursorOffset);
12627
12647
  }
12628
12648
 
12629
- #cloneTextNodeFormatting(anchorNode, selection, text) {
12630
- const parent = anchorNode.getParent();
12631
- const fallbackFormat = parent?.getTextFormat?.() || 0;
12632
- const fallbackStyle = parent?.getTextStyle?.() || "";
12633
- const format = Fr(selection) && selection.format ? selection.format : (anchorNode.getFormat() || fallbackFormat);
12634
- const style = Fr(selection) && selection.style ? selection.style : (anchorNode.getStyle() || fallbackStyle);
12635
-
12649
+ #cloneTextNodeFormatting(anchorNode, text) {
12636
12650
  return kr(text)
12637
- .setFormat(format)
12651
+ .setFormat(anchorNode.getFormat())
12638
12652
  .setDetail(anchorNode.getDetail())
12639
12653
  .setMode(anchorNode.getMode())
12640
- .setStyle(style)
12654
+ .setStyle(anchorNode.getStyle())
12641
12655
  }
12642
12656
 
12643
12657
  #insertReplacementNodes(startNode, replacementNodes) {
@@ -12927,14 +12941,31 @@ class Clipboard {
12927
12941
  #pasteMarkdown(text) {
12928
12942
  const html = k(text, { breaks: true });
12929
12943
  const doc = parseHtml(html);
12930
- const detail = Object.freeze({
12931
- markdown: text,
12932
- document: doc,
12933
- addBlockSpacing: () => addBlockSpacing(doc)
12934
- });
12935
12944
 
12936
- dispatch(this.editorElement, "lexxy:insert-markdown", detail);
12937
- this.contents.insertDOM(doc, { tag: jn });
12945
+ if (this.#isPlainTextWithoutMarkdown(doc)) {
12946
+ this.contents.insertText(text, { tag: jn });
12947
+ } else {
12948
+ const detail = Object.freeze({
12949
+ markdown: text,
12950
+ document: doc,
12951
+ addBlockSpacing: () => addBlockSpacing(doc)
12952
+ });
12953
+
12954
+ dispatch(this.editorElement, "lexxy:insert-markdown", detail);
12955
+ this.contents.insertDOM(doc, { tag: jn });
12956
+ }
12957
+ }
12958
+
12959
+ // Markdown conversion collapses runs of whitespace and unescapes backslashes,
12960
+ // silently corrupting plain text such as Windows/UNC file paths. When the text
12961
+ // carries no Markdown structure, paste it verbatim instead.
12962
+ #isPlainTextWithoutMarkdown(doc) {
12963
+ const elements = Array.from(doc.body.children);
12964
+ if (elements.length !== 1) return false
12965
+
12966
+ const paragraph = elements[0];
12967
+ return paragraph.nodeName === "P"
12968
+ && Array.from(paragraph.childNodes).every((node) => node.nodeType === Node.TEXT_NODE)
12938
12969
  }
12939
12970
 
12940
12971
  #pasteRichText(clipboardData) {
@@ -13542,7 +13573,7 @@ class TablesExtension extends LexxyExtension {
13542
13573
  }
13543
13574
  }
13544
13575
 
13545
- const MIME_TYPE = "application/x-lexxy-node-key";
13576
+ const MIME_TYPE$1 = "application/x-lexxy-node-key";
13546
13577
 
13547
13578
  class AttachmentDragAndDrop {
13548
13579
  #editor
@@ -13589,7 +13620,7 @@ class AttachmentDragAndDrop {
13589
13620
  if (!figure) return false
13590
13621
 
13591
13622
  this.#draggedNodeKey = figure.dataset.lexicalNodeKey;
13592
- event.dataTransfer.setData(MIME_TYPE, this.#draggedNodeKey);
13623
+ event.dataTransfer.setData(MIME_TYPE$1, this.#draggedNodeKey);
13593
13624
  event.dataTransfer.effectAllowed = "move";
13594
13625
 
13595
13626
  // Add dragging class after a tick so it doesn't affect the drag image
@@ -14369,6 +14400,268 @@ class PreventLexicalTripleClickExtension extends LexxyExtension {
14369
14400
  }
14370
14401
  }
14371
14402
 
14403
+ function caretRect(node, offset) {
14404
+ const range = document.createRange();
14405
+ range.setStart(node, offset);
14406
+ range.collapse(true);
14407
+
14408
+ const rect = range.getBoundingClientRect();
14409
+ if (rect.height > 0) {
14410
+ return rect
14411
+ } else {
14412
+ return null
14413
+ }
14414
+ }
14415
+
14416
+ function caretFromPoint(clientX, clientY) {
14417
+ if (document.caretPositionFromPoint) {
14418
+ const position = document.caretPositionFromPoint(clientX, clientY);
14419
+ if (position) return { node: position.offsetNode, offset: position.offset }
14420
+ } else if (document.caretRangeFromPoint) {
14421
+ const range = document.caretRangeFromPoint(clientX, clientY);
14422
+ if (range) return { node: range.startContainer, offset: range.startOffset }
14423
+ }
14424
+
14425
+ return null
14426
+ }
14427
+
14428
+ const MIME_TYPE = "application/x-lexxy-custom-attachment-key";
14429
+
14430
+ // Custom inline attachments reorder by dropping at a text caret, unlike block
14431
+ // attachments which insert between blocks or into galleries.
14432
+ class CustomAttachmentDragAndDrop {
14433
+ #editor
14434
+ #draggedNodeKey = null
14435
+ #draggingRafId = null
14436
+ #dragOverRafId = null
14437
+ #dropIndicator = null
14438
+ #listeners = new ListenerBin()
14439
+
14440
+ constructor(editor) {
14441
+ this.#editor = editor;
14442
+
14443
+ // Register at HIGH priority to intercept before the base @lexical/rich-text
14444
+ // handlers, which consume drag events. The block-attachment handler also
14445
+ // registers here but bails for inline custom attachments, so we get our turn.
14446
+ this.#listeners.track(
14447
+ editor.registerCommand(Be$2, (event) => this.#handleDragStart(event), so),
14448
+ editor.registerCommand(ze$2, (event) => this.#handleDrop(event), so)
14449
+ );
14450
+
14451
+ this.#listeners.track(editor.registerRootListener((root, prevRoot) => {
14452
+ if (prevRoot) {
14453
+ prevRoot.removeEventListener("dragover", this.#onDragOver);
14454
+ prevRoot.removeEventListener("dragend", this.#onDragEnd);
14455
+ }
14456
+ if (root) {
14457
+ root.addEventListener("dragover", this.#onDragOver);
14458
+ root.addEventListener("dragend", this.#onDragEnd);
14459
+ }
14460
+ }));
14461
+ }
14462
+
14463
+ destroy() {
14464
+ this.#cleanup();
14465
+ this.#dropIndicator?.remove();
14466
+ this.#dropIndicator = null;
14467
+ this.#listeners.dispose();
14468
+ }
14469
+
14470
+ #handleDragStart(event) {
14471
+ const attachment = this.#customAttachmentElementFrom(event.target);
14472
+ if (!attachment) return false
14473
+
14474
+ this.#draggedNodeKey = attachment.dataset.lexicalNodeKey;
14475
+ event.dataTransfer.setData(MIME_TYPE, this.#draggedNodeKey);
14476
+ event.dataTransfer.effectAllowed = "move";
14477
+
14478
+ this.#draggingRafId = requestAnimationFrame(() => {
14479
+ this.#draggingRafId = null;
14480
+ attachment.classList.add("lexxy-dragging");
14481
+ });
14482
+
14483
+ return true
14484
+ }
14485
+
14486
+ #onDragOver = (event) => {
14487
+ if (!this.#draggedNodeKey) return
14488
+
14489
+ event.preventDefault();
14490
+ event.dataTransfer.dropEffect = "move";
14491
+
14492
+ if (!this.#dragOverRafId) {
14493
+ this.#dragOverRafId = requestAnimationFrame(() => {
14494
+ this.#dragOverRafId = null;
14495
+ this.#updateDropIndicator(event);
14496
+ });
14497
+ }
14498
+ }
14499
+
14500
+ #onDragEnd = () => {
14501
+ this.#cleanup();
14502
+ }
14503
+
14504
+ #handleDrop(event) {
14505
+ if (!this.#draggedNodeKey) return false
14506
+
14507
+ event.preventDefault();
14508
+
14509
+ const dropPoint = this.#resolveDropPoint(event);
14510
+ const draggedKey = this.#draggedNodeKey;
14511
+ this.#cleanup();
14512
+
14513
+ if (dropPoint) {
14514
+ this.#moveAttachment(draggedKey, dropPoint);
14515
+ }
14516
+
14517
+ return true
14518
+ }
14519
+
14520
+ #resolveDropPoint(event) {
14521
+ const rootElement = this.#editor.getRootElement();
14522
+ if (!rootElement) return null
14523
+
14524
+ const caret = caretFromPoint(event.clientX, event.clientY);
14525
+ if (!caret || !rootElement.contains(caret.node)) return null
14526
+
14527
+ // A caret on the root itself points between blocks. Mentions behave like text:
14528
+ // they only drop onto an existing line, so snap to the nearest one.
14529
+ if (caret.node === rootElement) {
14530
+ return this.#nearestLineCaret(rootElement, event.clientY)
14531
+ } else {
14532
+ return caret
14533
+ }
14534
+ }
14535
+
14536
+ #nearestLineCaret(rootElement, clientY) {
14537
+ let nearestLine = null;
14538
+ let nearestDistance = Infinity;
14539
+
14540
+ for (const line of rootElement.children) {
14541
+ const rect = line.getBoundingClientRect();
14542
+ const distance = Math.min(Math.abs(clientY - rect.top), Math.abs(clientY - rect.bottom));
14543
+ if (distance < nearestDistance) {
14544
+ nearestDistance = distance;
14545
+ nearestLine = line;
14546
+ }
14547
+ }
14548
+
14549
+ if (!nearestLine) return null
14550
+
14551
+ const rect = nearestLine.getBoundingClientRect();
14552
+ if (clientY < rect.top) {
14553
+ return { node: nearestLine, offset: 0 }
14554
+ } else {
14555
+ return { node: nearestLine, offset: nearestLine.childNodes.length }
14556
+ }
14557
+ }
14558
+
14559
+ #moveAttachment(draggedKey, dropPoint) {
14560
+ this.#editor.update(() => {
14561
+ const draggedNode = Yo(draggedKey);
14562
+ if (!$isCustomActionTextAttachmentNode(draggedNode)) return
14563
+
14564
+ const selection = Gr({
14565
+ anchorNode: dropPoint.node,
14566
+ anchorOffset: dropPoint.offset,
14567
+ focusNode: dropPoint.node,
14568
+ focusOffset: dropPoint.offset
14569
+ }, this.#editor);
14570
+ if (!selection) return
14571
+
14572
+ es(selection);
14573
+
14574
+ draggedNode.remove();
14575
+ selection.insertNodes([ draggedNode ]);
14576
+ });
14577
+ }
14578
+
14579
+ #updateDropIndicator(event) {
14580
+ this.#hideCaret();
14581
+
14582
+ const dropPoint = this.#resolveDropPoint(event);
14583
+ if (dropPoint) this.#showCaret(this.#caretRectFor(dropPoint));
14584
+ }
14585
+
14586
+ #caretRectFor({ node, offset }) {
14587
+ const rect = caretRect(node, offset);
14588
+ if (rect) return rect
14589
+
14590
+ // A blank line has no text to measure, so fall back to the line's own box.
14591
+ const line = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
14592
+ if (!line) return null
14593
+
14594
+ const lineRect = line.getBoundingClientRect();
14595
+ return { left: lineRect.left, top: lineRect.top, height: lineRect.height }
14596
+ }
14597
+
14598
+ #showCaret(rect) {
14599
+ if (!rect) return
14600
+
14601
+ const caret = this.#ensureCaretIndicator();
14602
+ caret.style.blockSize = `${rect.height}px`;
14603
+ caret.style.insetInlineStart = `${rect.left}px`;
14604
+ caret.style.insetBlockStart = `${rect.top}px`;
14605
+ }
14606
+
14607
+ #ensureCaretIndicator() {
14608
+ this.#dropIndicator ||= createElement("div", { className: "lexxy-drop-caret" });
14609
+
14610
+ this.#editorElement().appendChild(this.#dropIndicator);
14611
+ this.#dropIndicator.style.display = "block";
14612
+ return this.#dropIndicator
14613
+ }
14614
+
14615
+ #editorElement() {
14616
+ return this.#editor.getRootElement().closest("lexxy-editor")
14617
+ }
14618
+
14619
+ #hideCaret() {
14620
+ if (this.#dropIndicator) this.#dropIndicator.style.display = "none";
14621
+ }
14622
+
14623
+ #customAttachmentElementFrom(target) {
14624
+ return target?.closest?.("[data-lexxy-decorator][data-lexical-node-key]")
14625
+ }
14626
+
14627
+ #cleanup() {
14628
+ if (this.#draggedNodeKey) {
14629
+ const rootElement = this.#editor.getRootElement();
14630
+ const attachment = rootElement?.querySelector(`[data-lexical-node-key="${this.#draggedNodeKey}"]`);
14631
+ attachment?.classList.remove("lexxy-dragging");
14632
+ }
14633
+
14634
+ this.#hideCaret();
14635
+ this.#draggedNodeKey = null;
14636
+
14637
+ if (this.#draggingRafId) {
14638
+ cancelAnimationFrame(this.#draggingRafId);
14639
+ this.#draggingRafId = null;
14640
+ }
14641
+
14642
+ if (this.#dragOverRafId) {
14643
+ cancelAnimationFrame(this.#dragOverRafId);
14644
+ this.#dragOverRafId = null;
14645
+ }
14646
+ }
14647
+ }
14648
+
14649
+ class CustomAttachmentDragAndDropExtension extends LexxyExtension {
14650
+ get enabled() {
14651
+ return this.editorElement.supportsRichText
14652
+ }
14653
+
14654
+ get lexicalExtension() {
14655
+ return dc({
14656
+ name: "lexxy/custom-attachment-drag-and-drop",
14657
+ register: (editor) => {
14658
+ const dragAndDrop = new CustomAttachmentDragAndDrop(editor);
14659
+ return () => dragAndDrop.destroy()
14660
+ }
14661
+ })
14662
+ }
14663
+ }
14664
+
14372
14665
  class LexicalEditorElement extends HTMLElement {
14373
14666
  static formAssociated = true
14374
14667
  static debug = false
@@ -14525,7 +14818,8 @@ class LexicalEditorElement extends HTMLElement {
14525
14818
  AttachmentsExtension,
14526
14819
  FormatEscapeExtension,
14527
14820
  LinkOpenerExtension,
14528
- PreventLexicalTripleClickExtension
14821
+ PreventLexicalTripleClickExtension,
14822
+ CustomAttachmentDragAndDropExtension
14529
14823
  ]
14530
14824
  }
14531
14825
 
@@ -15561,7 +15855,9 @@ class LexicalPromptElement extends HTMLElement {
15561
15855
  if (!node) return
15562
15856
 
15563
15857
  if (this.#cursorIsTypingSearchTerm(node, offset)) {
15564
- return
15858
+ if (!this.popoverElement.hasAttribute("data-anchored")) {
15859
+ this.#positionPopover();
15860
+ }
15565
15861
  } else {
15566
15862
  this.#hidePopover();
15567
15863
  }
@@ -15692,8 +15988,16 @@ class LexicalPromptElement extends HTMLElement {
15692
15988
  }
15693
15989
  }
15694
15990
 
15991
+ // Right after a Turbo history restore the editor reconnects before the DOM selection
15992
+ // is re-established, so the cursor geometry is momentarily unavailable. Anchoring then
15993
+ // would pin the menu to the editor's left edge for the rest of the open cycle, so we
15994
+ // skip it and let a later reposition anchor it once the selection is ready. The menu
15995
+ // stays hidden until anchored (see the `[data-anchored]` rule in the stylesheet).
15695
15996
  #positionPopover() {
15696
- const { x, y, fontSize } = this.#selection.cursorPosition;
15997
+ const cursorPosition = this.#selection.cursorPosition;
15998
+ if (!cursorPosition) return
15999
+
16000
+ const { x, y, fontSize } = cursorPosition;
15697
16001
  const editorRect = this.#editorElement.getBoundingClientRect();
15698
16002
  const contentRect = this.#editorContentElement.getBoundingClientRect();
15699
16003
  const verticalOffset = contentRect.top - editorRect.top;
@@ -17132,5 +17436,5 @@ const configure = Lexxy.configure;
17132
17436
  // Pushing elements definition to after the current call stack to allow global configuration to take place first
17133
17437
  setTimeout(defineElements, 0);
17134
17438
 
17135
- export { $createActionTextAttachmentNode, $createActionTextAttachmentUploadNode, $isActionTextAttachmentNode, ActionTextAttachmentNode, ActionTextAttachmentUploadNode, CustomActionTextAttachmentNode, LexxyExtension as Extension, HorizontalDividerNode, NativeAdapter, configure, highlightCode, highlightElement };
17439
+ export { $createActionTextAttachmentNode, $createActionTextAttachmentUploadNode, $isActionTextAttachmentNode, $isCustomActionTextAttachmentNode, ActionTextAttachmentNode, ActionTextAttachmentUploadNode, CustomActionTextAttachmentNode, LexxyExtension as Extension, HorizontalDividerNode, NativeAdapter, configure, highlightCode, highlightElement };
17136
17440
  //# sourceMappingURL=lexxy.js.map
Binary file
Binary file