@lexical/text 0.9.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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",