@webiny/lexical-nodes 0.0.0-unstable.06b2ede40f

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 (81) hide show
  1. package/FontColorNode.d.ts +43 -0
  2. package/FontColorNode.js +122 -0
  3. package/FontColorNode.js.map +1 -0
  4. package/HeadingNode.d.ts +40 -0
  5. package/HeadingNode.js +195 -0
  6. package/HeadingNode.js.map +1 -0
  7. package/ImageNode.d.ts +56 -0
  8. package/ImageNode.js +164 -0
  9. package/ImageNode.js.map +1 -0
  10. package/LICENSE +21 -0
  11. package/LinkNode.d.ts +101 -0
  12. package/LinkNode.js +327 -0
  13. package/LinkNode.js.map +1 -0
  14. package/ListItemNode.d.ts +43 -0
  15. package/ListItemNode.js +363 -0
  16. package/ListItemNode.js.map +1 -0
  17. package/ListNode.d.ts +53 -0
  18. package/ListNode.js +248 -0
  19. package/ListNode.js.map +1 -0
  20. package/ParagraphNode.d.ts +39 -0
  21. package/ParagraphNode.js +157 -0
  22. package/ParagraphNode.js.map +1 -0
  23. package/QuoteNode.d.ts +38 -0
  24. package/QuoteNode.js +120 -0
  25. package/QuoteNode.js.map +1 -0
  26. package/README.md +6 -0
  27. package/components/ImageNode/ContentEditable.css +22 -0
  28. package/components/ImageNode/ContentEditable.d.ts +12 -0
  29. package/components/ImageNode/ContentEditable.js +19 -0
  30. package/components/ImageNode/ContentEditable.js.map +1 -0
  31. package/components/ImageNode/ImageComponent.css +43 -0
  32. package/components/ImageNode/ImageComponent.d.ts +18 -0
  33. package/components/ImageNode/ImageComponent.js +235 -0
  34. package/components/ImageNode/ImageComponent.js.map +1 -0
  35. package/components/ImageNode/ImageResizer.d.ts +24 -0
  36. package/components/ImageNode/ImageResizer.js +211 -0
  37. package/components/ImageNode/ImageResizer.js.map +1 -0
  38. package/components/ImageNode/Placeholder.css +20 -0
  39. package/components/ImageNode/Placeholder.d.ts +15 -0
  40. package/components/ImageNode/Placeholder.js +24 -0
  41. package/components/ImageNode/Placeholder.js.map +1 -0
  42. package/components/ImageNode/SharedHistoryContext.d.ts +10 -0
  43. package/components/ImageNode/SharedHistoryContext.js +19 -0
  44. package/components/ImageNode/SharedHistoryContext.js.map +1 -0
  45. package/generateInitialLexicalValue.d.ts +4 -0
  46. package/generateInitialLexicalValue.js +27 -0
  47. package/generateInitialLexicalValue.js.map +1 -0
  48. package/index.d.ts +19 -0
  49. package/index.js +51 -0
  50. package/index.js.map +1 -0
  51. package/package.json +39 -0
  52. package/prepareLexicalState.d.ts +2 -0
  53. package/prepareLexicalState.js +53 -0
  54. package/prepareLexicalState.js.map +1 -0
  55. package/types.d.ts +11 -0
  56. package/types.js +3 -0
  57. package/types.js.map +1 -0
  58. package/utils/clearNodeFormating.d.ts +2 -0
  59. package/utils/clearNodeFormating.js +23 -0
  60. package/utils/clearNodeFormating.js.map +1 -0
  61. package/utils/formatList.d.ts +19 -0
  62. package/utils/formatList.js +412 -0
  63. package/utils/formatList.js.map +1 -0
  64. package/utils/formatToHeading.d.ts +3 -0
  65. package/utils/formatToHeading.js +19 -0
  66. package/utils/formatToHeading.js.map +1 -0
  67. package/utils/formatToParagraph.d.ts +2 -0
  68. package/utils/formatToParagraph.js +13 -0
  69. package/utils/formatToParagraph.js.map +1 -0
  70. package/utils/formatToQuote.d.ts +2 -0
  71. package/utils/formatToQuote.js +19 -0
  72. package/utils/formatToQuote.js.map +1 -0
  73. package/utils/getStyleId.d.ts +11 -0
  74. package/utils/getStyleId.js +14 -0
  75. package/utils/getStyleId.js.map +1 -0
  76. package/utils/listNode.d.ts +21 -0
  77. package/utils/listNode.js +103 -0
  78. package/utils/listNode.js.map +1 -0
  79. package/utils/toggleLink.d.ts +8 -0
  80. package/utils/toggleLink.js +131 -0
  81. package/utils/toggleLink.js.map +1 -0
@@ -0,0 +1,21 @@
1
+ import type { LexicalNode, Spread } from "lexical";
2
+ import type { ListNode } from "../ListNode";
3
+ import type { ListItemNode } from "../ListItemNode";
4
+ export declare function $getListDepth(listNode: ListNode): number;
5
+ export declare function $getTopListNode(listItem: LexicalNode): ListNode;
6
+ export declare function $getAllListItems(node: ListNode): Array<ListItemNode>;
7
+ declare const NestedListNodeBrand: unique symbol;
8
+ /**
9
+ * Checks to see if the passed node is a ListItemNode and has a ListNode as a child.
10
+ * @param node - The node to be checked.
11
+ * @returns true if the node is a ListItemNode and has a ListNode child, false otherwise.
12
+ */
13
+ export declare function isNestedListNode(node: LexicalNode | null | undefined): node is Spread<{
14
+ getFirstChild(): ListNode;
15
+ [NestedListNodeBrand]: never;
16
+ }, ListItemNode>;
17
+ export declare function findNearestListItemNode(node: LexicalNode): ListItemNode | null;
18
+ export declare function getUniqueListItemNodes(nodeList: Array<LexicalNode>): Array<ListItemNode>;
19
+ export declare function $removeHighestEmptyListParent(sublist: ListItemNode | ListNode): void;
20
+ export declare function wrapInListItem(node: LexicalNode): ListItemNode;
21
+ export {};
@@ -0,0 +1,103 @@
1
+ import { $isListNode } from "../ListNode";
2
+ import { $createListItemNode, $isListItemNode } from "../ListItemNode";
3
+ export function $getListDepth(listNode) {
4
+ let depth = 1;
5
+ let parent = listNode.getParent();
6
+ while (parent !== null) {
7
+ if ($isListItemNode(parent)) {
8
+ const parentList = parent.getParent();
9
+ if ($isListNode(parentList)) {
10
+ depth++;
11
+ parent = parentList?.getParent() || null;
12
+ continue;
13
+ }
14
+ console.log("A WebinyListItemNode must have a WebinyListNode for a parent.");
15
+ }
16
+ return depth;
17
+ }
18
+ return depth;
19
+ }
20
+ export function $getTopListNode(listItem) {
21
+ let list = listItem.getParent();
22
+ if (!$isListNode(list)) {
23
+ console.log("A WebinyListItemNode must have a ListNode for a parent.");
24
+ return listItem;
25
+ }
26
+ let parent = list;
27
+ while (parent !== null) {
28
+ parent = parent.getParent();
29
+ if ($isListNode(parent)) {
30
+ list = parent;
31
+ }
32
+ }
33
+ return list;
34
+ }
35
+ export function $getAllListItems(node) {
36
+ let listItemNodes = [];
37
+ const listChildren = node.getChildren().filter($isListItemNode);
38
+ for (let i = 0; i < listChildren.length; i++) {
39
+ const listItemNode = listChildren[i];
40
+ const firstChild = listItemNode?.getFirstChild();
41
+ if ($isListNode(firstChild)) {
42
+ listItemNodes = listItemNodes.concat($getAllListItems(firstChild));
43
+ } else {
44
+ listItemNodes.push(listItemNode);
45
+ }
46
+ }
47
+ return listItemNodes;
48
+ }
49
+ const NestedListNodeBrand = Symbol.for("@lexical/NestedListNodeBrand");
50
+
51
+ /**
52
+ * Checks to see if the passed node is a ListItemNode and has a ListNode as a child.
53
+ * @param node - The node to be checked.
54
+ * @returns true if the node is a ListItemNode and has a ListNode child, false otherwise.
55
+ */
56
+ export function isNestedListNode(node) {
57
+ return $isListItemNode(node) && $isListNode(node.getFirstChild());
58
+ }
59
+
60
+ // TODO: rewrite with $findMatchingParent or *nodeOfType
61
+ export function findNearestListItemNode(node) {
62
+ let currentNode = node;
63
+ while (currentNode !== null) {
64
+ if ($isListItemNode(currentNode)) {
65
+ return currentNode;
66
+ }
67
+ currentNode = currentNode.getParent();
68
+ }
69
+ return null;
70
+ }
71
+ export function getUniqueListItemNodes(nodeList) {
72
+ const keys = new Set();
73
+ for (let i = 0; i < nodeList.length; i++) {
74
+ const node = nodeList[i];
75
+ if ($isListItemNode(node)) {
76
+ keys.add(node);
77
+ }
78
+ }
79
+ return Array.from(keys);
80
+ }
81
+ export function $removeHighestEmptyListParent(sublist) {
82
+ // Nodes may be repeatedly indented, to create deeply nested lists that each
83
+ // contain just one bullet.
84
+ // Our goal is to remove these (empty) deeply nested lists. The easiest
85
+ // way to do that is crawl back up the tree until we find a node that has siblings
86
+ // (e.g. is actually part of the list contents) and delete that, or delete
87
+ // the root of the list (if no list nodes have siblings.)
88
+ let emptyListPtr = sublist;
89
+ while (emptyListPtr.getNextSibling() == null && emptyListPtr.getPreviousSibling() == null) {
90
+ const parent = emptyListPtr.getParent();
91
+ if (parent == null || !($isListItemNode(emptyListPtr) || $isListNode(emptyListPtr))) {
92
+ break;
93
+ }
94
+ emptyListPtr = parent;
95
+ }
96
+ emptyListPtr.remove();
97
+ }
98
+ export function wrapInListItem(node) {
99
+ const listItemWrapper = $createListItemNode();
100
+ return listItemWrapper.append(node);
101
+ }
102
+
103
+ //# sourceMappingURL=listNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["$isListNode","$createListItemNode","$isListItemNode","$getListDepth","listNode","depth","parent","getParent","parentList","console","log","$getTopListNode","listItem","list","$getAllListItems","node","listItemNodes","listChildren","getChildren","filter","i","length","listItemNode","firstChild","getFirstChild","concat","push","NestedListNodeBrand","Symbol","for","isNestedListNode","findNearestListItemNode","currentNode","getUniqueListItemNodes","nodeList","keys","Set","add","Array","from","$removeHighestEmptyListParent","sublist","emptyListPtr","getNextSibling","getPreviousSibling","remove","wrapInListItem","listItemWrapper","append"],"sources":["listNode.ts"],"sourcesContent":["import type { LexicalNode, Spread } from \"lexical\";\n\nimport type { ListNode } from \"~/ListNode\";\nimport { $isListNode } from \"~/ListNode\";\nimport type { ListItemNode } from \"~/ListItemNode\";\nimport { $createListItemNode, $isListItemNode } from \"~/ListItemNode\";\n\nexport function $getListDepth(listNode: ListNode): number {\n let depth = 1;\n let parent = listNode.getParent();\n\n while (parent !== null) {\n if ($isListItemNode(parent)) {\n const parentList = parent.getParent();\n\n if ($isListNode(parentList)) {\n depth++;\n parent = parentList?.getParent() || null;\n continue;\n }\n console.log(\"A WebinyListItemNode must have a WebinyListNode for a parent.\");\n }\n\n return depth;\n }\n\n return depth;\n}\n\nexport function $getTopListNode(listItem: LexicalNode): ListNode {\n let list = listItem.getParent<ListNode>();\n\n if (!$isListNode(list)) {\n console.log(\"A WebinyListItemNode must have a ListNode for a parent.\");\n return listItem as ListNode;\n }\n\n let parent: ListNode | null = list;\n\n while (parent !== null) {\n parent = parent.getParent();\n\n if ($isListNode(parent)) {\n list = parent;\n }\n }\n\n return list;\n}\n\nexport function $getAllListItems(node: ListNode): Array<ListItemNode> {\n let listItemNodes: Array<ListItemNode> = [];\n const listChildren: Array<ListItemNode> = node.getChildren().filter($isListItemNode);\n\n for (let i = 0; i < listChildren.length; i++) {\n const listItemNode = listChildren[i];\n const firstChild = listItemNode?.getFirstChild();\n\n if ($isListNode(firstChild)) {\n listItemNodes = listItemNodes.concat($getAllListItems(firstChild));\n } else {\n listItemNodes.push(listItemNode);\n }\n }\n\n return listItemNodes;\n}\n\nconst NestedListNodeBrand: unique symbol = Symbol.for(\"@lexical/NestedListNodeBrand\");\n\n/**\n * Checks to see if the passed node is a ListItemNode and has a ListNode as a child.\n * @param node - The node to be checked.\n * @returns true if the node is a ListItemNode and has a ListNode child, false otherwise.\n */\nexport function isNestedListNode(\n node: LexicalNode | null | undefined\n): node is Spread<{ getFirstChild(): ListNode; [NestedListNodeBrand]: never }, ListItemNode> {\n return $isListItemNode(node) && $isListNode(node.getFirstChild());\n}\n\n// TODO: rewrite with $findMatchingParent or *nodeOfType\nexport function findNearestListItemNode(node: LexicalNode): ListItemNode | null {\n let currentNode: LexicalNode | null = node;\n\n while (currentNode !== null) {\n if ($isListItemNode(currentNode)) {\n return currentNode;\n }\n currentNode = currentNode.getParent();\n }\n\n return null;\n}\n\nexport function getUniqueListItemNodes(nodeList: Array<LexicalNode>): Array<ListItemNode> {\n const keys = new Set<ListItemNode>();\n\n for (let i = 0; i < nodeList.length; i++) {\n const node = nodeList[i];\n\n if ($isListItemNode(node)) {\n keys.add(node);\n }\n }\n\n return Array.from(keys);\n}\n\nexport function $removeHighestEmptyListParent(sublist: ListItemNode | ListNode) {\n // Nodes may be repeatedly indented, to create deeply nested lists that each\n // contain just one bullet.\n // Our goal is to remove these (empty) deeply nested lists. The easiest\n // way to do that is crawl back up the tree until we find a node that has siblings\n // (e.g. is actually part of the list contents) and delete that, or delete\n // the root of the list (if no list nodes have siblings.)\n let emptyListPtr = sublist;\n\n while (emptyListPtr.getNextSibling() == null && emptyListPtr.getPreviousSibling() == null) {\n const parent = emptyListPtr.getParent<ListItemNode | ListNode>();\n\n if (parent == null || !($isListItemNode(emptyListPtr) || $isListNode(emptyListPtr))) {\n break;\n }\n\n emptyListPtr = parent;\n }\n\n emptyListPtr.remove();\n}\n\nexport function wrapInListItem(node: LexicalNode): ListItemNode {\n const listItemWrapper = $createListItemNode();\n return listItemWrapper.append(node);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,8 @@
1
+ import type { LinkAttributes } from "../LinkNode";
2
+ /**
3
+ * Generates or updates a LinkNode. It can also delete a LinkNode if the URL is null,
4
+ * but saves any children and brings them up to the parent node.
5
+ * @param url - The URL the link directs to.
6
+ * @param attributes - Optional HTML a tag attributes. { target, rel, title }
7
+ */
8
+ export declare function toggleLink(url: null | string, attributes?: LinkAttributes): void;
@@ -0,0 +1,131 @@
1
+ import { $getSelection, $isElementNode, $isRangeSelection } from "lexical";
2
+ import { $createLinkNode, $isLinkNode } from "../LinkNode";
3
+
4
+ /**
5
+ * Generates or updates a LinkNode. It can also delete a LinkNode if the URL is null,
6
+ * but saves any children and brings them up to the parent node.
7
+ * @param url - The URL the link directs to.
8
+ * @param attributes - Optional HTML a tag attributes. { target, rel, title }
9
+ */
10
+ export function toggleLink(url, attributes = {}) {
11
+ const {
12
+ target,
13
+ title,
14
+ alt
15
+ } = attributes;
16
+ const rel = attributes.rel === undefined ? "noreferrer" : attributes.rel;
17
+ const selection = $getSelection();
18
+ if (!$isRangeSelection(selection)) {
19
+ return;
20
+ }
21
+ const nodes = selection.extract();
22
+ if (url === null) {
23
+ // Remove LinkNodes
24
+ nodes.forEach(node => {
25
+ const parent = node.getParent();
26
+ if ($isLinkNode(parent)) {
27
+ const children = parent.getChildren();
28
+ for (let i = 0; i < children.length; i++) {
29
+ parent.insertBefore(children[i]);
30
+ }
31
+ parent.remove();
32
+ }
33
+ });
34
+ } else {
35
+ // Add or merge LinkNodes
36
+ if (nodes.length === 1) {
37
+ const firstNode = nodes[0];
38
+ // if the first node is a LinkNode or if its
39
+ // parent is a LinkNode, we update the URL, target and rel.
40
+ const linkNode = $isLinkNode(firstNode) ? firstNode : $getLinkAncestor(firstNode);
41
+ if (linkNode !== null) {
42
+ linkNode.setURL(url);
43
+ if (target !== undefined) {
44
+ linkNode.setTarget(target);
45
+ }
46
+ if (rel !== null) {
47
+ linkNode.setRel(rel);
48
+ }
49
+ if (title !== undefined) {
50
+ linkNode.setTitle(title);
51
+ }
52
+ if (alt !== undefined) {
53
+ linkNode.setAlt(alt);
54
+ }
55
+ return;
56
+ }
57
+ }
58
+ let prevParent = null;
59
+ let linkNode = null;
60
+ nodes.forEach(node => {
61
+ const parent = node.getParent();
62
+ if (parent === linkNode || parent === null || $isElementNode(node) && !node.isInline()) {
63
+ return;
64
+ }
65
+ if ($isLinkNode(parent)) {
66
+ linkNode = parent;
67
+ parent.setURL(url);
68
+ if (target !== undefined) {
69
+ parent.setTarget(target);
70
+ }
71
+ if (rel !== null) {
72
+ linkNode.setRel(rel);
73
+ }
74
+ if (title !== undefined) {
75
+ linkNode.setTitle(title);
76
+ }
77
+ if (alt !== undefined) {
78
+ linkNode.setAlt(alt);
79
+ }
80
+ return;
81
+ }
82
+ if (!parent.is(prevParent)) {
83
+ prevParent = parent;
84
+ linkNode = $createLinkNode(url, {
85
+ rel,
86
+ target,
87
+ alt
88
+ });
89
+ if ($isLinkNode(parent)) {
90
+ if (node.getPreviousSibling() === null) {
91
+ parent.insertBefore(linkNode);
92
+ } else {
93
+ parent.insertAfter(linkNode);
94
+ }
95
+ } else {
96
+ node.insertBefore(linkNode);
97
+ }
98
+ }
99
+ if ($isLinkNode(node)) {
100
+ if (node.is(linkNode)) {
101
+ return;
102
+ }
103
+ if (linkNode !== null) {
104
+ const children = node.getChildren();
105
+ for (let i = 0; i < children.length; i++) {
106
+ linkNode.append(children[i]);
107
+ }
108
+ }
109
+ node.remove();
110
+ return;
111
+ }
112
+ if (linkNode !== null) {
113
+ linkNode.append(node);
114
+ }
115
+ });
116
+ }
117
+ }
118
+ function $getLinkAncestor(node) {
119
+ const ancestor = $getAncestor(node, $isLinkNode);
120
+ if (!ancestor) {
121
+ return null;
122
+ }
123
+ return ancestor;
124
+ }
125
+ function $getAncestor(node, predicate) {
126
+ let parent = node;
127
+ while (parent !== null && (parent = parent.getParent()) !== null && !predicate(parent)) {}
128
+ return parent;
129
+ }
130
+
131
+ //# sourceMappingURL=toggleLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["$getSelection","$isElementNode","$isRangeSelection","$createLinkNode","$isLinkNode","toggleLink","url","attributes","target","title","alt","rel","undefined","selection","nodes","extract","forEach","node","parent","getParent","children","getChildren","i","length","insertBefore","remove","firstNode","linkNode","$getLinkAncestor","setURL","setTarget","setRel","setTitle","setAlt","prevParent","isInline","is","getPreviousSibling","insertAfter","append","ancestor","$getAncestor","predicate"],"sources":["toggleLink.ts"],"sourcesContent":["import type { ElementNode, LexicalNode } from \"lexical\";\nimport { $getSelection, $isElementNode, $isRangeSelection } from \"lexical\";\nimport type { LinkAttributes, LinkNode } from \"~/LinkNode\";\nimport { $createLinkNode, $isLinkNode } from \"~/LinkNode\";\n\n/**\n * Generates or updates a LinkNode. It can also delete a LinkNode if the URL is null,\n * but saves any children and brings them up to the parent node.\n * @param url - The URL the link directs to.\n * @param attributes - Optional HTML a tag attributes. { target, rel, title }\n */\nexport function toggleLink(url: null | string, attributes: LinkAttributes = {}): void {\n const { target, title, alt } = attributes;\n const rel = attributes.rel === undefined ? \"noreferrer\" : attributes.rel;\n const selection = $getSelection();\n\n if (!$isRangeSelection(selection)) {\n return;\n }\n const nodes = selection.extract();\n\n if (url === null) {\n // Remove LinkNodes\n nodes.forEach(node => {\n const parent = node.getParent();\n\n if ($isLinkNode(parent)) {\n const children = parent.getChildren();\n\n for (let i = 0; i < children.length; i++) {\n parent.insertBefore(children[i]);\n }\n\n parent.remove();\n }\n });\n } else {\n // Add or merge LinkNodes\n if (nodes.length === 1) {\n const firstNode = nodes[0];\n // if the first node is a LinkNode or if its\n // parent is a LinkNode, we update the URL, target and rel.\n const linkNode = $isLinkNode(firstNode) ? firstNode : $getLinkAncestor(firstNode);\n if (linkNode !== null) {\n linkNode.setURL(url);\n if (target !== undefined) {\n linkNode.setTarget(target);\n }\n if (rel !== null) {\n linkNode.setRel(rel);\n }\n if (title !== undefined) {\n linkNode.setTitle(title);\n }\n\n if (alt !== undefined) {\n linkNode.setAlt(alt);\n }\n return;\n }\n }\n\n let prevParent: ElementNode | LinkNode | null = null;\n let linkNode: LinkNode | null = null;\n\n nodes.forEach(node => {\n const parent = node.getParent();\n\n if (\n parent === linkNode ||\n parent === null ||\n ($isElementNode(node) && !node.isInline())\n ) {\n return;\n }\n\n if ($isLinkNode(parent)) {\n linkNode = parent;\n parent.setURL(url);\n if (target !== undefined) {\n parent.setTarget(target);\n }\n if (rel !== null) {\n linkNode.setRel(rel);\n }\n if (title !== undefined) {\n linkNode.setTitle(title);\n }\n if (alt !== undefined) {\n linkNode.setAlt(alt);\n }\n return;\n }\n\n if (!parent.is(prevParent)) {\n prevParent = parent;\n linkNode = $createLinkNode(url, { rel, target, alt });\n\n if ($isLinkNode(parent)) {\n if (node.getPreviousSibling() === null) {\n parent.insertBefore(linkNode);\n } else {\n parent.insertAfter(linkNode);\n }\n } else {\n node.insertBefore(linkNode);\n }\n }\n\n if ($isLinkNode(node)) {\n if (node.is(linkNode)) {\n return;\n }\n if (linkNode !== null) {\n const children = node.getChildren();\n\n for (let i = 0; i < children.length; i++) {\n linkNode.append(children[i]);\n }\n }\n\n node.remove();\n return;\n }\n\n if (linkNode !== null) {\n linkNode.append(node);\n }\n });\n }\n}\n\nfunction $getLinkAncestor(node: LexicalNode): LinkNode | null {\n const ancestor = $getAncestor(node, $isLinkNode);\n if (!ancestor) {\n return null;\n }\n\n return ancestor as LinkNode;\n}\n\nfunction $getAncestor<NodeType extends LexicalNode = LexicalNode>(\n node: LexicalNode,\n predicate: (ancestor: LexicalNode) => ancestor is NodeType\n): null | LexicalNode {\n let parent: null | LexicalNode = node;\n while (parent !== null && (parent = parent.getParent()) !== null && !predicate(parent)) {}\n return parent;\n}\n"],"mappings":"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","ignoreList":[]}