@37signals/lexxy 0.9.14-beta → 0.9.15-alpha.1
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/lexxy.esm.js +58 -13
- package/package.json +1 -1
package/dist/lexxy.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { highlightCode } from './lexxy_helpers.esm.js';
|
|
2
2
|
import DOMPurify from 'dompurify';
|
|
3
3
|
import { getStyleObjectFromCSS, getCSSFromStyleObject, $getSelectionStyleValueForProperty, $ensureForwardRangeSelection, $isAtNodeEnd, $patchStyleText, $setBlocksType, $forEachSelectedTextNode } from '@lexical/selection';
|
|
4
|
-
import { SKIP_DOM_SELECTION_TAG, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, CAN_REDO_COMMAND, $getSelection, $isRangeSelection, DecoratorNode, $createTextNode, $caretFromPoint, $setSelectionFromCaretRange, $getCaretRange, $normalizeCaret, $getChildCaret, $getCaretInDirection, $isParagraphNode, $isLineBreakNode, $createParagraphNode, $isElementNode, $isRootOrShadowRoot, $isRootNode, $createNodeSelection, $isDecoratorNode, $isTextNode, $getSiblingCaret, $rewindSiblingCaret, $splitAtPointCaretNext, $isChildCaret, $isTextPointCaret, $isExtendableTextPointCaret, $isSiblingCaret, $getCommonAncestor, $findMatchingParent, TextNode, createCommand, defineExtension, COMMAND_PRIORITY_EDITOR, $getEditor, $getNodeByKey, HISTORY_MERGE_TAG, SKIP_SCROLL_INTO_VIEW_TAG, $cloneWithProperties, $getNearestRootOrShadowRoot, $createRangeSelection, $setSelection, createState, COMMAND_PRIORITY_NORMAL, $getState, $setState, $hasUpdateTag, PASTE_TAG, FORMAT_TEXT_COMMAND, UNDO_COMMAND, REDO_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, $isNodeSelection,
|
|
4
|
+
import { SKIP_DOM_SELECTION_TAG, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, CAN_REDO_COMMAND, $getSelection, $isRangeSelection, DecoratorNode, $createTextNode, $getRoot, $caretFromPoint, $setSelectionFromCaretRange, $getCaretRange, $normalizeCaret, $getChildCaret, $getCaretInDirection, $isParagraphNode, $isLineBreakNode, $createParagraphNode, $isElementNode, $isRootOrShadowRoot, $isRootNode, $createNodeSelection, $isDecoratorNode, $isTextNode, $getSiblingCaret, $rewindSiblingCaret, $splitAtPointCaretNext, $isChildCaret, $isTextPointCaret, $isExtendableTextPointCaret, $isSiblingCaret, $getCommonAncestor, $findMatchingParent, TextNode, createCommand, defineExtension, COMMAND_PRIORITY_EDITOR, $getEditor, $getNodeByKey, HISTORY_MERGE_TAG, SKIP_SCROLL_INTO_VIEW_TAG, $cloneWithProperties, $getNearestRootOrShadowRoot, $createRangeSelection, $setSelection, createState, COMMAND_PRIORITY_NORMAL, $getState, $setState, $hasUpdateTag, PASTE_TAG, FORMAT_TEXT_COMMAND, UNDO_COMMAND, REDO_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, $isNodeSelection, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_DOWN_COMMAND, DELETE_CHARACTER_COMMAND, SELECTION_CHANGE_COMMAND, CLICK_COMMAND, isDOMNode, $getNearestNodeFromDOMNode, $addUpdateTag, ElementNode, $splitNode, $getChildCaretAtIndex, $createLineBreakNode, PASTE_COMMAND, SELECTION_INSERT_CLIPBOARD_NODES_COMMAND, ParagraphNode, RootNode, COMMAND_PRIORITY_HIGH, DRAGSTART_COMMAND, DROP_COMMAND, INSERT_PARAGRAPH_COMMAND, mergeRegister as mergeRegister$1, CLEAR_HISTORY_COMMAND, $onUpdate, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_SPACE_COMMAND, INPUT_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND } from 'lexical';
|
|
5
5
|
import { LinkNode, $createAutoLinkNode, $toggleLink, $createLinkNode, $isLinkNode, AutoLinkNode } from '@lexical/link';
|
|
6
6
|
import { buildEditorFromExtensions } from '@lexical/extension';
|
|
7
7
|
import { ListNode, ListItemNode, $getListDepth, INSERT_UNORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $isListItemNode, $isListNode, registerList } from '@lexical/list';
|
|
@@ -1527,14 +1527,15 @@ function $isShadowRoot(node) {
|
|
|
1527
1527
|
return $isElementNode(node) && $isRootOrShadowRoot(node) && !$isRootNode(node)
|
|
1528
1528
|
}
|
|
1529
1529
|
|
|
1530
|
+
function $isSafeForRoot(node) {
|
|
1531
|
+
return ($isElementNode(node) || $isDecoratorNode(node)) && !node.isParentRequired()
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1530
1534
|
function $makeSafeForRoot(node) {
|
|
1531
|
-
if ($
|
|
1532
|
-
return $wrapNodeInElement(node, $createParagraphNode)
|
|
1533
|
-
} else if (node.isParentRequired()) {
|
|
1534
|
-
const parent = node.createRequiredParent();
|
|
1535
|
-
return $wrapNodeInElement(node, parent)
|
|
1536
|
-
} else {
|
|
1535
|
+
if ($isSafeForRoot(node)) {
|
|
1537
1536
|
return node
|
|
1537
|
+
} else {
|
|
1538
|
+
return $wrapNodeInElement(node, () => node.createParentElementNode())
|
|
1538
1539
|
}
|
|
1539
1540
|
}
|
|
1540
1541
|
|
|
@@ -1649,6 +1650,39 @@ function $isListItemStructurallyEmpty(listItem) {
|
|
|
1649
1650
|
return true
|
|
1650
1651
|
}
|
|
1651
1652
|
|
|
1653
|
+
// Returns the document text up to `offset` inside `targetNode`. Non-inline
|
|
1654
|
+
// element siblings are joined with `\n\n`, matching Lexical's own
|
|
1655
|
+
// ElementNode.getTextContent behavior.
|
|
1656
|
+
function $textBeforeOffset(targetNode, offset) {
|
|
1657
|
+
const parts = [];
|
|
1658
|
+
let done = false;
|
|
1659
|
+
|
|
1660
|
+
function visit(node) {
|
|
1661
|
+
if (done) return
|
|
1662
|
+
if (node === targetNode) {
|
|
1663
|
+
parts.push(node.getTextContent().slice(0, offset));
|
|
1664
|
+
done = true;
|
|
1665
|
+
return
|
|
1666
|
+
}
|
|
1667
|
+
if ($isElementNode(node)) {
|
|
1668
|
+
const children = node.getChildren();
|
|
1669
|
+
for (let i = 0; i < children.length; i++) {
|
|
1670
|
+
visit(children[i]);
|
|
1671
|
+
if (done) return
|
|
1672
|
+
const child = children[i];
|
|
1673
|
+
if ($isElementNode(child) && !child.isInline() && i < children.length - 1) {
|
|
1674
|
+
parts.push("\n\n");
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
} else {
|
|
1678
|
+
parts.push(node.getTextContent());
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
visit($getRoot());
|
|
1683
|
+
return parts.join("")
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1652
1686
|
function isAttachmentSpacerTextNode(node, previousNode, index, childCount) {
|
|
1653
1687
|
return $isTextNode(node)
|
|
1654
1688
|
&& node.getTextContent() === " "
|
|
@@ -8552,6 +8586,9 @@ class RemoteFilterSource extends BaseSource {
|
|
|
8552
8586
|
const NOTHING_FOUND_DEFAULT_MESSAGE = "Nothing found";
|
|
8553
8587
|
const FILTER_DEBOUNCE_INTERVAL = 50;
|
|
8554
8588
|
|
|
8589
|
+
// Start of line, or after a space or newline.
|
|
8590
|
+
const DEFAULT_ONLY_AT_PATTERN = "^|[ \\n]";
|
|
8591
|
+
|
|
8555
8592
|
class LexicalPromptElement extends HTMLElement {
|
|
8556
8593
|
#globalListeners = new ListenerBin()
|
|
8557
8594
|
#popoverListeners = new ListenerBin()
|
|
@@ -8597,6 +8634,10 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
8597
8634
|
return this.hasAttribute("supports-space-in-searches")
|
|
8598
8635
|
}
|
|
8599
8636
|
|
|
8637
|
+
get onlyAt() {
|
|
8638
|
+
return this.getAttribute("only-at")
|
|
8639
|
+
}
|
|
8640
|
+
|
|
8600
8641
|
get open() {
|
|
8601
8642
|
return this.popoverElement?.classList?.contains("lexxy-prompt-menu--visible")
|
|
8602
8643
|
}
|
|
@@ -8640,14 +8681,10 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
8640
8681
|
if (offset >= triggerLength) {
|
|
8641
8682
|
const textBeforeCursor = fullText.slice(offset - triggerLength, offset);
|
|
8642
8683
|
|
|
8643
|
-
// Check if trigger is at the start of the text node (new line case) or preceded by space or newline
|
|
8644
8684
|
if (textBeforeCursor === this.trigger) {
|
|
8645
|
-
const
|
|
8646
|
-
|
|
8647
|
-
const charBeforeTrigger = offset > triggerLength ? fullText[offset - triggerLength - 1] : null;
|
|
8648
|
-
const isPrecededBySpaceOrNewline = charBeforeTrigger === " " || charBeforeTrigger === "\n";
|
|
8685
|
+
const textBeforeTrigger = $textBeforeOffset(node, offset - triggerLength);
|
|
8649
8686
|
|
|
8650
|
-
if (
|
|
8687
|
+
if (this.#onlyAtRegExp.test(textBeforeTrigger)) {
|
|
8651
8688
|
this.#popoverListeners.dispose();
|
|
8652
8689
|
this.#showPopover();
|
|
8653
8690
|
}
|
|
@@ -8658,7 +8695,15 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
8658
8695
|
}));
|
|
8659
8696
|
}
|
|
8660
8697
|
|
|
8698
|
+
get #onlyAtRegExp() {
|
|
8699
|
+
return new RegExp(`(?:${this.onlyAt ?? DEFAULT_ONLY_AT_PATTERN})$`)
|
|
8700
|
+
}
|
|
8701
|
+
|
|
8661
8702
|
get #promptContentTypePermitted() {
|
|
8703
|
+
// `insert-editable-text` prompts never create attachments, so the
|
|
8704
|
+
// editor's attachment support and content-type allowlist don't apply.
|
|
8705
|
+
if (this.hasAttribute("insert-editable-text")) return true
|
|
8706
|
+
|
|
8662
8707
|
const el = this.#editorElement;
|
|
8663
8708
|
if (!el.supportsAttachments) {
|
|
8664
8709
|
return false
|