@lexical/text 0.9.0 → 0.9.2

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.
@@ -9,6 +9,14 @@
9
9
  var lexical = require('lexical');
10
10
 
11
11
  /** @module @lexical/text */
12
+
13
+ /**
14
+ * Finds a TextNode with a size larger than targetCharacters and returns
15
+ * the node along with the remaining length of the text.
16
+ * @param root - The RootNode.
17
+ * @param targetCharacters - The number of characters whose TextNode must be larger than.
18
+ * @returns The TextNode and the intersections offset, or null if no TextNode is found.
19
+ */
12
20
  function $findTextIntersectionFromCharacters(root, targetCharacters) {
13
21
  let node = root.getFirstChild();
14
22
  let currentCharacters = 0;
@@ -59,6 +67,13 @@ function $findTextIntersectionFromCharacters(root, targetCharacters) {
59
67
 
60
68
  return null;
61
69
  }
70
+ /**
71
+ * Determines if the root has any text content and can trim any whitespace if it does.
72
+ * @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
73
+ * @param trim - Should the root text have its whitespaced trimmed? Defaults to true.
74
+ * @returns true if text content is empty, false if there is text or isEditorComposing is true.
75
+ */
76
+
62
77
  function $isRootTextContentEmpty(isEditorComposing, trim = true) {
63
78
  if (isEditorComposing) {
64
79
  return false;
@@ -72,13 +87,32 @@ function $isRootTextContentEmpty(isEditorComposing, trim = true) {
72
87
 
73
88
  return text === '';
74
89
  }
90
+ /**
91
+ * Returns a function that executes {@link $isRootTextContentEmpty}
92
+ * @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
93
+ * @param trim - Should the root text have its whitespaced trimmed? Defaults to true.
94
+ * @returns A function that executes $isRootTextContentEmpty based on arguments.
95
+ */
96
+
75
97
  function $isRootTextContentEmptyCurry(isEditorComposing, trim) {
76
98
  return () => $isRootTextContentEmpty(isEditorComposing, trim);
77
99
  }
100
+ /**
101
+ * Returns the root's text content.
102
+ * @returns The root's text content.
103
+ */
104
+
78
105
  function $rootTextContent() {
79
106
  const root = lexical.$getRoot();
80
107
  return root.getTextContent();
81
108
  }
109
+ /**
110
+ * Determines if the input should show the placeholder. If anything is in
111
+ * in the root the placeholder should not be shown.
112
+ * @param isComposing - Is the editor in composition mode due to an active Input Method Editor?
113
+ * @returns true if the input should show the placeholder, false otherwise.
114
+ */
115
+
82
116
  function $canShowPlaceholder(isComposing) {
83
117
  if (!$isRootTextContentEmpty(isComposing, false)) {
84
118
  return false;
@@ -95,6 +129,10 @@ function $canShowPlaceholder(isComposing) {
95
129
  for (let i = 0; i < childrenLength; i++) {
96
130
  const topBlock = children[i];
97
131
 
132
+ if (lexical.$isDecoratorNode(topBlock)) {
133
+ return false;
134
+ }
135
+
98
136
  if (lexical.$isElementNode(topBlock)) {
99
137
  if (!lexical.$isParagraphNode(topBlock)) {
100
138
  return false;
@@ -119,9 +157,35 @@ function $canShowPlaceholder(isComposing) {
119
157
 
120
158
  return true;
121
159
  }
160
+ /**
161
+ * Returns a function that executes {@link $canShowPlaceholder}
162
+ * @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
163
+ * @returns A function that executes $canShowPlaceholder with arguments.
164
+ */
165
+
122
166
  function $canShowPlaceholderCurry(isEditorComposing) {
123
167
  return () => $canShowPlaceholder(isEditorComposing);
124
168
  }
169
+
170
+ /**
171
+ * Returns a touple that can be rested (...) into mergeRegister to clean up
172
+ * node transforms listeners that transforms text into another node, eg. a HashtagNode.
173
+ * @example
174
+ * ```ts
175
+ * useEffect(() => {
176
+ return mergeRegister(
177
+ ...registerLexicalTextEntity(editor, getMatch, targetNode, createNode),
178
+ );
179
+ }, [createNode, editor, getMatch, targetNode]);
180
+ * ```
181
+ * Where targetNode is the type of node containing the text you want to transform (like a text input),
182
+ * then getMatch uses a regex to find a matching text and creates the proper node to include the matching text.
183
+ * @param editor - The lexical editor.
184
+ * @param getMatch - Finds a matching string that satisfies a regex expression.
185
+ * @param targetNode - The node type that contains text to match with. eg. HashtagNode
186
+ * @param createNode - A function that creates a new node to contain the matched text. eg createHashtagNode
187
+ * @returns An array containing the plain text and reverse node transform listeners.
188
+ */
125
189
  function registerLexicalTextEntity(editor, getMatch, targetNode, createNode) {
126
190
  const isTargetNode = node => {
127
191
  return node instanceof targetNode;
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- 'use strict';var h=require("lexical");function r(c,g=!0){if(c)return!1;c=t();g&&(c=c.trim());return""===c}function t(){return h.$getRoot().getTextContent()}function u(c){if(!r(c,!1))return!1;c=h.$getRoot().getChildren();let g=c.length;if(1<g)return!1;for(let e=0;e<g;e++){var b=c[e];if(h.$isElementNode(b)){if(!h.$isParagraphNode(b)||0!==b.__indent)return!1;b=b.getChildren();let n=b.length;for(let p=0;p<n;p++)if(!h.$isTextNode(b[e]))return!1}}return!0}exports.$canShowPlaceholder=u;
8
- exports.$canShowPlaceholderCurry=function(c){return()=>u(c)};exports.$findTextIntersectionFromCharacters=function(c,g){var b=c.getFirstChild();c=0;a:for(;null!==b;){if(h.$isElementNode(b)){var e=b.getFirstChild();if(null!==e){b=e;continue}}else if(h.$isTextNode(b)){e=b.getTextContentSize();if(c+e>g)return{node:b,offset:g-c};c+=e}e=b.getNextSibling();if(null!==e)b=e;else{for(b=b.getParent();null!==b;){e=b.getNextSibling();if(null!==e){b=e;continue a}b=b.getParent()}break}}return null};
9
- exports.$isRootTextContentEmpty=r;exports.$isRootTextContentEmptyCurry=function(c,g){return()=>r(c,g)};exports.$rootTextContent=t;
10
- exports.registerLexicalTextEntity=function(c,g,b,e){let n=a=>{const d=h.$createTextNode(a.getTextContent());d.setFormat(a.getFormat());a.replace(d)},p=c.registerNodeTransform(h.TextNode,a=>{if(a.isSimpleText()){var d=a.getPreviousSibling(),l=a.getTextContent(),m=a;if(h.$isTextNode(d)){var k=d.getTextContent(),f=g(k+l);if(d instanceof b){if(null===f||0!==d.getLatest().__mode){n(d);return}f=f.end-k.length;if(0<f){m=l.slice(0,f);m=k+m;d.select();d.setTextContent(m);f===l.length?a.remove():(d=l.slice(f),
11
- a.setTextContent(d));return}}else if(null===f||f.start<k.length)return}for(;;){a=g(l);l=f=null===a?"":l.slice(a.end);if(""===f){if(k=m.getNextSibling(),h.$isTextNode(k))if(f=m.getTextContent()+k.getTextContent(),f=g(f),null===f){k instanceof b?n(k):k.markDirty();break}else if(0!==f.start)break}else if(k=g(f),null!==k&&0===k.start)break;if(null===a)break;if(0===a.start&&h.$isTextNode(d)&&d.isTextEntity())continue;let q;0===a.start?[q,m]=m.splitText(a.end):[,q,m]=m.splitText(a.start,a.end);a=e(q);q.replace(a);
12
- if(null==m)break}}});c=c.registerNodeTransform(b,a=>{var d=a.getTextContent();const l=g(d);null===l||0!==l.start?n(a):d.length>l.end?a.splitText(l.end):(d=a.getPreviousSibling(),h.$isTextNode(d)&&d.isTextEntity()&&(n(d),n(a)),d=a.getNextSibling(),h.$isTextNode(d)&&d.isTextEntity()&&(n(d),a instanceof b&&n(a)))});return[p,c]}
7
+ 'use strict';var g=require("lexical");function r(c,h=!0){if(c)return!1;c=t();h&&(c=c.trim());return""===c}function t(){return g.$getRoot().getTextContent()}function u(c){if(!r(c,!1))return!1;c=g.$getRoot().getChildren();let h=c.length;if(1<h)return!1;for(let e=0;e<h;e++){var a=c[e];if(g.$isDecoratorNode(a))return!1;if(g.$isElementNode(a)){if(!g.$isParagraphNode(a)||0!==a.__indent)return!1;a=a.getChildren();let n=a.length;for(let p=0;p<n;p++)if(!g.$isTextNode(a[e]))return!1}}return!0}
8
+ exports.$canShowPlaceholder=u;exports.$canShowPlaceholderCurry=function(c){return()=>u(c)};exports.$findTextIntersectionFromCharacters=function(c,h){var a=c.getFirstChild();c=0;a:for(;null!==a;){if(g.$isElementNode(a)){var e=a.getFirstChild();if(null!==e){a=e;continue}}else if(g.$isTextNode(a)){e=a.getTextContentSize();if(c+e>h)return{node:a,offset:h-c};c+=e}e=a.getNextSibling();if(null!==e)a=e;else{for(a=a.getParent();null!==a;){e=a.getNextSibling();if(null!==e){a=e;continue a}a=a.getParent()}break}}return null};
9
+ exports.$isRootTextContentEmpty=r;exports.$isRootTextContentEmptyCurry=function(c,h){return()=>r(c,h)};exports.$rootTextContent=t;
10
+ exports.registerLexicalTextEntity=function(c,h,a,e){let n=b=>{const d=g.$createTextNode(b.getTextContent());d.setFormat(b.getFormat());b.replace(d)},p=c.registerNodeTransform(g.TextNode,b=>{if(b.isSimpleText()){var d=b.getPreviousSibling(),l=b.getTextContent(),m=b;if(g.$isTextNode(d)){var k=d.getTextContent(),f=h(k+l);if(d instanceof a){if(null===f||0!==d.getLatest().__mode){n(d);return}f=f.end-k.length;if(0<f){m=l.slice(0,f);m=k+m;d.select();d.setTextContent(m);f===l.length?b.remove():(d=l.slice(f),
11
+ b.setTextContent(d));return}}else if(null===f||f.start<k.length)return}for(;;){b=h(l);l=f=null===b?"":l.slice(b.end);if(""===f){if(k=m.getNextSibling(),g.$isTextNode(k))if(f=m.getTextContent()+k.getTextContent(),f=h(f),null===f){k instanceof a?n(k):k.markDirty();break}else if(0!==f.start)break}else if(k=h(f),null!==k&&0===k.start)break;if(null===b)break;if(0===b.start&&g.$isTextNode(d)&&d.isTextEntity())continue;let q;0===b.start?[q,m]=m.splitText(b.end):[,q,m]=m.splitText(b.start,b.end);b=e(q);q.replace(b);
12
+ if(null==m)break}}});c=c.registerNodeTransform(a,b=>{var d=b.getTextContent();const l=h(d);null===l||0!==l.start?n(b):d.length>l.end?b.splitText(l.end):(d=b.getPreviousSibling(),g.$isTextNode(d)&&d.isTextEntity()&&(n(d),n(b)),d=b.getNextSibling(),g.$isTextNode(d)&&d.isTextEntity()&&(n(d),b instanceof a&&n(b)))});return[p,c]}
package/index.d.ts CHANGED
@@ -12,17 +12,70 @@ export declare type TextNodeWithOffset = {
12
12
  node: TextNode;
13
13
  offset: number;
14
14
  };
15
+ /**
16
+ * Finds a TextNode with a size larger than targetCharacters and returns
17
+ * the node along with the remaining length of the text.
18
+ * @param root - The RootNode.
19
+ * @param targetCharacters - The number of characters whose TextNode must be larger than.
20
+ * @returns The TextNode and the intersections offset, or null if no TextNode is found.
21
+ */
15
22
  export declare function $findTextIntersectionFromCharacters(root: RootNode, targetCharacters: number): null | {
16
23
  node: TextNode;
17
24
  offset: number;
18
25
  };
26
+ /**
27
+ * Determines if the root has any text content and can trim any whitespace if it does.
28
+ * @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
29
+ * @param trim - Should the root text have its whitespaced trimmed? Defaults to true.
30
+ * @returns true if text content is empty, false if there is text or isEditorComposing is true.
31
+ */
19
32
  export declare function $isRootTextContentEmpty(isEditorComposing: boolean, trim?: boolean): boolean;
33
+ /**
34
+ * Returns a function that executes {@link $isRootTextContentEmpty}
35
+ * @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
36
+ * @param trim - Should the root text have its whitespaced trimmed? Defaults to true.
37
+ * @returns A function that executes $isRootTextContentEmpty based on arguments.
38
+ */
20
39
  export declare function $isRootTextContentEmptyCurry(isEditorComposing: boolean, trim?: boolean): () => boolean;
40
+ /**
41
+ * Returns the root's text content.
42
+ * @returns The root's text content.
43
+ */
21
44
  export declare function $rootTextContent(): string;
45
+ /**
46
+ * Determines if the input should show the placeholder. If anything is in
47
+ * in the root the placeholder should not be shown.
48
+ * @param isComposing - Is the editor in composition mode due to an active Input Method Editor?
49
+ * @returns true if the input should show the placeholder, false otherwise.
50
+ */
22
51
  export declare function $canShowPlaceholder(isComposing: boolean): boolean;
52
+ /**
53
+ * Returns a function that executes {@link $canShowPlaceholder}
54
+ * @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
55
+ * @returns A function that executes $canShowPlaceholder with arguments.
56
+ */
23
57
  export declare function $canShowPlaceholderCurry(isEditorComposing: boolean): () => boolean;
24
58
  export declare type EntityMatch = {
25
59
  end: number;
26
60
  start: number;
27
61
  };
62
+ /**
63
+ * Returns a touple that can be rested (...) into mergeRegister to clean up
64
+ * node transforms listeners that transforms text into another node, eg. a HashtagNode.
65
+ * @example
66
+ * ```ts
67
+ * useEffect(() => {
68
+ return mergeRegister(
69
+ ...registerLexicalTextEntity(editor, getMatch, targetNode, createNode),
70
+ );
71
+ }, [createNode, editor, getMatch, targetNode]);
72
+ * ```
73
+ * Where targetNode is the type of node containing the text you want to transform (like a text input),
74
+ * then getMatch uses a regex to find a matching text and creates the proper node to include the matching text.
75
+ * @param editor - The lexical editor.
76
+ * @param getMatch - Finds a matching string that satisfies a regex expression.
77
+ * @param targetNode - The node type that contains text to match with. eg. HashtagNode
78
+ * @param createNode - A function that creates a new node to contain the matched text. eg createHashtagNode
79
+ * @returns An array containing the plain text and reverse node transform listeners.
80
+ */
28
81
  export declare function registerLexicalTextEntity<T extends TextNode>(editor: LexicalEditor, getMatch: (text: string) => null | EntityMatch, targetNode: Klass<T>, createNode: (textNode: TextNode) => T): Array<() => void>;
package/package.json CHANGED
@@ -9,10 +9,10 @@
9
9
  "text"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "0.9.0",
12
+ "version": "0.9.2",
13
13
  "main": "LexicalText.js",
14
14
  "peerDependencies": {
15
- "lexical": "0.9.0"
15
+ "lexical": "0.9.2"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",