@fluentui-copilot/chat-input-plugins 0.0.3 → 0.0.4

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 (38) hide show
  1. package/CHANGELOG.json +22 -1
  2. package/CHANGELOG.md +12 -2
  3. package/dist/index.d.ts +18 -1
  4. package/lib/BasicFunctionality/BasicFunctionality.base.js +99 -8
  5. package/lib/BasicFunctionality/BasicFunctionality.base.js.map +1 -1
  6. package/lib/BasicFunctionality/SentinelNode.js +24 -0
  7. package/lib/BasicFunctionality/SentinelNode.js.map +1 -0
  8. package/lib/BasicFunctionality/index.js +1 -0
  9. package/lib/BasicFunctionality/index.js.map +1 -1
  10. package/lib/ChatInputEntity/ChatInputEntityPlugin.base.js.map +1 -1
  11. package/lib/ChatInputEntity/ChatInputEntityPlugin.types.js.map +1 -1
  12. package/lib/ChatInputEntity/index.js.map +1 -1
  13. package/lib/GhostText/GhostText.base.js.map +1 -1
  14. package/lib/GhostText/index.js.map +1 -1
  15. package/lib/ImperativeControl/ImperativeControl.base.js.map +1 -1
  16. package/lib/ImperativeControl/index.js.map +1 -1
  17. package/lib/ManualGhostText/ManualGhostText.base.js.map +1 -1
  18. package/lib/ManualGhostText/index.js.map +1 -1
  19. package/lib/index.js +1 -1
  20. package/lib/index.js.map +1 -1
  21. package/lib-commonjs/BasicFunctionality/BasicFunctionality.base.js +95 -7
  22. package/lib-commonjs/BasicFunctionality/BasicFunctionality.base.js.map +1 -1
  23. package/lib-commonjs/BasicFunctionality/SentinelNode.js +44 -0
  24. package/lib-commonjs/BasicFunctionality/SentinelNode.js.map +1 -0
  25. package/lib-commonjs/BasicFunctionality/index.js +1 -0
  26. package/lib-commonjs/BasicFunctionality/index.js.map +1 -1
  27. package/lib-commonjs/ChatInputEntity/ChatInputEntityPlugin.base.js.map +1 -1
  28. package/lib-commonjs/ChatInputEntity/ChatInputEntityPlugin.types.js.map +1 -1
  29. package/lib-commonjs/ChatInputEntity/index.js.map +1 -1
  30. package/lib-commonjs/GhostText/GhostText.base.js.map +1 -1
  31. package/lib-commonjs/GhostText/index.js.map +1 -1
  32. package/lib-commonjs/ImperativeControl/ImperativeControl.base.js.map +1 -1
  33. package/lib-commonjs/ImperativeControl/index.js.map +1 -1
  34. package/lib-commonjs/ManualGhostText/ManualGhostText.base.js.map +1 -1
  35. package/lib-commonjs/ManualGhostText/index.js.map +1 -1
  36. package/lib-commonjs/index.js +9 -0
  37. package/lib-commonjs/index.js.map +1 -1
  38. package/package.json +2 -2
package/CHANGELOG.json CHANGED
@@ -2,7 +2,28 @@
2
2
  "name": "@fluentui-copilot/chat-input-plugins",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 18 Apr 2024 00:27:52 GMT",
5
+ "date": "Tue, 30 Apr 2024 20:54:47 GMT",
6
+ "tag": "@fluentui-copilot/chat-input-plugins_v0.0.4",
7
+ "version": "0.0.4",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "author": "owcampbe@microsoft.com",
12
+ "package": "@fluentui-copilot/chat-input-plugins",
13
+ "commit": "f2067016fa67e0718cb2c309338ab4376d256cd4",
14
+ "comment": "feat: Add onPaste to BasicFunctionalityPlugin."
15
+ },
16
+ {
17
+ "author": "owcampbe@microsoft.com",
18
+ "package": "@fluentui-copilot/chat-input-plugins",
19
+ "commit": "3483acc61611eefb8dc8a66e21c4d71e74e73674",
20
+ "comment": "fix: Add invisible sentinel node to ChatInput to fix cursor issues."
21
+ }
22
+ ]
23
+ }
24
+ },
25
+ {
26
+ "date": "Thu, 18 Apr 2024 00:28:05 GMT",
6
27
  "tag": "@fluentui-copilot/chat-input-plugins_v0.0.3",
7
28
  "version": "0.0.3",
8
29
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,22 @@
1
1
  # Change Log - @fluentui-copilot/chat-input-plugins
2
2
 
3
- This log was last generated on Thu, 18 Apr 2024 00:27:52 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 30 Apr 2024 20:54:47 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [0.0.4](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/chat-input-plugins_v0.0.4)
8
+
9
+ Tue, 30 Apr 2024 20:54:47 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/chat-input-plugins_v0.0.3..@fluentui-copilot/chat-input-plugins_v0.0.4)
11
+
12
+ ### Patches
13
+
14
+ - feat: Add onPaste to BasicFunctionalityPlugin. ([PR #1556](https://github.com/microsoft/fluentai/pull/1556) by owcampbe@microsoft.com)
15
+ - fix: Add invisible sentinel node to ChatInput to fix cursor issues. ([PR #1599](https://github.com/microsoft/fluentai/pull/1599) by owcampbe@microsoft.com)
16
+
7
17
  ## [0.0.3](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/chat-input-plugins_v0.0.3)
8
18
 
9
- Thu, 18 Apr 2024 00:27:52 GMT
19
+ Thu, 18 Apr 2024 00:28:05 GMT
10
20
  [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/chat-input-plugins_v0.0.2..@fluentui-copilot/chat-input-plugins_v0.0.3)
11
21
 
12
22
  ### Patches
package/dist/index.d.ts CHANGED
@@ -3,17 +3,25 @@ import { Klass } from 'lexical';
3
3
  import { LexicalEditor } from 'lexical';
4
4
  import { LexicalNode } from 'lexical';
5
5
  import { NodeKey } from 'lexical';
6
+ import { TextNode } from 'lexical';
7
+
8
+ export declare function $createSentinelNode(key?: NodeKey): SentinelNode;
9
+
10
+ export declare function $isSentinelNode(node: LexicalNode | null): node is SentinelNode;
6
11
 
7
12
  export declare class BasicFunctionalityBase implements IBasicFunctionalityBase {
8
13
  private __editor;
9
14
  private __contentChangeCleanup?;
10
15
  private __trimWhitespaceCleanup?;
11
- private __enterHandlerCleanup?;
16
+ private __baseHandlersCleanup?;
17
+ private __pasteHandlerCleanup?;
12
18
  private __enterHandler;
13
19
  constructor(editor: LexicalEditor);
14
20
  insertDefaultValue(defaultValue: string): void;
15
21
  activateContentCallbacks(onContentChange?: ((value: string) => void) | undefined, onCountChanged?: ((count: number) => void) | undefined): void;
16
22
  deactivateContentCallbacks(): void;
23
+ activatePasteCallback(onPaste: (event: ClipboardEvent) => void): void;
24
+ deactivatePasteCallback(): void;
17
25
  activateTrimWhitespace(): void;
18
26
  deactivateTrimWhitespace(): void;
19
27
  setIsDisabled(isDisabled: boolean): void;
@@ -71,6 +79,8 @@ export declare interface IBasicFunctionalityBase {
71
79
  deactivateContentCallbacks(): void;
72
80
  activateTrimWhitespace(): void;
73
81
  deactivateTrimWhitespace(): void;
82
+ activatePasteCallback(onPaste: (event: ClipboardEvent) => void): void;
83
+ deactivatePasteCallback(): void;
74
84
  cleanup(): void;
75
85
  }
76
86
 
@@ -140,4 +150,11 @@ export declare class ManualGhostTextBase<ComponentPropsType> {
140
150
  cancelGhostText(): void;
141
151
  }
142
152
 
153
+ export declare class SentinelNode extends TextNode {
154
+ constructor(key?: NodeKey);
155
+ static getType(): string;
156
+ static clone(node: SentinelNode): SentinelNode;
157
+ isToken(): boolean;
158
+ }
159
+
143
160
  export { }
@@ -1,5 +1,6 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import { $createTextNode, $getRoot, $getSelection, $insertNodes, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, INSERT_PARAGRAPH_COMMAND, KEY_ENTER_COMMAND } from '@fluentui-copilot/text-editor';
2
+ import { $createTextNode, $getLeafNodes, $getRoot, $getSelection, $insertNodes, $isRangeSelection, $normalizeSelection__EXPERIMENTAL, $setSelection, COMMAND_PRIORITY_CRITICAL, INSERT_PARAGRAPH_COMMAND, KEY_ENTER_COMMAND, PASTE_COMMAND, mergeRegister } from '@fluentui-copilot/text-editor';
3
+ import { $createSentinelNode, $isSentinelNode, SentinelNode } from './SentinelNode';
3
4
  export class BasicFunctionalityBase {
4
5
  __enterHandler(event) {
5
6
  const selection = $getSelection();
@@ -26,8 +27,10 @@ export class BasicFunctionalityBase {
26
27
  activateContentCallbacks(onContentChange, onCountChanged) {
27
28
  this.deactivateContentCallbacks();
28
29
  this.__contentChangeCleanup = this.__editor.registerTextContentListener(text => {
29
- onContentChange === null || onContentChange === void 0 ? void 0 : onContentChange(text);
30
- onCountChanged === null || onCountChanged === void 0 ? void 0 : onCountChanged(text.length);
30
+ // Remove the sentinel node
31
+ const processed = text.replace('\u200b\u200c', '');
32
+ onContentChange === null || onContentChange === void 0 ? void 0 : onContentChange(processed);
33
+ onCountChanged === null || onCountChanged === void 0 ? void 0 : onCountChanged(processed.length);
31
34
  });
32
35
  }
33
36
  deactivateContentCallbacks() {
@@ -35,6 +38,20 @@ export class BasicFunctionalityBase {
35
38
  (_this___contentChangeCleanup = (_this = this).__contentChangeCleanup) === null || _this___contentChangeCleanup === void 0 ? void 0 : _this___contentChangeCleanup.call(_this);
36
39
  this.__contentChangeCleanup = undefined;
37
40
  }
41
+ activatePasteCallback(onPaste) {
42
+ this.__pasteHandlerCleanup = this.__editor.registerCommand(PASTE_COMMAND, event => {
43
+ onPaste(event);
44
+ if (event.defaultPrevented) {
45
+ return true;
46
+ }
47
+ return false;
48
+ }, COMMAND_PRIORITY_CRITICAL);
49
+ }
50
+ deactivatePasteCallback() {
51
+ var _this___pasteHandlerCleanup, _this;
52
+ (_this___pasteHandlerCleanup = (_this = this).__pasteHandlerCleanup) === null || _this___pasteHandlerCleanup === void 0 ? void 0 : _this___pasteHandlerCleanup.call(_this);
53
+ this.__pasteHandlerCleanup = undefined;
54
+ }
38
55
  activateTrimWhitespace() {
39
56
  this.deactivateTrimWhitespace();
40
57
  this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener(text => {
@@ -60,19 +77,93 @@ export class BasicFunctionalityBase {
60
77
  this.__editor.setEditable(!isDisabled);
61
78
  }
62
79
  cleanup() {
63
- var _this___enterHandlerCleanup, _this;
80
+ var _this___baseHandlersCleanup, _this;
64
81
  this.deactivateContentCallbacks();
65
82
  this.deactivateTrimWhitespace();
66
- (_this___enterHandlerCleanup = (_this = this).__enterHandlerCleanup) === null || _this___enterHandlerCleanup === void 0 ? void 0 : _this___enterHandlerCleanup.call(_this);
67
- this.__enterHandlerCleanup = undefined;
83
+ this.deactivatePasteCallback();
84
+ (_this___baseHandlersCleanup = (_this = this).__baseHandlersCleanup) === null || _this___baseHandlersCleanup === void 0 ? void 0 : _this___baseHandlersCleanup.call(_this);
85
+ this.__baseHandlersCleanup = undefined;
68
86
  }
69
87
  constructor(editor) {
70
88
  _define_property(this, "__editor", void 0);
71
89
  _define_property(this, "__contentChangeCleanup", void 0);
72
90
  _define_property(this, "__trimWhitespaceCleanup", void 0);
73
- _define_property(this, "__enterHandlerCleanup", void 0);
91
+ _define_property(this, "__baseHandlersCleanup", void 0);
92
+ _define_property(this, "__pasteHandlerCleanup", void 0);
74
93
  this.__editor = editor;
75
- this.__enterHandlerCleanup = this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_CRITICAL);
94
+ this.__baseHandlersCleanup = mergeRegister(this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_CRITICAL),
95
+ // Add a sentinel node at the end of the input when there is content.
96
+ // This sentinel node fixes a number of issues.
97
+ // In Safari, Lexical's behaviour of adding <br /> tags to the end of the input when it ends
98
+ // in a decorator node causes cursor location issues: https://github.com/facebook/lexical/issues/4487
99
+ // Otherwise, when a decorator node is the last node in the input, the cursor can't move past it.
100
+ // Adding an invisible text node that doesn't contribute to the content and can't be selected to the end of the input
101
+ // mitigates these issues.
102
+ this.__editor.registerUpdateListener(({
103
+ editorState
104
+ }) => {
105
+ editorState.read(() => {
106
+ const leaves = $getLeafNodes($getRoot());
107
+ if (leaves.length === 0) {
108
+ return;
109
+ }
110
+ const sentinel = leaves[leaves.length - 1];
111
+ // If the last node isn't a sentinel, add one
112
+ if (!$isSentinelNode(sentinel)) {
113
+ this.__editor.update(() => {
114
+ sentinel.insertAfter($createSentinelNode());
115
+ }, {
116
+ discrete: true
117
+ });
118
+ return;
119
+ }
120
+ // If the sentinel node is not selected, we're done
121
+ const previous = sentinel.getPreviousSibling();
122
+ if (!previous || !sentinel.isSelected()) {
123
+ return;
124
+ }
125
+ const selection = $getSelection();
126
+ if (!$isRangeSelection(selection)) {
127
+ return;
128
+ }
129
+ // If the cursor is inside the sentinel node, move it out (next to the beginning)
130
+ // We allow selection on the boundary of the sentinel in case the adjacent node is a decorator node
131
+ // where selection is ill-defined.
132
+ if (selection.isCollapsed() && selection.anchor.offset > 0) {
133
+ this.__editor.update(() => {
134
+ sentinel.selectStart();
135
+ }, {
136
+ discrete: true
137
+ });
138
+ return;
139
+ }
140
+ // If the selection is a range which includes the sentinel, modify the range to exclude it
141
+ if (!selection.isCollapsed()) {
142
+ let selectionChanged = false;
143
+ const newSelection = selection.clone();
144
+ if (newSelection.anchor.getNode() === sentinel && newSelection.anchor.offset > 0) {
145
+ newSelection.anchor.set(sentinel.getKey(), 0, 'text');
146
+ selectionChanged = true;
147
+ }
148
+ if (newSelection.focus.getNode() === sentinel && newSelection.focus.offset > 0) {
149
+ newSelection.focus.set(sentinel.getKey(), 0, 'text');
150
+ selectionChanged = true;
151
+ }
152
+ if (selectionChanged) {
153
+ this.__editor.update(() => {
154
+ $setSelection($normalizeSelection__EXPERIMENTAL(newSelection));
155
+ }, {
156
+ discrete: true
157
+ });
158
+ }
159
+ }
160
+ });
161
+ }), this.__editor.registerNodeTransform(SentinelNode, node => {
162
+ if (!node.getPreviousSibling() || node.getNextSibling()) {
163
+ node.remove();
164
+ return;
165
+ }
166
+ }));
76
167
  }
77
168
  }
78
169
  //# sourceMappingURL=BasicFunctionality.base.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["BasicFunctionality.base.ts"],"sourcesContent":["import type { LexicalEditor } from '@fluentui-copilot/text-editor';\nimport {\n $createTextNode,\n $getRoot,\n $getSelection,\n $insertNodes,\n $isRangeSelection,\n COMMAND_PRIORITY_CRITICAL,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ENTER_COMMAND,\n} from '@fluentui-copilot/text-editor';\n\nexport interface IBasicFunctionalityBase {\n insertDefaultValue: (defaultValue: string) => void;\n setIsDisabled: (isDisabled: boolean) => void;\n activateContentCallbacks(onContentChange?: (value: string) => void, onCountChanged?: (count: number) => void): void;\n deactivateContentCallbacks(): void;\n activateTrimWhitespace(): void;\n deactivateTrimWhitespace(): void;\n cleanup(): void;\n}\n\nexport class BasicFunctionalityBase implements IBasicFunctionalityBase {\n private __editor: LexicalEditor;\n private __contentChangeCleanup?: () => void;\n private __trimWhitespaceCleanup?: () => void;\n private __enterHandlerCleanup?: () => void;\n\n private __enterHandler(event: KeyboardEvent) {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return false;\n }\n\n if (event === null) {\n return false;\n }\n\n event.preventDefault();\n\n if (event.shiftKey) {\n return this.__editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined);\n }\n\n // Mark event handled to override default behavior\n return true;\n }\n\n constructor(editor: LexicalEditor) {\n this.__editor = editor;\n\n this.__enterHandlerCleanup = this.__editor.registerCommand(\n KEY_ENTER_COMMAND,\n this.__enterHandler.bind(this),\n COMMAND_PRIORITY_CRITICAL,\n );\n }\n\n insertDefaultValue(defaultValue: string) {\n if (defaultValue) {\n this.__editor.update(() => {\n $insertNodes([$createTextNode(defaultValue)]);\n });\n }\n }\n\n activateContentCallbacks(\n onContentChange?: ((value: string) => void) | undefined,\n onCountChanged?: ((count: number) => void) | undefined,\n ) {\n this.deactivateContentCallbacks();\n this.__contentChangeCleanup = this.__editor.registerTextContentListener(text => {\n onContentChange?.(text);\n onCountChanged?.(text.length);\n });\n }\n\n deactivateContentCallbacks() {\n this.__contentChangeCleanup?.();\n this.__contentChangeCleanup = undefined;\n }\n\n activateTrimWhitespace() {\n this.deactivateTrimWhitespace();\n this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener(text => {\n if (text.trim() === '') {\n this.__editor.update(\n () => {\n $getRoot()\n .getAllTextNodes()\n .forEach(node => {\n node.remove();\n });\n },\n // Don't allow undoing this action\n { tag: 'historic' },\n );\n }\n });\n }\n\n deactivateTrimWhitespace() {\n this.__trimWhitespaceCleanup?.();\n this.__trimWhitespaceCleanup = undefined;\n }\n\n setIsDisabled(isDisabled: boolean) {\n this.__editor.setEditable(!isDisabled);\n }\n\n cleanup() {\n this.deactivateContentCallbacks();\n this.deactivateTrimWhitespace();\n this.__enterHandlerCleanup?.();\n this.__enterHandlerCleanup = undefined;\n }\n}\n"],"names":["$createTextNode","$getRoot","$getSelection","$insertNodes","$isRangeSelection","COMMAND_PRIORITY_CRITICAL","INSERT_PARAGRAPH_COMMAND","KEY_ENTER_COMMAND","BasicFunctionalityBase","__enterHandler","event","selection","preventDefault","shiftKey","__editor","dispatchCommand","undefined","insertDefaultValue","defaultValue","update","activateContentCallbacks","onContentChange","onCountChanged","deactivateContentCallbacks","__contentChangeCleanup","registerTextContentListener","text","length","activateTrimWhitespace","deactivateTrimWhitespace","__trimWhitespaceCleanup","trim","getAllTextNodes","forEach","node","remove","tag","setIsDisabled","isDisabled","setEditable","cleanup","__enterHandlerCleanup","constructor","editor","registerCommand","bind"],"mappings":";AACA,SACEA,eAAe,EACfC,QAAQ,EACRC,aAAa,EACbC,YAAY,EACZC,iBAAiB,EACjBC,yBAAyB,EACzBC,wBAAwB,EACxBC,iBAAiB,QACZ,gCAAgC;AAYvC,OAAO,MAAMC;IAMHC,eAAeC,KAAoB,EAAE;QAC3C,MAAMC,YAAYT;QAClB,IAAI,CAACE,kBAAkBO,YAAY;YACjC,OAAO;QACT;QAEA,IAAID,UAAU,MAAM;YAClB,OAAO;QACT;QAEAA,MAAME,cAAc;QAEpB,IAAIF,MAAMG,QAAQ,EAAE;YAClB,OAAO,IAAI,CAACC,QAAQ,CAACC,eAAe,CAACT,0BAA0BU;QACjE;QAEA,kDAAkD;QAClD,OAAO;IACT;IAYAC,mBAAmBC,YAAoB,EAAE;QACvC,IAAIA,cAAc;YAChB,IAAI,CAACJ,QAAQ,CAACK,MAAM,CAAC;gBACnBhB,aAAa;oBAACH,gBAAgBkB;iBAAc;YAC9C;QACF;IACF;IAEAE,yBACEC,eAAuD,EACvDC,cAAsD,EACtD;QACA,IAAI,CAACC,0BAA0B;QAC/B,IAAI,CAACC,sBAAsB,GAAG,IAAI,CAACV,QAAQ,CAACW,2BAA2B,CAACC,CAAAA;YACtEL,4BAAAA,sCAAAA,gBAAkBK;YAClBJ,2BAAAA,qCAAAA,eAAiBI,KAAKC,MAAM;QAC9B;IACF;IAEAJ,6BAA6B;YAC3B,8BAAA;SAAA,+BAAA,CAAA,QAAA,IAAI,EAACC,sBAAsB,cAA3B,mDAAA,kCAAA;QACA,IAAI,CAACA,sBAAsB,GAAGR;IAChC;IAEAY,yBAAyB;QACvB,IAAI,CAACC,wBAAwB;QAC7B,IAAI,CAACC,uBAAuB,GAAG,IAAI,CAAChB,QAAQ,CAACW,2BAA2B,CAACC,CAAAA;YACvE,IAAIA,KAAKK,IAAI,OAAO,IAAI;gBACtB,IAAI,CAACjB,QAAQ,CAACK,MAAM,CAClB;oBACElB,WACG+B,eAAe,GACfC,OAAO,CAACC,CAAAA;wBACPA,KAAKC,MAAM;oBACb;gBACJ,GACA,kCAAkC;gBAClC;oBAAEC,KAAK;gBAAW;YAEtB;QACF;IACF;IAEAP,2BAA2B;YACzB,+BAAA;SAAA,gCAAA,CAAA,QAAA,IAAI,EAACC,uBAAuB,cAA5B,oDAAA,mCAAA;QACA,IAAI,CAACA,uBAAuB,GAAGd;IACjC;IAEAqB,cAAcC,UAAmB,EAAE;QACjC,IAAI,CAACxB,QAAQ,CAACyB,WAAW,CAAC,CAACD;IAC7B;IAEAE,UAAU;YAGR,6BAAA;QAFA,IAAI,CAACjB,0BAA0B;QAC/B,IAAI,CAACM,wBAAwB;SAC7B,8BAAA,CAAA,QAAA,IAAI,EAACY,qBAAqB,cAA1B,kDAAA,iCAAA;QACA,IAAI,CAACA,qBAAqB,GAAGzB;IAC/B;IAnEA0B,YAAYC,MAAqB,CAAE;QAzBnC,uBAAQ7B,YAAR,KAAA;QACA,uBAAQU,0BAAR,KAAA;QACA,uBAAQM,2BAAR,KAAA;QACA,uBAAQW,yBAAR,KAAA;QAuBE,IAAI,CAAC3B,QAAQ,GAAG6B;QAEhB,IAAI,CAACF,qBAAqB,GAAG,IAAI,CAAC3B,QAAQ,CAAC8B,eAAe,CACxDrC,mBACA,IAAI,CAACE,cAAc,CAACoC,IAAI,CAAC,IAAI,GAC7BxC;IAEJ;AA4DF"}
1
+ {"version":3,"sources":["BasicFunctionality.base.ts"],"sourcesContent":["import type { LexicalEditor } from '@fluentui-copilot/text-editor';\nimport {\n $createTextNode,\n $getLeafNodes,\n $getRoot,\n $getSelection,\n $insertNodes,\n $isRangeSelection,\n $normalizeSelection__EXPERIMENTAL,\n $setSelection,\n COMMAND_PRIORITY_CRITICAL,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\nimport { $createSentinelNode, $isSentinelNode, SentinelNode } from './SentinelNode';\n\nexport interface IBasicFunctionalityBase {\n insertDefaultValue: (defaultValue: string) => void;\n setIsDisabled: (isDisabled: boolean) => void;\n activateContentCallbacks(onContentChange?: (value: string) => void, onCountChanged?: (count: number) => void): void;\n deactivateContentCallbacks(): void;\n activateTrimWhitespace(): void;\n deactivateTrimWhitespace(): void;\n activatePasteCallback(onPaste: (event: ClipboardEvent) => void): void;\n deactivatePasteCallback(): void;\n cleanup(): void;\n}\n\nexport class BasicFunctionalityBase implements IBasicFunctionalityBase {\n private __editor: LexicalEditor;\n private __contentChangeCleanup?: () => void;\n private __trimWhitespaceCleanup?: () => void;\n private __baseHandlersCleanup?: () => void;\n private __pasteHandlerCleanup?: () => void;\n\n private __enterHandler(event: KeyboardEvent) {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return false;\n }\n\n if (event === null) {\n return false;\n }\n\n event.preventDefault();\n\n if (event.shiftKey) {\n return this.__editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined);\n }\n\n // Mark event handled to override default behavior\n return true;\n }\n\n constructor(editor: LexicalEditor) {\n this.__editor = editor;\n\n this.__baseHandlersCleanup = mergeRegister(\n this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_CRITICAL),\n\n // Add a sentinel node at the end of the input when there is content.\n // This sentinel node fixes a number of issues.\n // In Safari, Lexical's behaviour of adding <br /> tags to the end of the input when it ends\n // in a decorator node causes cursor location issues: https://github.com/facebook/lexical/issues/4487\n // Otherwise, when a decorator node is the last node in the input, the cursor can't move past it.\n // Adding an invisible text node that doesn't contribute to the content and can't be selected to the end of the input\n // mitigates these issues.\n this.__editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const leaves = $getLeafNodes($getRoot());\n if (leaves.length === 0) {\n return;\n }\n\n const sentinel = leaves[leaves.length - 1];\n\n // If the last node isn't a sentinel, add one\n if (!$isSentinelNode(sentinel)) {\n this.__editor.update(\n () => {\n sentinel.insertAfter($createSentinelNode());\n },\n { discrete: true },\n );\n return;\n }\n\n // If the sentinel node is not selected, we're done\n const previous = sentinel.getPreviousSibling();\n if (!previous || !sentinel.isSelected()) {\n return;\n }\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n // If the cursor is inside the sentinel node, move it out (next to the beginning)\n // We allow selection on the boundary of the sentinel in case the adjacent node is a decorator node\n // where selection is ill-defined.\n if (selection.isCollapsed() && selection.anchor.offset > 0) {\n this.__editor.update(\n () => {\n sentinel.selectStart();\n },\n { discrete: true },\n );\n return;\n }\n\n // If the selection is a range which includes the sentinel, modify the range to exclude it\n if (!selection.isCollapsed()) {\n let selectionChanged = false;\n const newSelection = selection.clone();\n\n if (newSelection.anchor.getNode() === sentinel && newSelection.anchor.offset > 0) {\n newSelection.anchor.set(sentinel.getKey(), 0, 'text');\n selectionChanged = true;\n }\n if (newSelection.focus.getNode() === sentinel && newSelection.focus.offset > 0) {\n newSelection.focus.set(sentinel.getKey(), 0, 'text');\n selectionChanged = true;\n }\n\n if (selectionChanged) {\n this.__editor.update(\n () => {\n $setSelection($normalizeSelection__EXPERIMENTAL(newSelection));\n },\n { discrete: true },\n );\n }\n }\n });\n }),\n this.__editor.registerNodeTransform(SentinelNode, node => {\n if (!node.getPreviousSibling() || node.getNextSibling()) {\n node.remove();\n return;\n }\n }),\n );\n }\n\n insertDefaultValue(defaultValue: string) {\n if (defaultValue) {\n this.__editor.update(() => {\n $insertNodes([$createTextNode(defaultValue)]);\n });\n }\n }\n\n activateContentCallbacks(\n onContentChange?: ((value: string) => void) | undefined,\n onCountChanged?: ((count: number) => void) | undefined,\n ) {\n this.deactivateContentCallbacks();\n this.__contentChangeCleanup = this.__editor.registerTextContentListener(text => {\n // Remove the sentinel node\n const processed = text.replace('\\u200b\\u200c', '');\n onContentChange?.(processed);\n onCountChanged?.(processed.length);\n });\n }\n\n deactivateContentCallbacks() {\n this.__contentChangeCleanup?.();\n this.__contentChangeCleanup = undefined;\n }\n\n activatePasteCallback(onPaste: (event: ClipboardEvent) => void) {\n this.__pasteHandlerCleanup = this.__editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n onPaste(event);\n\n if (event.defaultPrevented) {\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n }\n\n deactivatePasteCallback() {\n this.__pasteHandlerCleanup?.();\n this.__pasteHandlerCleanup = undefined;\n }\n\n activateTrimWhitespace() {\n this.deactivateTrimWhitespace();\n this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener(text => {\n if (text.trim() === '') {\n this.__editor.update(\n () => {\n $getRoot()\n .getAllTextNodes()\n .forEach(node => {\n node.remove();\n });\n },\n // Don't allow undoing this action\n { tag: 'historic' },\n );\n }\n });\n }\n\n deactivateTrimWhitespace() {\n this.__trimWhitespaceCleanup?.();\n this.__trimWhitespaceCleanup = undefined;\n }\n\n setIsDisabled(isDisabled: boolean) {\n this.__editor.setEditable(!isDisabled);\n }\n\n cleanup() {\n this.deactivateContentCallbacks();\n this.deactivateTrimWhitespace();\n this.deactivatePasteCallback();\n this.__baseHandlersCleanup?.();\n this.__baseHandlersCleanup = undefined;\n }\n}\n"],"names":["$createTextNode","$getLeafNodes","$getRoot","$getSelection","$insertNodes","$isRangeSelection","$normalizeSelection__EXPERIMENTAL","$setSelection","COMMAND_PRIORITY_CRITICAL","INSERT_PARAGRAPH_COMMAND","KEY_ENTER_COMMAND","PASTE_COMMAND","mergeRegister","$createSentinelNode","$isSentinelNode","SentinelNode","BasicFunctionalityBase","__enterHandler","event","selection","preventDefault","shiftKey","__editor","dispatchCommand","undefined","insertDefaultValue","defaultValue","update","activateContentCallbacks","onContentChange","onCountChanged","deactivateContentCallbacks","__contentChangeCleanup","registerTextContentListener","text","processed","replace","length","activatePasteCallback","onPaste","__pasteHandlerCleanup","registerCommand","defaultPrevented","deactivatePasteCallback","activateTrimWhitespace","deactivateTrimWhitespace","__trimWhitespaceCleanup","trim","getAllTextNodes","forEach","node","remove","tag","setIsDisabled","isDisabled","setEditable","cleanup","__baseHandlersCleanup","constructor","editor","bind","registerUpdateListener","editorState","read","leaves","sentinel","insertAfter","discrete","previous","getPreviousSibling","isSelected","isCollapsed","anchor","offset","selectStart","selectionChanged","newSelection","clone","getNode","set","getKey","focus","registerNodeTransform","getNextSibling"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AACA,SACEA,eAAe,EACfC,aAAa,EACbC,QAAQ,EACRC,aAAa,EACbC,YAAY,EACZC,iBAAiB,EACjBC,iCAAiC,EACjCC,aAAa,EACbC,yBAAyB,EACzBC,wBAAwB,EACxBC,iBAAiB,EACjBC,aAAa,EACbC,aAAa,QACR,gCAAgC;AACvC,SAASC,mBAAmB,EAAEC,eAAe,EAAEC,YAAY,QAAQ,iBAAiB;AAcpF,OAAO,MAAMC;IAOHC,eAAeC,KAAoB,EAAE;QAC3C,MAAMC,YAAYhB;QAClB,IAAI,CAACE,kBAAkBc,YAAY;YACjC,OAAO;QACT;QAEA,IAAID,UAAU,MAAM;YAClB,OAAO;QACT;QAEAA,MAAME,cAAc;QAEpB,IAAIF,MAAMG,QAAQ,EAAE;YAClB,OAAO,IAAI,CAACC,QAAQ,CAACC,eAAe,CAACd,0BAA0Be;QACjE;QAEA,kDAAkD;QAClD,OAAO;IACT;IA6FAC,mBAAmBC,YAAoB,EAAE;QACvC,IAAIA,cAAc;YAChB,IAAI,CAACJ,QAAQ,CAACK,MAAM,CAAC;gBACnBvB,aAAa;oBAACJ,gBAAgB0B;iBAAc;YAC9C;QACF;IACF;IAEAE,yBACEC,eAAuD,EACvDC,cAAsD,EACtD;QACA,IAAI,CAACC,0BAA0B;QAC/B,IAAI,CAACC,sBAAsB,GAAG,IAAI,CAACV,QAAQ,CAACW,2BAA2B,CAACC,CAAAA;YACtE,2BAA2B;YAC3B,MAAMC,YAAYD,KAAKE,OAAO,CAAC,gBAAgB;YAC/CP,4BAAAA,sCAAAA,gBAAkBM;YAClBL,2BAAAA,qCAAAA,eAAiBK,UAAUE,MAAM;QACnC;IACF;IAEAN,6BAA6B;YAC3B,8BAAA;SAAA,+BAAA,CAAA,QAAA,IAAI,EAACC,sBAAsB,cAA3B,mDAAA,kCAAA;QACA,IAAI,CAACA,sBAAsB,GAAGR;IAChC;IAEAc,sBAAsBC,OAAwC,EAAE;QAC9D,IAAI,CAACC,qBAAqB,GAAG,IAAI,CAAClB,QAAQ,CAACmB,eAAe,CACxD9B,eACA,CAACO;YACCqB,QAAQrB;YAER,IAAIA,MAAMwB,gBAAgB,EAAE;gBAC1B,OAAO;YACT;YAEA,OAAO;QACT,GACAlC;IAEJ;IAEAmC,0BAA0B;YACxB,6BAAA;SAAA,8BAAA,CAAA,QAAA,IAAI,EAACH,qBAAqB,cAA1B,kDAAA,iCAAA;QACA,IAAI,CAACA,qBAAqB,GAAGhB;IAC/B;IAEAoB,yBAAyB;QACvB,IAAI,CAACC,wBAAwB;QAC7B,IAAI,CAACC,uBAAuB,GAAG,IAAI,CAACxB,QAAQ,CAACW,2BAA2B,CAACC,CAAAA;YACvE,IAAIA,KAAKa,IAAI,OAAO,IAAI;gBACtB,IAAI,CAACzB,QAAQ,CAACK,MAAM,CAClB;oBACEzB,WACG8C,eAAe,GACfC,OAAO,CAACC,CAAAA;wBACPA,KAAKC,MAAM;oBACb;gBACJ,GACA,kCAAkC;gBAClC;oBAAEC,KAAK;gBAAW;YAEtB;QACF;IACF;IAEAP,2BAA2B;YACzB,+BAAA;SAAA,gCAAA,CAAA,QAAA,IAAI,EAACC,uBAAuB,cAA5B,oDAAA,mCAAA;QACA,IAAI,CAACA,uBAAuB,GAAGtB;IACjC;IAEA6B,cAAcC,UAAmB,EAAE;QACjC,IAAI,CAAChC,QAAQ,CAACiC,WAAW,CAAC,CAACD;IAC7B;IAEAE,UAAU;YAIR,6BAAA;QAHA,IAAI,CAACzB,0BAA0B;QAC/B,IAAI,CAACc,wBAAwB;QAC7B,IAAI,CAACF,uBAAuB;SAC5B,8BAAA,CAAA,QAAA,IAAI,EAACc,qBAAqB,cAA1B,kDAAA,iCAAA;QACA,IAAI,CAACA,qBAAqB,GAAGjC;IAC/B;IA5KAkC,YAAYC,MAAqB,CAAE;QA1BnC,uBAAQrC,YAAR,KAAA;QACA,uBAAQU,0BAAR,KAAA;QACA,uBAAQc,2BAAR,KAAA;QACA,uBAAQW,yBAAR,KAAA;QACA,uBAAQjB,yBAAR,KAAA;QAuBE,IAAI,CAAClB,QAAQ,GAAGqC;QAEhB,IAAI,CAACF,qBAAqB,GAAG7C,cAC3B,IAAI,CAACU,QAAQ,CAACmB,eAAe,CAAC/B,mBAAmB,IAAI,CAACO,cAAc,CAAC2C,IAAI,CAAC,IAAI,GAAGpD,4BAEjF,qEAAqE;QACrE,+CAA+C;QAC/C,4FAA4F;QAC5F,qGAAqG;QACrG,iGAAiG;QACjG,qHAAqH;QACrH,0BAA0B;QAC1B,IAAI,CAACc,QAAQ,CAACuC,sBAAsB,CAAC,CAAC,EAAEC,WAAW,EAAE;YACnDA,YAAYC,IAAI,CAAC;gBACf,MAAMC,SAAS/D,cAAcC;gBAC7B,IAAI8D,OAAO3B,MAAM,KAAK,GAAG;oBACvB;gBACF;gBAEA,MAAM4B,WAAWD,MAAM,CAACA,OAAO3B,MAAM,GAAG,EAAE;gBAE1C,6CAA6C;gBAC7C,IAAI,CAACvB,gBAAgBmD,WAAW;oBAC9B,IAAI,CAAC3C,QAAQ,CAACK,MAAM,CAClB;wBACEsC,SAASC,WAAW,CAACrD;oBACvB,GACA;wBAAEsD,UAAU;oBAAK;oBAEnB;gBACF;gBAEA,mDAAmD;gBACnD,MAAMC,WAAWH,SAASI,kBAAkB;gBAC5C,IAAI,CAACD,YAAY,CAACH,SAASK,UAAU,IAAI;oBACvC;gBACF;gBAEA,MAAMnD,YAAYhB;gBAClB,IAAI,CAACE,kBAAkBc,YAAY;oBACjC;gBACF;gBAEA,iFAAiF;gBACjF,mGAAmG;gBACnG,kCAAkC;gBAClC,IAAIA,UAAUoD,WAAW,MAAMpD,UAAUqD,MAAM,CAACC,MAAM,GAAG,GAAG;oBAC1D,IAAI,CAACnD,QAAQ,CAACK,MAAM,CAClB;wBACEsC,SAASS,WAAW;oBACtB,GACA;wBAAEP,UAAU;oBAAK;oBAEnB;gBACF;gBAEA,0FAA0F;gBAC1F,IAAI,CAAChD,UAAUoD,WAAW,IAAI;oBAC5B,IAAII,mBAAmB;oBACvB,MAAMC,eAAezD,UAAU0D,KAAK;oBAEpC,IAAID,aAAaJ,MAAM,CAACM,OAAO,OAAOb,YAAYW,aAAaJ,MAAM,CAACC,MAAM,GAAG,GAAG;wBAChFG,aAAaJ,MAAM,CAACO,GAAG,CAACd,SAASe,MAAM,IAAI,GAAG;wBAC9CL,mBAAmB;oBACrB;oBACA,IAAIC,aAAaK,KAAK,CAACH,OAAO,OAAOb,YAAYW,aAAaK,KAAK,CAACR,MAAM,GAAG,GAAG;wBAC9EG,aAAaK,KAAK,CAACF,GAAG,CAACd,SAASe,MAAM,IAAI,GAAG;wBAC7CL,mBAAmB;oBACrB;oBAEA,IAAIA,kBAAkB;wBACpB,IAAI,CAACrD,QAAQ,CAACK,MAAM,CAClB;4BACEpB,cAAcD,kCAAkCsE;wBAClD,GACA;4BAAET,UAAU;wBAAK;oBAErB;gBACF;YACF;QACF,IACA,IAAI,CAAC7C,QAAQ,CAAC4D,qBAAqB,CAACnE,cAAcmC,CAAAA;YAChD,IAAI,CAACA,KAAKmB,kBAAkB,MAAMnB,KAAKiC,cAAc,IAAI;gBACvDjC,KAAKC,MAAM;gBACX;YACF;QACF;IAEJ;AAoFF"}
@@ -0,0 +1,24 @@
1
+ import { TextNode } from '@fluentui-copilot/text-editor';
2
+ export class SentinelNode extends TextNode {
3
+ static getType() {
4
+ return 'sentinel';
5
+ }
6
+ static clone(node) {
7
+ return new SentinelNode(node.__key);
8
+ }
9
+ isToken() {
10
+ return true;
11
+ }
12
+ constructor(key) {
13
+ // 2 zero width characters will not be visible in the editor.
14
+ // These also happen to be markers for CIQ to ignore the following content.
15
+ super('\u200b\u200c', key);
16
+ }
17
+ }
18
+ export function $createSentinelNode(key) {
19
+ return new SentinelNode(key);
20
+ }
21
+ export function $isSentinelNode(node) {
22
+ return node instanceof SentinelNode;
23
+ }
24
+ //# sourceMappingURL=SentinelNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["SentinelNode.ts"],"sourcesContent":["import type { LexicalNode, NodeKey } from '@fluentui-copilot/text-editor';\nimport { TextNode } from '@fluentui-copilot/text-editor';\n\nexport class SentinelNode extends TextNode {\n constructor(key?: NodeKey) {\n // 2 zero width characters will not be visible in the editor.\n // These also happen to be markers for CIQ to ignore the following content.\n super('\\u200b\\u200c', key);\n }\n\n static getType() {\n return 'sentinel';\n }\n static clone(node: SentinelNode) {\n return new SentinelNode(node.__key);\n }\n\n isToken() {\n return true;\n }\n}\n\nexport function $createSentinelNode(key?: NodeKey) {\n return new SentinelNode(key);\n}\n\nexport function $isSentinelNode(node: LexicalNode | null): node is SentinelNode {\n return node instanceof SentinelNode;\n}\n"],"names":["TextNode","SentinelNode","getType","clone","node","__key","isToken","constructor","key","$createSentinelNode","$isSentinelNode"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;","mappings":"AACA,SAASA,QAAQ,QAAQ,gCAAgC;AAEzD,OAAO,MAAMC,qBAAqBD;IAOhC,OAAOE,UAAU;QACf,OAAO;IACT;IACA,OAAOC,MAAMC,IAAkB,EAAE;QAC/B,OAAO,IAAIH,aAAaG,KAAKC,KAAK;IACpC;IAEAC,UAAU;QACR,OAAO;IACT;IAfAC,YAAYC,GAAa,CAAE;QACzB,6DAA6D;QAC7D,2EAA2E;QAC3E,KAAK,CAAC,gBAAgBA;IACxB;AAYF;AAEA,OAAO,SAASC,oBAAoBD,GAAa;IAC/C,OAAO,IAAIP,aAAaO;AAC1B;AAEA,OAAO,SAASE,gBAAgBN,IAAwB;IACtD,OAAOA,gBAAgBH;AACzB"}
@@ -1,2 +1,3 @@
1
1
  export * from './BasicFunctionality.base';
2
+ export * from './SentinelNode';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './BasicFunctionality.base';\n"],"names":[],"mappings":"AAAA,cAAc,4BAA4B"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './BasicFunctionality.base';\nexport * from './SentinelNode';\n"],"names":[],"rangeMappings":";","mappings":"AAAA,cAAc,4BAA4B;AAC1C,cAAc,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ChatInputEntityPlugin.base.ts"],"sourcesContent":["import type { LexicalEditor, LexicalNode, NodeKey, Klass } from '@fluentui-copilot/text-editor';\nimport {\n $createParagraphNode,\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $insertNodes,\n $isDecoratorNode,\n $isRangeSelection,\n $isRootOrShadowRoot,\n $nodesOfType,\n $wrapNodeInElement,\n COMMAND_PRIORITY_CRITICAL,\n DELETE_CHARACTER_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\nimport type { ChatInputEntityData, IChatInputEntityPluginBase, IEntityNode } from './ChatInputEntityPlugin.types';\n\nexport class ChatInputEntityPluginBase<\n ExtraDataType,\n NodePropsType,\n NodeType extends IEntityNode<ExtraDataType, NodePropsType>,\n> implements IChatInputEntityPluginBase<ExtraDataType, NodePropsType>\n{\n private __nodeClass: Klass<NodeType>;\n private __editor: LexicalEditor;\n private __id: string;\n\n private __deleteDirection: 'forward' | 'backward' | null = null;\n private __$createNode: (\n pluginId: string,\n text: string,\n data?: ExtraDataType,\n entityProps?: NodePropsType,\n key?: NodeKey,\n ) => NodeType;\n\n private _cleanup: () => void;\n\n cleanup() {\n this._cleanup();\n }\n\n constructor(\n editor: LexicalEditor,\n id: string,\n nodeClass: Klass<NodeType>,\n $createNode: (\n pluginId: string,\n text: string,\n data?: ExtraDataType,\n entityProps?: NodePropsType,\n key?: NodeKey,\n ) => NodeType,\n $isChatInputEntityNode: (node: LexicalNode | null) => node is NodeType,\n onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void,\n onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void,\n ) {\n this.__$createNode = $createNode;\n this.__editor = editor;\n this.__id = id;\n this.__nodeClass = nodeClass;\n\n this._cleanup = mergeRegister(\n // Keep track of delete direction so we know where to put the selection after adding back a space\n editor.registerCommand(\n DELETE_CHARACTER_COMMAND,\n isBackward => {\n this.__deleteDirection = isBackward ? 'backward' : 'forward';\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n ),\n // Always maintain a space before, after, and between entities in order for selection to work properly\n editor.registerNodeTransform(this.__nodeClass, node => {\n const nextSibling = node.getNextSibling();\n if (!nextSibling || $isDecoratorNode(nextSibling)) {\n const selection = $getSelection();\n\n // If selection is between the two nodes, that means the user is trying to delete the space\n // If they deleted to the left, we should move the cursor to the end of the entity\n // If they delete to the right, we should move the cursor to the end of the newly added space\n // This mimics changing the delete into a cursor move action\n const shouldMoveSelection =\n selection &&\n $isRangeSelection(selection) &&\n selection.isCollapsed() &&\n selection.anchor.offset === node.getIndexWithinParent() + 1;\n const text = $createTextNode(' ');\n node.insertAfter(text);\n if (shouldMoveSelection) {\n if (this.__deleteDirection === 'forward') {\n text.selectEnd();\n } else {\n node.selectEnd();\n }\n }\n }\n\n // In the case the entity is the first node, we need a space before it.\n if (!node.getPreviousSibling()) {\n const text = $createTextNode(' ');\n node.insertBefore(text);\n }\n }),\n onChatInputEntityAdded || onChatInputEntityDeleted\n ? editor.registerMutationListener(this.__nodeClass, (nodes, payload) => {\n for (const [nodeKey, mutation] of nodes) {\n if (onChatInputEntityDeleted && mutation === 'destroyed') {\n payload.prevEditorState.read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityDeleted(node.getEntityData());\n }\n });\n } else if (onChatInputEntityAdded && mutation === 'created') {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityAdded(node.getEntityData());\n }\n });\n }\n }\n })\n : noop,\n );\n }\n insertChatInputEntity(props: ChatInputEntityData<ExtraDataType, NodePropsType>): string | undefined {\n let key: string | undefined = undefined;\n this.__editor.update(() => {\n const { text, data, entityProps } = props;\n\n const entityNode = this.__$createNode(this.__id, text, data, entityProps);\n\n $insertNodes([entityNode]);\n entityNode.selectEnd();\n if ($isRootOrShadowRoot(entityNode.getParentOrThrow())) {\n $wrapNodeInElement(entityNode, $createParagraphNode).selectEnd();\n }\n\n key = entityNode.getKey();\n });\n\n return key;\n }\n removeChatInputEntity(\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n ) {\n this.__editor.update(() => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass)\n .filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i))\n .forEach(node => node.remove());\n } else {\n $getNodeByKey(keyOrPredicate)?.remove();\n }\n });\n }\n updateChatInputEntityProps(\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n props:\n | ChatInputEntityData<ExtraDataType, NodePropsType>\n | ((\n oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>,\n ) => ChatInputEntityData<ExtraDataType, NodePropsType>),\n ) {\n const updateNode = (node: NodeType) => {\n const newProps = typeof props === 'function' ? props(node.getEntityData()) : props;\n node.updateEntityData(newProps);\n };\n\n this.__editor.update(\n () => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass)\n .filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i))\n .forEach(updateNode);\n } else {\n const node = $getNodeByKey<NodeType>(keyOrPredicate);\n if (node) {\n updateNode(node);\n }\n }\n },\n { tag: 'historic' },\n );\n }\n\n getActiveEntities(): ChatInputEntityData<ExtraDataType, NodePropsType>[] {\n return this.__editor.getEditorState().read(() =>\n $nodesOfType(this.__nodeClass)\n .filter(node => node.__pluginId === this.__id)\n .map(node => node.getEntityData()),\n );\n }\n}\n\nfunction noop() {\n return;\n}\n"],"names":["$createParagraphNode","$createTextNode","$getNodeByKey","$getSelection","$insertNodes","$isDecoratorNode","$isRangeSelection","$isRootOrShadowRoot","$nodesOfType","$wrapNodeInElement","COMMAND_PRIORITY_CRITICAL","DELETE_CHARACTER_COMMAND","mergeRegister","ChatInputEntityPluginBase","cleanup","_cleanup","insertChatInputEntity","props","key","undefined","__editor","update","text","data","entityProps","entityNode","__$createNode","__id","selectEnd","getParentOrThrow","getKey","removeChatInputEntity","keyOrPredicate","__nodeClass","filter","node","i","__pluginId","getEntityData","forEach","remove","updateChatInputEntityProps","updateNode","newProps","updateEntityData","tag","getActiveEntities","getEditorState","read","map","constructor","editor","id","nodeClass","$createNode","$isChatInputEntityNode","onChatInputEntityAdded","onChatInputEntityDeleted","__deleteDirection","registerCommand","isBackward","registerNodeTransform","nextSibling","getNextSibling","selection","shouldMoveSelection","isCollapsed","anchor","offset","getIndexWithinParent","insertAfter","getPreviousSibling","insertBefore","registerMutationListener","nodes","payload","nodeKey","mutation","prevEditorState","noop"],"mappings":"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"}
1
+ {"version":3,"sources":["ChatInputEntityPlugin.base.ts"],"sourcesContent":["import type { LexicalEditor, LexicalNode, NodeKey, Klass } from '@fluentui-copilot/text-editor';\nimport {\n $createParagraphNode,\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $insertNodes,\n $isDecoratorNode,\n $isRangeSelection,\n $isRootOrShadowRoot,\n $nodesOfType,\n $wrapNodeInElement,\n COMMAND_PRIORITY_CRITICAL,\n DELETE_CHARACTER_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\nimport type { ChatInputEntityData, IChatInputEntityPluginBase, IEntityNode } from './ChatInputEntityPlugin.types';\n\nexport class ChatInputEntityPluginBase<\n ExtraDataType,\n NodePropsType,\n NodeType extends IEntityNode<ExtraDataType, NodePropsType>,\n> implements IChatInputEntityPluginBase<ExtraDataType, NodePropsType>\n{\n private __nodeClass: Klass<NodeType>;\n private __editor: LexicalEditor;\n private __id: string;\n\n private __deleteDirection: 'forward' | 'backward' | null = null;\n private __$createNode: (\n pluginId: string,\n text: string,\n data?: ExtraDataType,\n entityProps?: NodePropsType,\n key?: NodeKey,\n ) => NodeType;\n\n private _cleanup: () => void;\n\n cleanup() {\n this._cleanup();\n }\n\n constructor(\n editor: LexicalEditor,\n id: string,\n nodeClass: Klass<NodeType>,\n $createNode: (\n pluginId: string,\n text: string,\n data?: ExtraDataType,\n entityProps?: NodePropsType,\n key?: NodeKey,\n ) => NodeType,\n $isChatInputEntityNode: (node: LexicalNode | null) => node is NodeType,\n onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void,\n onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void,\n ) {\n this.__$createNode = $createNode;\n this.__editor = editor;\n this.__id = id;\n this.__nodeClass = nodeClass;\n\n this._cleanup = mergeRegister(\n // Keep track of delete direction so we know where to put the selection after adding back a space\n editor.registerCommand(\n DELETE_CHARACTER_COMMAND,\n isBackward => {\n this.__deleteDirection = isBackward ? 'backward' : 'forward';\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n ),\n // Always maintain a space before, after, and between entities in order for selection to work properly\n editor.registerNodeTransform(this.__nodeClass, node => {\n const nextSibling = node.getNextSibling();\n if (!nextSibling || $isDecoratorNode(nextSibling)) {\n const selection = $getSelection();\n\n // If selection is between the two nodes, that means the user is trying to delete the space\n // If they deleted to the left, we should move the cursor to the end of the entity\n // If they delete to the right, we should move the cursor to the end of the newly added space\n // This mimics changing the delete into a cursor move action\n const shouldMoveSelection =\n selection &&\n $isRangeSelection(selection) &&\n selection.isCollapsed() &&\n selection.anchor.offset === node.getIndexWithinParent() + 1;\n const text = $createTextNode(' ');\n node.insertAfter(text);\n if (shouldMoveSelection) {\n if (this.__deleteDirection === 'forward') {\n text.selectEnd();\n } else {\n node.selectEnd();\n }\n }\n }\n\n // In the case the entity is the first node, we need a space before it.\n if (!node.getPreviousSibling()) {\n const text = $createTextNode(' ');\n node.insertBefore(text);\n }\n }),\n onChatInputEntityAdded || onChatInputEntityDeleted\n ? editor.registerMutationListener(this.__nodeClass, (nodes, payload) => {\n for (const [nodeKey, mutation] of nodes) {\n if (onChatInputEntityDeleted && mutation === 'destroyed') {\n payload.prevEditorState.read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityDeleted(node.getEntityData());\n }\n });\n } else if (onChatInputEntityAdded && mutation === 'created') {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityAdded(node.getEntityData());\n }\n });\n }\n }\n })\n : noop,\n );\n }\n insertChatInputEntity(props: ChatInputEntityData<ExtraDataType, NodePropsType>): string | undefined {\n let key: string | undefined = undefined;\n this.__editor.update(() => {\n const { text, data, entityProps } = props;\n\n const entityNode = this.__$createNode(this.__id, text, data, entityProps);\n\n $insertNodes([entityNode]);\n entityNode.selectEnd();\n if ($isRootOrShadowRoot(entityNode.getParentOrThrow())) {\n $wrapNodeInElement(entityNode, $createParagraphNode).selectEnd();\n }\n\n key = entityNode.getKey();\n });\n\n return key;\n }\n removeChatInputEntity(\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n ) {\n this.__editor.update(() => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass)\n .filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i))\n .forEach(node => node.remove());\n } else {\n $getNodeByKey(keyOrPredicate)?.remove();\n }\n });\n }\n updateChatInputEntityProps(\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n props:\n | ChatInputEntityData<ExtraDataType, NodePropsType>\n | ((\n oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>,\n ) => ChatInputEntityData<ExtraDataType, NodePropsType>),\n ) {\n const updateNode = (node: NodeType) => {\n const newProps = typeof props === 'function' ? props(node.getEntityData()) : props;\n node.updateEntityData(newProps);\n };\n\n this.__editor.update(\n () => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass)\n .filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i))\n .forEach(updateNode);\n } else {\n const node = $getNodeByKey<NodeType>(keyOrPredicate);\n if (node) {\n updateNode(node);\n }\n }\n },\n { tag: 'historic' },\n );\n }\n\n getActiveEntities(): ChatInputEntityData<ExtraDataType, NodePropsType>[] {\n return this.__editor.getEditorState().read(() =>\n $nodesOfType(this.__nodeClass)\n .filter(node => node.__pluginId === this.__id)\n .map(node => node.getEntityData()),\n );\n }\n}\n\nfunction noop() {\n return;\n}\n"],"names":["$createParagraphNode","$createTextNode","$getNodeByKey","$getSelection","$insertNodes","$isDecoratorNode","$isRangeSelection","$isRootOrShadowRoot","$nodesOfType","$wrapNodeInElement","COMMAND_PRIORITY_CRITICAL","DELETE_CHARACTER_COMMAND","mergeRegister","ChatInputEntityPluginBase","cleanup","_cleanup","insertChatInputEntity","props","key","undefined","__editor","update","text","data","entityProps","entityNode","__$createNode","__id","selectEnd","getParentOrThrow","getKey","removeChatInputEntity","keyOrPredicate","__nodeClass","filter","node","i","__pluginId","getEntityData","forEach","remove","updateChatInputEntityProps","updateNode","newProps","updateEntityData","tag","getActiveEntities","getEditorState","read","map","constructor","editor","id","nodeClass","$createNode","$isChatInputEntityNode","onChatInputEntityAdded","onChatInputEntityDeleted","__deleteDirection","registerCommand","isBackward","registerNodeTransform","nextSibling","getNextSibling","selection","shouldMoveSelection","isCollapsed","anchor","offset","getIndexWithinParent","insertAfter","getPreviousSibling","insertBefore","registerMutationListener","nodes","payload","nodeKey","mutation","prevEditorState","noop"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ChatInputEntityPlugin.types.ts"],"sourcesContent":["import type { LexicalNode } from '@fluentui-copilot/text-editor';\n\nexport type ChatInputEntityData<ExtraDataType, NodePropsType> = {\n // Represents the string content of the entity that will returned inside the ChatInput's text content\n text: string;\n // Props to pass to the component rendered by the node\n // By default, `text` will be used as the entity's text content.\n // If entityProps contains information for rendering children, that will take priority\n entityProps?: NodePropsType;\n // Optional extra data that can be associated with the entity\n data?: ExtraDataType;\n};\n\nexport type ChatInputEntityPluginProps<ExtraDataType, NodePropsType> = {\n // An identifier for an instance of the ChatInputEntityPlugin\n // Only entities created by this instance of the plugin will be handled by it\n id: string;\n onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n};\n\n/**\n * A lexical node representing an entity should conform to this interface\n */\nexport interface IEntityNode<ExtraDataType, NodePropsType> extends LexicalNode {\n getEntityData: () => ChatInputEntityData<ExtraDataType, NodePropsType>;\n updateEntityData: (data: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n __pluginId: string;\n}\n\nexport interface IChatInputEntityPluginBase<ExtraDataType, NodePropsType> {\n // Inserts a new entity and returns its key, to be used by removeChatInputEntity or updateChatInputEntityProps\n insertChatInputEntity: (props: ChatInputEntityData<ExtraDataType, NodePropsType>) => string | undefined;\n // Removes an entity by its key, or removes all entities that match a predicate function\n removeChatInputEntity: (\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n ) => void;\n // Updates an entity by its key, or removes all entities that match a predicate function\n updateChatInputEntityProps: (\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n props:\n | ChatInputEntityData<ExtraDataType, NodePropsType>\n | ((\n oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>,\n ) => ChatInputEntityData<ExtraDataType, NodePropsType>),\n ) => void;\n getActiveEntities: () => ChatInputEntityData<ExtraDataType, NodePropsType>[];\n}\n"],"names":[],"mappings":"AAAA,WA+CC"}
1
+ {"version":3,"sources":["ChatInputEntityPlugin.types.ts"],"sourcesContent":["import type { LexicalNode } from '@fluentui-copilot/text-editor';\n\nexport type ChatInputEntityData<ExtraDataType, NodePropsType> = {\n // Represents the string content of the entity that will returned inside the ChatInput's text content\n text: string;\n // Props to pass to the component rendered by the node\n // By default, `text` will be used as the entity's text content.\n // If entityProps contains information for rendering children, that will take priority\n entityProps?: NodePropsType;\n // Optional extra data that can be associated with the entity\n data?: ExtraDataType;\n};\n\nexport type ChatInputEntityPluginProps<ExtraDataType, NodePropsType> = {\n // An identifier for an instance of the ChatInputEntityPlugin\n // Only entities created by this instance of the plugin will be handled by it\n id: string;\n onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n};\n\n/**\n * A lexical node representing an entity should conform to this interface\n */\nexport interface IEntityNode<ExtraDataType, NodePropsType> extends LexicalNode {\n getEntityData: () => ChatInputEntityData<ExtraDataType, NodePropsType>;\n updateEntityData: (data: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n __pluginId: string;\n}\n\nexport interface IChatInputEntityPluginBase<ExtraDataType, NodePropsType> {\n // Inserts a new entity and returns its key, to be used by removeChatInputEntity or updateChatInputEntityProps\n insertChatInputEntity: (props: ChatInputEntityData<ExtraDataType, NodePropsType>) => string | undefined;\n // Removes an entity by its key, or removes all entities that match a predicate function\n removeChatInputEntity: (\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n ) => void;\n // Updates an entity by its key, or removes all entities that match a predicate function\n updateChatInputEntityProps: (\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n props:\n | ChatInputEntityData<ExtraDataType, NodePropsType>\n | ((\n oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>,\n ) => ChatInputEntityData<ExtraDataType, NodePropsType>),\n ) => void;\n getActiveEntities: () => ChatInputEntityData<ExtraDataType, NodePropsType>[];\n}\n"],"names":[],"rangeMappings":"","mappings":"AA8BA,WAiBC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ChatInputEntityPlugin.types';\nexport * from './ChatInputEntityPlugin.base';\n"],"names":[],"mappings":"AAAA,cAAc,gCAAgC;AAC9C,cAAc,+BAA+B"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ChatInputEntityPlugin.types';\nexport * from './ChatInputEntityPlugin.base';\n"],"names":[],"rangeMappings":";","mappings":"AAAA,cAAc,gCAAgC;AAC9C,cAAc,+BAA+B"}
@@ -1 +1 @@
1
- {"version":3,"sources":["GhostText.base.ts"],"sourcesContent":["import type { EditorState, Klass, LexicalEditor, LexicalNode, UpdateListener } from '@fluentui-copilot/text-editor';\nimport {\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n KEY_TAB_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\n\nexport type GetGhostTextFunction = (\n editor: LexicalEditor,\n editorState: EditorState,\n prevEditorState: EditorState,\n) => Promise<string | undefined>;\n\nexport interface IGhostTextNode<ComponentPropsType> extends LexicalNode {\n __content: string;\n __id: string;\n __allowCommitting?: boolean;\n __componentProps?: ComponentPropsType;\n __exposeText?: boolean;\n}\n\nexport class GhostTextPluginBase<ComponentPropsType> {\n private __id: string;\n private __$getGhostText: GetGhostTextFunction;\n private __componentProps?: ComponentPropsType;\n private __exposeText?: boolean;\n private __allowCompletion?: boolean;\n\n private __cleanup?: () => void;\n\n cleanup() {\n this.__cleanup?.();\n }\n\n constructor(\n editor: LexicalEditor,\n id: string,\n $getGhostText: GetGhostTextFunction,\n nodeClass: Klass<IGhostTextNode<ComponentPropsType>>,\n createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>,\n componentProps?: ComponentPropsType,\n // Whether or not the ghost text should count as text inside the input for submitting and character count\n exposeText?: boolean,\n allowCompletion?: boolean,\n ) {\n this.__id = id;\n this.__$getGhostText = $getGhostText;\n this.__componentProps = componentProps;\n this.__exposeText = exposeText;\n this.__allowCompletion = allowCompletion;\n\n let ghostTextNodeKey: string | null = null;\n let lastText: string | undefined = undefined;\n let justRemovedGhostText = false;\n\n function $clearGhostText() {\n const ghostTextNode = ghostTextNodeKey !== null ? $getNodeByKey(ghostTextNodeKey) : null;\n ghostTextNodeKey = null;\n lastText = undefined;\n if (ghostTextNode && ghostTextNode.isAttached()) {\n ghostTextNode.remove();\n }\n }\n function handleGhostTextNodeTransform(node: IGhostTextNode<ComponentPropsType>) {\n const key = node.getKey();\n\n if (node.__id === id && key !== ghostTextNodeKey) {\n // Only one ghost text\n node.remove();\n $clearGhostText();\n }\n }\n\n const handleGhostTextResponse = (text?: string) => {\n if (text === lastText) {\n return;\n }\n\n editor.update(\n () => {\n $clearGhostText();\n\n const selection = $getSelection();\n if (!text || !selection) {\n justRemovedGhostText = true;\n return;\n }\n\n const selectionCopy = selection.clone();\n\n const node = createNode(this.__id, text, this.__exposeText, this.__componentProps);\n ghostTextNodeKey = node.getKey();\n lastText = text;\n\n selection.insertNodes([node]);\n $setSelection(selectionCopy);\n },\n { tag: 'historic' },\n );\n };\n\n const handleUpdate: UpdateListener = props => {\n const { editorState, prevEditorState } = props;\n // If this update was caused by deleting the previous ghost text, don't create a new one until a subsequent update\n if (justRemovedGhostText) {\n justRemovedGhostText = false;\n return;\n }\n editorState.read(() => {\n const promise = this.__$getGhostText(editor, editorState, prevEditorState);\n promise.then(handleGhostTextResponse).catch(e => console.error(e));\n });\n };\n\n function unmountGhostText() {\n if (ghostTextNodeKey) {\n editor.update(\n () => {\n $clearGhostText();\n },\n { tag: 'historic' },\n );\n }\n }\n\n function $handleTabCommand(e: KeyboardEvent) {\n if (ghostTextNodeKey === null || lastText === null) {\n return false;\n }\n\n const ghostTextNode = $getNodeByKey(ghostTextNodeKey);\n if (!ghostTextNode) {\n return false;\n }\n\n e.preventDefault();\n\n const textNode = $createTextNode(lastText);\n ghostTextNode.replace(textNode);\n textNode.selectEnd();\n $clearGhostText();\n return true;\n }\n\n this.__cleanup = mergeRegister(\n editor.registerNodeTransform(nodeClass, handleGhostTextNodeTransform),\n editor.registerUpdateListener(handleUpdate),\n this.__allowCompletion ? editor.registerCommand(KEY_TAB_COMMAND, $handleTabCommand, COMMAND_PRIORITY_LOW) : noop,\n unmountGhostText,\n );\n }\n\n setExposeText(exposeText?: boolean) {\n this.__exposeText = exposeText;\n }\n\n setComponentProps(componentProps?: ComponentPropsType) {\n this.__componentProps = componentProps;\n }\n\n setGetGhostText($getGhostText: GetGhostTextFunction) {\n this.__$getGhostText = $getGhostText;\n }\n\n setAllowCompletion(allowCompletion?: boolean) {\n this.__allowCompletion = allowCompletion;\n }\n}\nfunction noop(): void {\n return;\n}\n"],"names":["$createTextNode","$getNodeByKey","$getSelection","$setSelection","COMMAND_PRIORITY_LOW","KEY_TAB_COMMAND","mergeRegister","GhostTextPluginBase","cleanup","__cleanup","setExposeText","exposeText","__exposeText","setComponentProps","componentProps","__componentProps","setGetGhostText","$getGhostText","__$getGhostText","setAllowCompletion","allowCompletion","__allowCompletion","constructor","editor","id","nodeClass","createNode","__id","ghostTextNodeKey","lastText","undefined","justRemovedGhostText","$clearGhostText","ghostTextNode","isAttached","remove","handleGhostTextNodeTransform","node","key","getKey","handleGhostTextResponse","text","update","selection","selectionCopy","clone","insertNodes","tag","handleUpdate","props","editorState","prevEditorState","read","promise","then","catch","e","console","error","unmountGhostText","$handleTabCommand","preventDefault","textNode","replace","selectEnd","registerNodeTransform","registerUpdateListener","registerCommand","noop"],"mappings":"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"}
1
+ {"version":3,"sources":["GhostText.base.ts"],"sourcesContent":["import type { EditorState, Klass, LexicalEditor, LexicalNode, UpdateListener } from '@fluentui-copilot/text-editor';\nimport {\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n KEY_TAB_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\n\nexport type GetGhostTextFunction = (\n editor: LexicalEditor,\n editorState: EditorState,\n prevEditorState: EditorState,\n) => Promise<string | undefined>;\n\nexport interface IGhostTextNode<ComponentPropsType> extends LexicalNode {\n __content: string;\n __id: string;\n __allowCommitting?: boolean;\n __componentProps?: ComponentPropsType;\n __exposeText?: boolean;\n}\n\nexport class GhostTextPluginBase<ComponentPropsType> {\n private __id: string;\n private __$getGhostText: GetGhostTextFunction;\n private __componentProps?: ComponentPropsType;\n private __exposeText?: boolean;\n private __allowCompletion?: boolean;\n\n private __cleanup?: () => void;\n\n cleanup() {\n this.__cleanup?.();\n }\n\n constructor(\n editor: LexicalEditor,\n id: string,\n $getGhostText: GetGhostTextFunction,\n nodeClass: Klass<IGhostTextNode<ComponentPropsType>>,\n createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>,\n componentProps?: ComponentPropsType,\n // Whether or not the ghost text should count as text inside the input for submitting and character count\n exposeText?: boolean,\n allowCompletion?: boolean,\n ) {\n this.__id = id;\n this.__$getGhostText = $getGhostText;\n this.__componentProps = componentProps;\n this.__exposeText = exposeText;\n this.__allowCompletion = allowCompletion;\n\n let ghostTextNodeKey: string | null = null;\n let lastText: string | undefined = undefined;\n let justRemovedGhostText = false;\n\n function $clearGhostText() {\n const ghostTextNode = ghostTextNodeKey !== null ? $getNodeByKey(ghostTextNodeKey) : null;\n ghostTextNodeKey = null;\n lastText = undefined;\n if (ghostTextNode && ghostTextNode.isAttached()) {\n ghostTextNode.remove();\n }\n }\n function handleGhostTextNodeTransform(node: IGhostTextNode<ComponentPropsType>) {\n const key = node.getKey();\n\n if (node.__id === id && key !== ghostTextNodeKey) {\n // Only one ghost text\n node.remove();\n $clearGhostText();\n }\n }\n\n const handleGhostTextResponse = (text?: string) => {\n if (text === lastText) {\n return;\n }\n\n editor.update(\n () => {\n $clearGhostText();\n\n const selection = $getSelection();\n if (!text || !selection) {\n justRemovedGhostText = true;\n return;\n }\n\n const selectionCopy = selection.clone();\n\n const node = createNode(this.__id, text, this.__exposeText, this.__componentProps);\n ghostTextNodeKey = node.getKey();\n lastText = text;\n\n selection.insertNodes([node]);\n $setSelection(selectionCopy);\n },\n { tag: 'historic' },\n );\n };\n\n const handleUpdate: UpdateListener = props => {\n const { editorState, prevEditorState } = props;\n // If this update was caused by deleting the previous ghost text, don't create a new one until a subsequent update\n if (justRemovedGhostText) {\n justRemovedGhostText = false;\n return;\n }\n editorState.read(() => {\n const promise = this.__$getGhostText(editor, editorState, prevEditorState);\n promise.then(handleGhostTextResponse).catch(e => console.error(e));\n });\n };\n\n function unmountGhostText() {\n if (ghostTextNodeKey) {\n editor.update(\n () => {\n $clearGhostText();\n },\n { tag: 'historic' },\n );\n }\n }\n\n function $handleTabCommand(e: KeyboardEvent) {\n if (ghostTextNodeKey === null || lastText === null) {\n return false;\n }\n\n const ghostTextNode = $getNodeByKey(ghostTextNodeKey);\n if (!ghostTextNode) {\n return false;\n }\n\n e.preventDefault();\n\n const textNode = $createTextNode(lastText);\n ghostTextNode.replace(textNode);\n textNode.selectEnd();\n $clearGhostText();\n return true;\n }\n\n this.__cleanup = mergeRegister(\n editor.registerNodeTransform(nodeClass, handleGhostTextNodeTransform),\n editor.registerUpdateListener(handleUpdate),\n this.__allowCompletion ? editor.registerCommand(KEY_TAB_COMMAND, $handleTabCommand, COMMAND_PRIORITY_LOW) : noop,\n unmountGhostText,\n );\n }\n\n setExposeText(exposeText?: boolean) {\n this.__exposeText = exposeText;\n }\n\n setComponentProps(componentProps?: ComponentPropsType) {\n this.__componentProps = componentProps;\n }\n\n setGetGhostText($getGhostText: GetGhostTextFunction) {\n this.__$getGhostText = $getGhostText;\n }\n\n setAllowCompletion(allowCompletion?: boolean) {\n this.__allowCompletion = allowCompletion;\n }\n}\nfunction noop(): void {\n return;\n}\n"],"names":["$createTextNode","$getNodeByKey","$getSelection","$setSelection","COMMAND_PRIORITY_LOW","KEY_TAB_COMMAND","mergeRegister","GhostTextPluginBase","cleanup","__cleanup","setExposeText","exposeText","__exposeText","setComponentProps","componentProps","__componentProps","setGetGhostText","$getGhostText","__$getGhostText","setAllowCompletion","allowCompletion","__allowCompletion","constructor","editor","id","nodeClass","createNode","__id","ghostTextNodeKey","lastText","undefined","justRemovedGhostText","$clearGhostText","ghostTextNode","isAttached","remove","handleGhostTextNodeTransform","node","key","getKey","handleGhostTextResponse","text","update","selection","selectionCopy","clone","insertNodes","tag","handleUpdate","props","editorState","prevEditorState","read","promise","then","catch","e","console","error","unmountGhostText","$handleTabCommand","preventDefault","textNode","replace","selectEnd","registerNodeTransform","registerUpdateListener","registerCommand","noop"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AACA,SACEA,eAAe,EACfC,aAAa,EACbC,aAAa,EACbC,aAAa,EACbC,oBAAoB,EACpBC,eAAe,EACfC,aAAa,QACR,gCAAgC;AAgBvC,OAAO,MAAMC;IASXC,UAAU;YACR,iBAAA;SAAA,kBAAA,CAAA,QAAA,IAAI,EAACC,SAAS,cAAd,sCAAA,qBAAA;IACF;IA6HAC,cAAcC,UAAoB,EAAE;QAClC,IAAI,CAACC,YAAY,GAAGD;IACtB;IAEAE,kBAAkBC,cAAmC,EAAE;QACrD,IAAI,CAACC,gBAAgB,GAAGD;IAC1B;IAEAE,gBAAgBC,aAAmC,EAAE;QACnD,IAAI,CAACC,eAAe,GAAGD;IACzB;IAEAE,mBAAmBC,eAAyB,EAAE;QAC5C,IAAI,CAACC,iBAAiB,GAAGD;IAC3B;IAzIAE,YACEC,MAAqB,EACrBC,EAAU,EACVP,aAAmC,EACnCQ,SAAoD,EACpDC,UAKuC,EACvCZ,cAAmC,EACnC,yGAAyG;IACzGH,UAAoB,EACpBS,eAAyB,CACzB;QA3BF,uBAAQO,QAAR,KAAA;QACA,uBAAQT,mBAAR,KAAA;QACA,uBAAQH,oBAAR,KAAA;QACA,uBAAQH,gBAAR,KAAA;QACA,uBAAQS,qBAAR,KAAA;QAEA,uBAAQZ,aAAR,KAAA;QAsBE,IAAI,CAACkB,IAAI,GAAGH;QACZ,IAAI,CAACN,eAAe,GAAGD;QACvB,IAAI,CAACF,gBAAgB,GAAGD;QACxB,IAAI,CAACF,YAAY,GAAGD;QACpB,IAAI,CAACU,iBAAiB,GAAGD;QAEzB,IAAIQ,mBAAkC;QACtC,IAAIC,WAA+BC;QACnC,IAAIC,uBAAuB;QAE3B,SAASC;YACP,MAAMC,gBAAgBL,qBAAqB,OAAO3B,cAAc2B,oBAAoB;YACpFA,mBAAmB;YACnBC,WAAWC;YACX,IAAIG,iBAAiBA,cAAcC,UAAU,IAAI;gBAC/CD,cAAcE,MAAM;YACtB;QACF;QACA,SAASC,6BAA6BC,IAAwC;YAC5E,MAAMC,MAAMD,KAAKE,MAAM;YAEvB,IAAIF,KAAKV,IAAI,KAAKH,MAAMc,QAAQV,kBAAkB;gBAChD,sBAAsB;gBACtBS,KAAKF,MAAM;gBACXH;YACF;QACF;QAEA,MAAMQ,0BAA0B,CAACC;YAC/B,IAAIA,SAASZ,UAAU;gBACrB;YACF;YAEAN,OAAOmB,MAAM,CACX;gBACEV;gBAEA,MAAMW,YAAYzC;gBAClB,IAAI,CAACuC,QAAQ,CAACE,WAAW;oBACvBZ,uBAAuB;oBACvB;gBACF;gBAEA,MAAMa,gBAAgBD,UAAUE,KAAK;gBAErC,MAAMR,OAAOX,WAAW,IAAI,CAACC,IAAI,EAAEc,MAAM,IAAI,CAAC7B,YAAY,EAAE,IAAI,CAACG,gBAAgB;gBACjFa,mBAAmBS,KAAKE,MAAM;gBAC9BV,WAAWY;gBAEXE,UAAUG,WAAW,CAAC;oBAACT;iBAAK;gBAC5BlC,cAAcyC;YAChB,GACA;gBAAEG,KAAK;YAAW;QAEtB;QAEA,MAAMC,eAA+BC,CAAAA;YACnC,MAAM,EAAEC,WAAW,EAAEC,eAAe,EAAE,GAAGF;YACzC,kHAAkH;YAClH,IAAIlB,sBAAsB;gBACxBA,uBAAuB;gBACvB;YACF;YACAmB,YAAYE,IAAI,CAAC;gBACf,MAAMC,UAAU,IAAI,CAACnC,eAAe,CAACK,QAAQ2B,aAAaC;gBAC1DE,QAAQC,IAAI,CAACd,yBAAyBe,KAAK,CAACC,CAAAA,IAAKC,QAAQC,KAAK,CAACF;YACjE;QACF;QAEA,SAASG;YACP,IAAI/B,kBAAkB;gBACpBL,OAAOmB,MAAM,CACX;oBACEV;gBACF,GACA;oBAAEe,KAAK;gBAAW;YAEtB;QACF;QAEA,SAASa,kBAAkBJ,CAAgB;YACzC,IAAI5B,qBAAqB,QAAQC,aAAa,MAAM;gBAClD,OAAO;YACT;YAEA,MAAMI,gBAAgBhC,cAAc2B;YACpC,IAAI,CAACK,eAAe;gBAClB,OAAO;YACT;YAEAuB,EAAEK,cAAc;YAEhB,MAAMC,WAAW9D,gBAAgB6B;YACjCI,cAAc8B,OAAO,CAACD;YACtBA,SAASE,SAAS;YAClBhC;YACA,OAAO;QACT;QAEA,IAAI,CAACvB,SAAS,GAAGH,cACfiB,OAAO0C,qBAAqB,CAACxC,WAAWW,+BACxCb,OAAO2C,sBAAsB,CAAClB,eAC9B,IAAI,CAAC3B,iBAAiB,GAAGE,OAAO4C,eAAe,CAAC9D,iBAAiBuD,mBAAmBxD,wBAAwBgE,MAC5GT;IAEJ;AAiBF;AACA,SAASS;IACP;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './GhostText.base';\n"],"names":[],"mappings":"AAAA,cAAc,mBAAmB"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './GhostText.base';\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,mBAAmB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ImperativeControl.base.ts"],"sourcesContent":["import type { LexicalEditor } from '@fluentui-copilot/text-editor';\nimport {\n $createParagraphNode,\n $createRangeSelection,\n $createTextNode,\n $getLeafNodes,\n $getRoot,\n $getSelection,\n $isTextNode,\n $normalizeSelection__EXPERIMENTAL,\n $setSelection,\n} from '@fluentui-copilot/text-editor';\n\nexport interface IImperativeControlBase {\n setInputText: (inputText: string) => void;\n appendText: (text: string) => void;\n prependText: (text: string) => void;\n insertTextAtCursor: (text: string) => void;\n getInputText: () => string;\n scrollToBottom: () => void;\n moveCursor: (location: number) => void;\n}\n\nexport class ImperativeControlBase implements IImperativeControlBase {\n private __editor: LexicalEditor;\n\n constructor(editor: LexicalEditor) {\n this.__editor = editor;\n }\n\n moveCursor(location: number): void {\n this.__editor.update(() => {\n const children = $getLeafNodes($getRoot());\n\n let baseOffset = 0;\n let currentNode = children.shift();\n while (baseOffset < location && currentNode) {\n const nodeLength =\n $isTextNode(currentNode) && !currentNode.isToken()\n ? currentNode.getTextContent().length\n : // Token text nodes and non-text nodes are considered to be a single entry in the input\n 1;\n\n if (baseOffset + nodeLength >= location) {\n const elementType = $isTextNode(currentNode) ? 'text' : 'element';\n const localOffset = location - baseOffset;\n const nodeKey = currentNode.getKey();\n\n const selection = $createRangeSelection();\n selection.anchor.set(nodeKey, localOffset, elementType);\n selection.focus.set(nodeKey, localOffset, elementType);\n\n $setSelection($normalizeSelection__EXPERIMENTAL(selection));\n return;\n }\n\n baseOffset += nodeLength;\n currentNode = children.shift();\n }\n\n if (location > baseOffset) {\n $getRoot().selectEnd();\n }\n });\n }\n setInputText(inputText: string) {\n this.__editor.update(() => {\n const root = $getRoot();\n root.clear();\n if (inputText !== '') {\n const newParagraph = $createParagraphNode();\n const newText = $createTextNode(inputText);\n\n newParagraph.append(newText);\n root.append(newParagraph);\n root.selectEnd();\n }\n });\n }\n appendText(text: string) {\n this.__editor.update(() => {\n $getRoot().selectEnd().insertText(text);\n });\n }\n prependText(text: string) {\n this.__editor.update(() => {\n $getRoot().selectStart().insertText(text);\n });\n }\n insertTextAtCursor(text: string) {\n this.__editor.update(() => {\n $getSelection()?.insertText(text);\n });\n }\n getInputText() {\n return this.__editor.getEditorState().read(() => {\n return $getRoot().getTextContent();\n });\n }\n scrollToBottom() {\n this.__editor.getRootElement()?.scrollIntoView({ behavior: 'smooth', block: 'end' });\n return;\n }\n}\n"],"names":["$createParagraphNode","$createRangeSelection","$createTextNode","$getLeafNodes","$getRoot","$getSelection","$isTextNode","$normalizeSelection__EXPERIMENTAL","$setSelection","ImperativeControlBase","moveCursor","location","__editor","update","children","baseOffset","currentNode","shift","nodeLength","isToken","getTextContent","length","elementType","localOffset","nodeKey","getKey","selection","anchor","set","focus","selectEnd","setInputText","inputText","root","clear","newParagraph","newText","append","appendText","text","insertText","prependText","selectStart","insertTextAtCursor","getInputText","getEditorState","read","scrollToBottom","getRootElement","scrollIntoView","behavior","block","constructor","editor"],"mappings":";AACA,SACEA,oBAAoB,EACpBC,qBAAqB,EACrBC,eAAe,EACfC,aAAa,EACbC,QAAQ,EACRC,aAAa,EACbC,WAAW,EACXC,iCAAiC,EACjCC,aAAa,QACR,gCAAgC;AAYvC,OAAO,MAAMC;IAOXC,WAAWC,QAAgB,EAAQ;QACjC,IAAI,CAACC,QAAQ,CAACC,MAAM,CAAC;YACnB,MAAMC,WAAWX,cAAcC;YAE/B,IAAIW,aAAa;YACjB,IAAIC,cAAcF,SAASG,KAAK;YAChC,MAAOF,aAAaJ,YAAYK,YAAa;gBAC3C,MAAME,aACJZ,YAAYU,gBAAgB,CAACA,YAAYG,OAAO,KAC5CH,YAAYI,cAAc,GAAGC,MAAM,GAEnC;gBAEN,IAAIN,aAAaG,cAAcP,UAAU;oBACvC,MAAMW,cAAchB,YAAYU,eAAe,SAAS;oBACxD,MAAMO,cAAcZ,WAAWI;oBAC/B,MAAMS,UAAUR,YAAYS,MAAM;oBAElC,MAAMC,YAAYzB;oBAClByB,UAAUC,MAAM,CAACC,GAAG,CAACJ,SAASD,aAAaD;oBAC3CI,UAAUG,KAAK,CAACD,GAAG,CAACJ,SAASD,aAAaD;oBAE1Cd,cAAcD,kCAAkCmB;oBAChD;gBACF;gBAEAX,cAAcG;gBACdF,cAAcF,SAASG,KAAK;YAC9B;YAEA,IAAIN,WAAWI,YAAY;gBACzBX,WAAW0B,SAAS;YACtB;QACF;IACF;IACAC,aAAaC,SAAiB,EAAE;QAC9B,IAAI,CAACpB,QAAQ,CAACC,MAAM,CAAC;YACnB,MAAMoB,OAAO7B;YACb6B,KAAKC,KAAK;YACV,IAAIF,cAAc,IAAI;gBACpB,MAAMG,eAAenC;gBACrB,MAAMoC,UAAUlC,gBAAgB8B;gBAEhCG,aAAaE,MAAM,CAACD;gBACpBH,KAAKI,MAAM,CAACF;gBACZF,KAAKH,SAAS;YAChB;QACF;IACF;IACAQ,WAAWC,IAAY,EAAE;QACvB,IAAI,CAAC3B,QAAQ,CAACC,MAAM,CAAC;YACnBT,WAAW0B,SAAS,GAAGU,UAAU,CAACD;QACpC;IACF;IACAE,YAAYF,IAAY,EAAE;QACxB,IAAI,CAAC3B,QAAQ,CAACC,MAAM,CAAC;YACnBT,WAAWsC,WAAW,GAAGF,UAAU,CAACD;QACtC;IACF;IACAI,mBAAmBJ,IAAY,EAAE;QAC/B,IAAI,CAAC3B,QAAQ,CAACC,MAAM,CAAC;gBACnBR;aAAAA,iBAAAA,6BAAAA,qCAAAA,eAAiBmC,UAAU,CAACD;QAC9B;IACF;IACAK,eAAe;QACb,OAAO,IAAI,CAAChC,QAAQ,CAACiC,cAAc,GAAGC,IAAI,CAAC;YACzC,OAAO1C,WAAWgB,cAAc;QAClC;IACF;IACA2B,iBAAiB;YACf;SAAA,gCAAA,IAAI,CAACnC,QAAQ,CAACoC,cAAc,gBAA5B,oDAAA,8BAAgCC,cAAc,CAAC;YAAEC,UAAU;YAAUC,OAAO;QAAM;QAClF;IACF;IA5EAC,YAAYC,MAAqB,CAAE;QAFnC,uBAAQzC,YAAR,KAAA;QAGE,IAAI,CAACA,QAAQ,GAAGyC;IAClB;AA2EF"}
1
+ {"version":3,"sources":["ImperativeControl.base.ts"],"sourcesContent":["import type { LexicalEditor } from '@fluentui-copilot/text-editor';\nimport {\n $createParagraphNode,\n $createRangeSelection,\n $createTextNode,\n $getLeafNodes,\n $getRoot,\n $getSelection,\n $isTextNode,\n $normalizeSelection__EXPERIMENTAL,\n $setSelection,\n} from '@fluentui-copilot/text-editor';\n\nexport interface IImperativeControlBase {\n setInputText: (inputText: string) => void;\n appendText: (text: string) => void;\n prependText: (text: string) => void;\n insertTextAtCursor: (text: string) => void;\n getInputText: () => string;\n scrollToBottom: () => void;\n moveCursor: (location: number) => void;\n}\n\nexport class ImperativeControlBase implements IImperativeControlBase {\n private __editor: LexicalEditor;\n\n constructor(editor: LexicalEditor) {\n this.__editor = editor;\n }\n\n moveCursor(location: number): void {\n this.__editor.update(() => {\n const children = $getLeafNodes($getRoot());\n\n let baseOffset = 0;\n let currentNode = children.shift();\n while (baseOffset < location && currentNode) {\n const nodeLength =\n $isTextNode(currentNode) && !currentNode.isToken()\n ? currentNode.getTextContent().length\n : // Token text nodes and non-text nodes are considered to be a single entry in the input\n 1;\n\n if (baseOffset + nodeLength >= location) {\n const elementType = $isTextNode(currentNode) ? 'text' : 'element';\n const localOffset = location - baseOffset;\n const nodeKey = currentNode.getKey();\n\n const selection = $createRangeSelection();\n selection.anchor.set(nodeKey, localOffset, elementType);\n selection.focus.set(nodeKey, localOffset, elementType);\n\n $setSelection($normalizeSelection__EXPERIMENTAL(selection));\n return;\n }\n\n baseOffset += nodeLength;\n currentNode = children.shift();\n }\n\n if (location > baseOffset) {\n $getRoot().selectEnd();\n }\n });\n }\n setInputText(inputText: string) {\n this.__editor.update(() => {\n const root = $getRoot();\n root.clear();\n if (inputText !== '') {\n const newParagraph = $createParagraphNode();\n const newText = $createTextNode(inputText);\n\n newParagraph.append(newText);\n root.append(newParagraph);\n root.selectEnd();\n }\n });\n }\n appendText(text: string) {\n this.__editor.update(() => {\n $getRoot().selectEnd().insertText(text);\n });\n }\n prependText(text: string) {\n this.__editor.update(() => {\n $getRoot().selectStart().insertText(text);\n });\n }\n insertTextAtCursor(text: string) {\n this.__editor.update(() => {\n $getSelection()?.insertText(text);\n });\n }\n getInputText() {\n return this.__editor.getEditorState().read(() => {\n return $getRoot().getTextContent();\n });\n }\n scrollToBottom() {\n this.__editor.getRootElement()?.scrollIntoView({ behavior: 'smooth', block: 'end' });\n return;\n }\n}\n"],"names":["$createParagraphNode","$createRangeSelection","$createTextNode","$getLeafNodes","$getRoot","$getSelection","$isTextNode","$normalizeSelection__EXPERIMENTAL","$setSelection","ImperativeControlBase","moveCursor","location","__editor","update","children","baseOffset","currentNode","shift","nodeLength","isToken","getTextContent","length","elementType","localOffset","nodeKey","getKey","selection","anchor","set","focus","selectEnd","setInputText","inputText","root","clear","newParagraph","newText","append","appendText","text","insertText","prependText","selectStart","insertTextAtCursor","getInputText","getEditorState","read","scrollToBottom","getRootElement","scrollIntoView","behavior","block","constructor","editor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AACA,SACEA,oBAAoB,EACpBC,qBAAqB,EACrBC,eAAe,EACfC,aAAa,EACbC,QAAQ,EACRC,aAAa,EACbC,WAAW,EACXC,iCAAiC,EACjCC,aAAa,QACR,gCAAgC;AAYvC,OAAO,MAAMC;IAOXC,WAAWC,QAAgB,EAAQ;QACjC,IAAI,CAACC,QAAQ,CAACC,MAAM,CAAC;YACnB,MAAMC,WAAWX,cAAcC;YAE/B,IAAIW,aAAa;YACjB,IAAIC,cAAcF,SAASG,KAAK;YAChC,MAAOF,aAAaJ,YAAYK,YAAa;gBAC3C,MAAME,aACJZ,YAAYU,gBAAgB,CAACA,YAAYG,OAAO,KAC5CH,YAAYI,cAAc,GAAGC,MAAM,GAEnC;gBAEN,IAAIN,aAAaG,cAAcP,UAAU;oBACvC,MAAMW,cAAchB,YAAYU,eAAe,SAAS;oBACxD,MAAMO,cAAcZ,WAAWI;oBAC/B,MAAMS,UAAUR,YAAYS,MAAM;oBAElC,MAAMC,YAAYzB;oBAClByB,UAAUC,MAAM,CAACC,GAAG,CAACJ,SAASD,aAAaD;oBAC3CI,UAAUG,KAAK,CAACD,GAAG,CAACJ,SAASD,aAAaD;oBAE1Cd,cAAcD,kCAAkCmB;oBAChD;gBACF;gBAEAX,cAAcG;gBACdF,cAAcF,SAASG,KAAK;YAC9B;YAEA,IAAIN,WAAWI,YAAY;gBACzBX,WAAW0B,SAAS;YACtB;QACF;IACF;IACAC,aAAaC,SAAiB,EAAE;QAC9B,IAAI,CAACpB,QAAQ,CAACC,MAAM,CAAC;YACnB,MAAMoB,OAAO7B;YACb6B,KAAKC,KAAK;YACV,IAAIF,cAAc,IAAI;gBACpB,MAAMG,eAAenC;gBACrB,MAAMoC,UAAUlC,gBAAgB8B;gBAEhCG,aAAaE,MAAM,CAACD;gBACpBH,KAAKI,MAAM,CAACF;gBACZF,KAAKH,SAAS;YAChB;QACF;IACF;IACAQ,WAAWC,IAAY,EAAE;QACvB,IAAI,CAAC3B,QAAQ,CAACC,MAAM,CAAC;YACnBT,WAAW0B,SAAS,GAAGU,UAAU,CAACD;QACpC;IACF;IACAE,YAAYF,IAAY,EAAE;QACxB,IAAI,CAAC3B,QAAQ,CAACC,MAAM,CAAC;YACnBT,WAAWsC,WAAW,GAAGF,UAAU,CAACD;QACtC;IACF;IACAI,mBAAmBJ,IAAY,EAAE;QAC/B,IAAI,CAAC3B,QAAQ,CAACC,MAAM,CAAC;gBACnBR;aAAAA,iBAAAA,6BAAAA,qCAAAA,eAAiBmC,UAAU,CAACD;QAC9B;IACF;IACAK,eAAe;QACb,OAAO,IAAI,CAAChC,QAAQ,CAACiC,cAAc,GAAGC,IAAI,CAAC;YACzC,OAAO1C,WAAWgB,cAAc;QAClC;IACF;IACA2B,iBAAiB;YACf;SAAA,gCAAA,IAAI,CAACnC,QAAQ,CAACoC,cAAc,gBAA5B,oDAAA,8BAAgCC,cAAc,CAAC;YAAEC,UAAU;YAAUC,OAAO;QAAM;QAClF;IACF;IA5EAC,YAAYC,MAAqB,CAAE;QAFnC,uBAAQzC,YAAR,KAAA;QAGE,IAAI,CAACA,QAAQ,GAAGyC;IAClB;AA2EF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ImperativeControl.base';\n"],"names":[],"mappings":"AAAA,cAAc,2BAA2B"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ImperativeControl.base';\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,2BAA2B"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ManualGhostText.base.ts"],"sourcesContent":["import {\n $createTextNode,\n $getNodeByKey,\n $insertNodes,\n type LexicalEditor,\n type LexicalNode,\n} from '@fluentui-copilot/text-editor';\nimport type { IGhostTextNode } from '../GhostText';\n\nexport interface IManualGhostTextBase<ComponentPropsType> {\n getGhostText: () => string | undefined;\n setGhostText: (text: string, componentProps?: ComponentPropsType) => void;\n commitGhostText: (finalText: string) => void;\n cancelGhostText: () => void;\n}\n\nexport class ManualGhostTextBase<ComponentPropsType> {\n private __editor: LexicalEditor;\n private __nodeKey?: string;\n\n private __id: string;\n private __$isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>;\n private __$createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>;\n\n constructor(\n editor: LexicalEditor,\n id: string,\n $isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>,\n $createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>,\n ) {\n this.__editor = editor;\n this.__id = id;\n this.__$isNodeType = $isNodeType;\n this.__$createNode = $createNode;\n }\n\n getGhostText(): string | undefined {\n return this.__editor.getEditorState().read(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n return node.__content;\n }\n }\n });\n }\n\n setGhostText(text: string, exposeText?: boolean, componentProps?: ComponentPropsType): void {\n this.__editor.update(\n () => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.getWritable().__content = text;\n return;\n }\n }\n\n const node = this.__$createNode(this.__id, text, exposeText, componentProps);\n this.__nodeKey = node.getKey();\n $insertNodes([node]);\n node.selectStart();\n },\n { tag: 'historic' },\n );\n }\n\n commitGhostText(finalText: string): void {\n if (this.__nodeKey) {\n this.__editor.update(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n const textNode = $createTextNode(finalText);\n node.replace(textNode);\n textNode.selectEnd();\n }\n }\n });\n this.__nodeKey = undefined;\n }\n }\n\n cancelGhostText(): void {\n if (this.__nodeKey) {\n this.__editor.update(\n () => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.remove();\n }\n }\n },\n { tag: 'historic' },\n );\n this.__nodeKey = undefined;\n }\n }\n}\n"],"names":["$createTextNode","$getNodeByKey","$insertNodes","ManualGhostTextBase","getGhostText","__editor","getEditorState","read","__nodeKey","node","__$isNodeType","__content","setGhostText","text","exposeText","componentProps","update","getWritable","__$createNode","__id","getKey","selectStart","tag","commitGhostText","finalText","textNode","replace","selectEnd","undefined","cancelGhostText","remove","constructor","editor","id","$isNodeType","$createNode"],"mappings":";AAAA,SACEA,eAAe,EACfC,aAAa,EACbC,YAAY,QAGP,gCAAgC;AAUvC,OAAO,MAAMC;IA8BXC,eAAmC;QACjC,OAAO,IAAI,CAACC,QAAQ,CAACC,cAAc,GAAGC,IAAI,CAAC;YACzC,IAAI,IAAI,CAACC,SAAS,EAAE;gBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;gBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;oBAC5B,OAAOA,KAAKE,SAAS;gBACvB;YACF;QACF;IACF;IAEAC,aAAaC,IAAY,EAAEC,UAAoB,EAAEC,cAAmC,EAAQ;QAC1F,IAAI,CAACV,QAAQ,CAACW,MAAM,CAClB;YACE,IAAI,IAAI,CAACR,SAAS,EAAE;gBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;gBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;oBAC5BA,KAAKQ,WAAW,GAAGN,SAAS,GAAGE;oBAC/B;gBACF;YACF;YAEA,MAAMJ,OAAO,IAAI,CAACS,aAAa,CAAC,IAAI,CAACC,IAAI,EAAEN,MAAMC,YAAYC;YAC7D,IAAI,CAACP,SAAS,GAAGC,KAAKW,MAAM;YAC5BlB,aAAa;gBAACO;aAAK;YACnBA,KAAKY,WAAW;QAClB,GACA;YAAEC,KAAK;QAAW;IAEtB;IAEAC,gBAAgBC,SAAiB,EAAQ;QACvC,IAAI,IAAI,CAAChB,SAAS,EAAE;YAClB,IAAI,CAACH,QAAQ,CAACW,MAAM,CAAC;gBACnB,IAAI,IAAI,CAACR,SAAS,EAAE;oBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;oBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;wBAC5B,MAAMgB,WAAWzB,gBAAgBwB;wBACjCf,KAAKiB,OAAO,CAACD;wBACbA,SAASE,SAAS;oBACpB;gBACF;YACF;YACA,IAAI,CAACnB,SAAS,GAAGoB;QACnB;IACF;IAEAC,kBAAwB;QACtB,IAAI,IAAI,CAACrB,SAAS,EAAE;YAClB,IAAI,CAACH,QAAQ,CAACW,MAAM,CAClB;gBACE,IAAI,IAAI,CAACR,SAAS,EAAE;oBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;oBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;wBAC5BA,KAAKqB,MAAM;oBACb;gBACF;YACF,GACA;gBAAER,KAAK;YAAW;YAEpB,IAAI,CAACd,SAAS,GAAGoB;QACnB;IACF;IA/EAG,YACEC,MAAqB,EACrBC,EAAU,EACVC,WAAqF,EACrFC,WAKuC,CACvC;QAtBF,uBAAQ9B,YAAR,KAAA;QACA,uBAAQG,aAAR,KAAA;QAEA,uBAAQW,QAAR,KAAA;QACA,uBAAQT,iBAAR,KAAA;QACA,uBAAQQ,iBAAR,KAAA;QAkBE,IAAI,CAACb,QAAQ,GAAG2B;QAChB,IAAI,CAACb,IAAI,GAAGc;QACZ,IAAI,CAACvB,aAAa,GAAGwB;QACrB,IAAI,CAAChB,aAAa,GAAGiB;IACvB;AAiEF"}
1
+ {"version":3,"sources":["ManualGhostText.base.ts"],"sourcesContent":["import {\n $createTextNode,\n $getNodeByKey,\n $insertNodes,\n type LexicalEditor,\n type LexicalNode,\n} from '@fluentui-copilot/text-editor';\nimport type { IGhostTextNode } from '../GhostText';\n\nexport interface IManualGhostTextBase<ComponentPropsType> {\n getGhostText: () => string | undefined;\n setGhostText: (text: string, componentProps?: ComponentPropsType) => void;\n commitGhostText: (finalText: string) => void;\n cancelGhostText: () => void;\n}\n\nexport class ManualGhostTextBase<ComponentPropsType> {\n private __editor: LexicalEditor;\n private __nodeKey?: string;\n\n private __id: string;\n private __$isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>;\n private __$createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>;\n\n constructor(\n editor: LexicalEditor,\n id: string,\n $isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>,\n $createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>,\n ) {\n this.__editor = editor;\n this.__id = id;\n this.__$isNodeType = $isNodeType;\n this.__$createNode = $createNode;\n }\n\n getGhostText(): string | undefined {\n return this.__editor.getEditorState().read(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n return node.__content;\n }\n }\n });\n }\n\n setGhostText(text: string, exposeText?: boolean, componentProps?: ComponentPropsType): void {\n this.__editor.update(\n () => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.getWritable().__content = text;\n return;\n }\n }\n\n const node = this.__$createNode(this.__id, text, exposeText, componentProps);\n this.__nodeKey = node.getKey();\n $insertNodes([node]);\n node.selectStart();\n },\n { tag: 'historic' },\n );\n }\n\n commitGhostText(finalText: string): void {\n if (this.__nodeKey) {\n this.__editor.update(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n const textNode = $createTextNode(finalText);\n node.replace(textNode);\n textNode.selectEnd();\n }\n }\n });\n this.__nodeKey = undefined;\n }\n }\n\n cancelGhostText(): void {\n if (this.__nodeKey) {\n this.__editor.update(\n () => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.remove();\n }\n }\n },\n { tag: 'historic' },\n );\n this.__nodeKey = undefined;\n }\n }\n}\n"],"names":["$createTextNode","$getNodeByKey","$insertNodes","ManualGhostTextBase","getGhostText","__editor","getEditorState","read","__nodeKey","node","__$isNodeType","__content","setGhostText","text","exposeText","componentProps","update","getWritable","__$createNode","__id","getKey","selectStart","tag","commitGhostText","finalText","textNode","replace","selectEnd","undefined","cancelGhostText","remove","constructor","editor","id","$isNodeType","$createNode"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AAAA,SACEA,eAAe,EACfC,aAAa,EACbC,YAAY,QAGP,gCAAgC;AAUvC,OAAO,MAAMC;IA8BXC,eAAmC;QACjC,OAAO,IAAI,CAACC,QAAQ,CAACC,cAAc,GAAGC,IAAI,CAAC;YACzC,IAAI,IAAI,CAACC,SAAS,EAAE;gBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;gBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;oBAC5B,OAAOA,KAAKE,SAAS;gBACvB;YACF;QACF;IACF;IAEAC,aAAaC,IAAY,EAAEC,UAAoB,EAAEC,cAAmC,EAAQ;QAC1F,IAAI,CAACV,QAAQ,CAACW,MAAM,CAClB;YACE,IAAI,IAAI,CAACR,SAAS,EAAE;gBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;gBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;oBAC5BA,KAAKQ,WAAW,GAAGN,SAAS,GAAGE;oBAC/B;gBACF;YACF;YAEA,MAAMJ,OAAO,IAAI,CAACS,aAAa,CAAC,IAAI,CAACC,IAAI,EAAEN,MAAMC,YAAYC;YAC7D,IAAI,CAACP,SAAS,GAAGC,KAAKW,MAAM;YAC5BlB,aAAa;gBAACO;aAAK;YACnBA,KAAKY,WAAW;QAClB,GACA;YAAEC,KAAK;QAAW;IAEtB;IAEAC,gBAAgBC,SAAiB,EAAQ;QACvC,IAAI,IAAI,CAAChB,SAAS,EAAE;YAClB,IAAI,CAACH,QAAQ,CAACW,MAAM,CAAC;gBACnB,IAAI,IAAI,CAACR,SAAS,EAAE;oBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;oBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;wBAC5B,MAAMgB,WAAWzB,gBAAgBwB;wBACjCf,KAAKiB,OAAO,CAACD;wBACbA,SAASE,SAAS;oBACpB;gBACF;YACF;YACA,IAAI,CAACnB,SAAS,GAAGoB;QACnB;IACF;IAEAC,kBAAwB;QACtB,IAAI,IAAI,CAACrB,SAAS,EAAE;YAClB,IAAI,CAACH,QAAQ,CAACW,MAAM,CAClB;gBACE,IAAI,IAAI,CAACR,SAAS,EAAE;oBAClB,MAAMC,OAAOR,cAAc,IAAI,CAACO,SAAS;oBACzC,IAAI,IAAI,CAACE,aAAa,CAACD,OAAO;wBAC5BA,KAAKqB,MAAM;oBACb;gBACF;YACF,GACA;gBAAER,KAAK;YAAW;YAEpB,IAAI,CAACd,SAAS,GAAGoB;QACnB;IACF;IA/EAG,YACEC,MAAqB,EACrBC,EAAU,EACVC,WAAqF,EACrFC,WAKuC,CACvC;QAtBF,uBAAQ9B,YAAR,KAAA;QACA,uBAAQG,aAAR,KAAA;QAEA,uBAAQW,QAAR,KAAA;QACA,uBAAQT,iBAAR,KAAA;QACA,uBAAQQ,iBAAR,KAAA;QAkBE,IAAI,CAACb,QAAQ,GAAG2B;QAChB,IAAI,CAACb,IAAI,GAAGc;QACZ,IAAI,CAACvB,aAAa,GAAGwB;QACrB,IAAI,CAAChB,aAAa,GAAGiB;IACvB;AAiEF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ManualGhostText.base';\n"],"names":[],"mappings":"AAAA,cAAc,yBAAyB"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ManualGhostText.base';\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,yBAAyB"}
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { BasicFunctionalityBase } from './BasicFunctionality';
1
+ export { BasicFunctionalityBase, SentinelNode, $createSentinelNode, $isSentinelNode } from './BasicFunctionality';
2
2
  export { ChatInputEntityPluginBase } from './ChatInputEntity';
3
3
  export { GhostTextPluginBase } from './GhostText';
4
4
  export { ImperativeControlBase } from './ImperativeControl';
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export { BasicFunctionalityBase } from './BasicFunctionality';\nexport type { IBasicFunctionalityBase } from './BasicFunctionality';\n\nexport { ChatInputEntityPluginBase } from './ChatInputEntity';\nexport type {\n ChatInputEntityData,\n ChatInputEntityPluginProps,\n IChatInputEntityPluginBase,\n IEntityNode,\n} from './ChatInputEntity';\n\nexport { GhostTextPluginBase } from './GhostText';\nexport type { GetGhostTextFunction, IGhostTextNode } from './GhostText';\n\nexport { ImperativeControlBase } from './ImperativeControl';\nexport type { IImperativeControlBase } from './ImperativeControl';\n\nexport { ManualGhostTextBase } from './ManualGhostText';\nexport type { IManualGhostTextBase } from './ManualGhostText';\n"],"names":["BasicFunctionalityBase","ChatInputEntityPluginBase","GhostTextPluginBase","ImperativeControlBase","ManualGhostTextBase"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,uBAAuB;AAG9D,SAASC,yBAAyB,QAAQ,oBAAoB;AAQ9D,SAASC,mBAAmB,QAAQ,cAAc;AAGlD,SAASC,qBAAqB,QAAQ,sBAAsB;AAG5D,SAASC,mBAAmB,QAAQ,oBAAoB"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export { BasicFunctionalityBase, SentinelNode, $createSentinelNode, $isSentinelNode } from './BasicFunctionality';\nexport type { IBasicFunctionalityBase } from './BasicFunctionality';\n\nexport { ChatInputEntityPluginBase } from './ChatInputEntity';\nexport type {\n ChatInputEntityData,\n ChatInputEntityPluginProps,\n IChatInputEntityPluginBase,\n IEntityNode,\n} from './ChatInputEntity';\n\nexport { GhostTextPluginBase } from './GhostText';\nexport type { GetGhostTextFunction, IGhostTextNode } from './GhostText';\n\nexport { ImperativeControlBase } from './ImperativeControl';\nexport type { IImperativeControlBase } from './ImperativeControl';\n\nexport { ManualGhostTextBase } from './ManualGhostText';\nexport type { IManualGhostTextBase } from './ManualGhostText';\n"],"names":["BasicFunctionalityBase","SentinelNode","$createSentinelNode","$isSentinelNode","ChatInputEntityPluginBase","GhostTextPluginBase","ImperativeControlBase","ManualGhostTextBase"],"rangeMappings":";;;;","mappings":"AAAA,SAASA,sBAAsB,EAAEC,YAAY,EAAEC,mBAAmB,EAAEC,eAAe,QAAQ,uBAAuB;AAGlH,SAASC,yBAAyB,QAAQ,oBAAoB;AAQ9D,SAASC,mBAAmB,QAAQ,cAAc;AAGlD,SAASC,qBAAqB,QAAQ,sBAAsB;AAG5D,SAASC,mBAAmB,QAAQ,oBAAoB"}
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "BasicFunctionalityBase", {
10
10
  });
11
11
  const _define_property = require("@swc/helpers/_/_define_property");
12
12
  const _texteditor = require("@fluentui-copilot/text-editor");
13
+ const _SentinelNode = require("./SentinelNode");
13
14
  class BasicFunctionalityBase {
14
15
  __enterHandler(event) {
15
16
  const selection = (0, _texteditor.$getSelection)();
@@ -38,8 +39,10 @@ class BasicFunctionalityBase {
38
39
  activateContentCallbacks(onContentChange, onCountChanged) {
39
40
  this.deactivateContentCallbacks();
40
41
  this.__contentChangeCleanup = this.__editor.registerTextContentListener((text)=>{
41
- onContentChange === null || onContentChange === void 0 ? void 0 : onContentChange(text);
42
- onCountChanged === null || onCountChanged === void 0 ? void 0 : onCountChanged(text.length);
42
+ // Remove the sentinel node
43
+ const processed = text.replace('\u200b\u200c', '');
44
+ onContentChange === null || onContentChange === void 0 ? void 0 : onContentChange(processed);
45
+ onCountChanged === null || onCountChanged === void 0 ? void 0 : onCountChanged(processed.length);
43
46
  });
44
47
  }
45
48
  deactivateContentCallbacks() {
@@ -47,6 +50,20 @@ class BasicFunctionalityBase {
47
50
  (_this___contentChangeCleanup = (_this = this).__contentChangeCleanup) === null || _this___contentChangeCleanup === void 0 ? void 0 : _this___contentChangeCleanup.call(_this);
48
51
  this.__contentChangeCleanup = undefined;
49
52
  }
53
+ activatePasteCallback(onPaste) {
54
+ this.__pasteHandlerCleanup = this.__editor.registerCommand(_texteditor.PASTE_COMMAND, (event)=>{
55
+ onPaste(event);
56
+ if (event.defaultPrevented) {
57
+ return true;
58
+ }
59
+ return false;
60
+ }, _texteditor.COMMAND_PRIORITY_CRITICAL);
61
+ }
62
+ deactivatePasteCallback() {
63
+ var _this___pasteHandlerCleanup, _this;
64
+ (_this___pasteHandlerCleanup = (_this = this).__pasteHandlerCleanup) === null || _this___pasteHandlerCleanup === void 0 ? void 0 : _this___pasteHandlerCleanup.call(_this);
65
+ this.__pasteHandlerCleanup = undefined;
66
+ }
50
67
  activateTrimWhitespace() {
51
68
  this.deactivateTrimWhitespace();
52
69
  this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener((text)=>{
@@ -71,18 +88,89 @@ class BasicFunctionalityBase {
71
88
  this.__editor.setEditable(!isDisabled);
72
89
  }
73
90
  cleanup() {
74
- var _this___enterHandlerCleanup, _this;
91
+ var _this___baseHandlersCleanup, _this;
75
92
  this.deactivateContentCallbacks();
76
93
  this.deactivateTrimWhitespace();
77
- (_this___enterHandlerCleanup = (_this = this).__enterHandlerCleanup) === null || _this___enterHandlerCleanup === void 0 ? void 0 : _this___enterHandlerCleanup.call(_this);
78
- this.__enterHandlerCleanup = undefined;
94
+ this.deactivatePasteCallback();
95
+ (_this___baseHandlersCleanup = (_this = this).__baseHandlersCleanup) === null || _this___baseHandlersCleanup === void 0 ? void 0 : _this___baseHandlersCleanup.call(_this);
96
+ this.__baseHandlersCleanup = undefined;
79
97
  }
80
98
  constructor(editor){
81
99
  (0, _define_property._)(this, "__editor", void 0);
82
100
  (0, _define_property._)(this, "__contentChangeCleanup", void 0);
83
101
  (0, _define_property._)(this, "__trimWhitespaceCleanup", void 0);
84
- (0, _define_property._)(this, "__enterHandlerCleanup", void 0);
102
+ (0, _define_property._)(this, "__baseHandlersCleanup", void 0);
103
+ (0, _define_property._)(this, "__pasteHandlerCleanup", void 0);
85
104
  this.__editor = editor;
86
- this.__enterHandlerCleanup = this.__editor.registerCommand(_texteditor.KEY_ENTER_COMMAND, this.__enterHandler.bind(this), _texteditor.COMMAND_PRIORITY_CRITICAL);
105
+ this.__baseHandlersCleanup = (0, _texteditor.mergeRegister)(this.__editor.registerCommand(_texteditor.KEY_ENTER_COMMAND, this.__enterHandler.bind(this), _texteditor.COMMAND_PRIORITY_CRITICAL), // Add a sentinel node at the end of the input when there is content.
106
+ // This sentinel node fixes a number of issues.
107
+ // In Safari, Lexical's behaviour of adding <br /> tags to the end of the input when it ends
108
+ // in a decorator node causes cursor location issues: https://github.com/facebook/lexical/issues/4487
109
+ // Otherwise, when a decorator node is the last node in the input, the cursor can't move past it.
110
+ // Adding an invisible text node that doesn't contribute to the content and can't be selected to the end of the input
111
+ // mitigates these issues.
112
+ this.__editor.registerUpdateListener(({ editorState })=>{
113
+ editorState.read(()=>{
114
+ const leaves = (0, _texteditor.$getLeafNodes)((0, _texteditor.$getRoot)());
115
+ if (leaves.length === 0) {
116
+ return;
117
+ }
118
+ const sentinel = leaves[leaves.length - 1];
119
+ // If the last node isn't a sentinel, add one
120
+ if (!(0, _SentinelNode.$isSentinelNode)(sentinel)) {
121
+ this.__editor.update(()=>{
122
+ sentinel.insertAfter((0, _SentinelNode.$createSentinelNode)());
123
+ }, {
124
+ discrete: true
125
+ });
126
+ return;
127
+ }
128
+ // If the sentinel node is not selected, we're done
129
+ const previous = sentinel.getPreviousSibling();
130
+ if (!previous || !sentinel.isSelected()) {
131
+ return;
132
+ }
133
+ const selection = (0, _texteditor.$getSelection)();
134
+ if (!(0, _texteditor.$isRangeSelection)(selection)) {
135
+ return;
136
+ }
137
+ // If the cursor is inside the sentinel node, move it out (next to the beginning)
138
+ // We allow selection on the boundary of the sentinel in case the adjacent node is a decorator node
139
+ // where selection is ill-defined.
140
+ if (selection.isCollapsed() && selection.anchor.offset > 0) {
141
+ this.__editor.update(()=>{
142
+ sentinel.selectStart();
143
+ }, {
144
+ discrete: true
145
+ });
146
+ return;
147
+ }
148
+ // If the selection is a range which includes the sentinel, modify the range to exclude it
149
+ if (!selection.isCollapsed()) {
150
+ let selectionChanged = false;
151
+ const newSelection = selection.clone();
152
+ if (newSelection.anchor.getNode() === sentinel && newSelection.anchor.offset > 0) {
153
+ newSelection.anchor.set(sentinel.getKey(), 0, 'text');
154
+ selectionChanged = true;
155
+ }
156
+ if (newSelection.focus.getNode() === sentinel && newSelection.focus.offset > 0) {
157
+ newSelection.focus.set(sentinel.getKey(), 0, 'text');
158
+ selectionChanged = true;
159
+ }
160
+ if (selectionChanged) {
161
+ this.__editor.update(()=>{
162
+ (0, _texteditor.$setSelection)((0, _texteditor.$normalizeSelection__EXPERIMENTAL)(newSelection));
163
+ }, {
164
+ discrete: true
165
+ });
166
+ }
167
+ }
168
+ });
169
+ }), this.__editor.registerNodeTransform(_SentinelNode.SentinelNode, (node)=>{
170
+ if (!node.getPreviousSibling() || node.getNextSibling()) {
171
+ node.remove();
172
+ return;
173
+ }
174
+ }));
87
175
  }
88
176
  } //# sourceMappingURL=BasicFunctionality.base.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["BasicFunctionality.base.js"],"sourcesContent":["import { _ as _define_property } from \"@swc/helpers/_/_define_property\";\nimport { $createTextNode, $getRoot, $getSelection, $insertNodes, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, INSERT_PARAGRAPH_COMMAND, KEY_ENTER_COMMAND } from '@fluentui-copilot/text-editor';\nexport class BasicFunctionalityBase {\n __enterHandler(event) {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return false;\n }\n if (event === null) {\n return false;\n }\n event.preventDefault();\n if (event.shiftKey) {\n return this.__editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined);\n }\n // Mark event handled to override default behavior\n return true;\n }\n insertDefaultValue(defaultValue) {\n if (defaultValue) {\n this.__editor.update(() => {\n $insertNodes([$createTextNode(defaultValue)]);\n });\n }\n }\n activateContentCallbacks(onContentChange, onCountChanged) {\n this.deactivateContentCallbacks();\n this.__contentChangeCleanup = this.__editor.registerTextContentListener(text => {\n onContentChange === null || onContentChange === void 0 ? void 0 : onContentChange(text);\n onCountChanged === null || onCountChanged === void 0 ? void 0 : onCountChanged(text.length);\n });\n }\n deactivateContentCallbacks() {\n var _this___contentChangeCleanup, _this;\n (_this___contentChangeCleanup = (_this = this).__contentChangeCleanup) === null || _this___contentChangeCleanup === void 0 ? void 0 : _this___contentChangeCleanup.call(_this);\n this.__contentChangeCleanup = undefined;\n }\n activateTrimWhitespace() {\n this.deactivateTrimWhitespace();\n this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener(text => {\n if (text.trim() === '') {\n this.__editor.update(() => {\n $getRoot().getAllTextNodes().forEach(node => {\n node.remove();\n });\n },\n // Don't allow undoing this action\n {\n tag: 'historic'\n });\n }\n });\n }\n deactivateTrimWhitespace() {\n var _this___trimWhitespaceCleanup, _this;\n (_this___trimWhitespaceCleanup = (_this = this).__trimWhitespaceCleanup) === null || _this___trimWhitespaceCleanup === void 0 ? void 0 : _this___trimWhitespaceCleanup.call(_this);\n this.__trimWhitespaceCleanup = undefined;\n }\n setIsDisabled(isDisabled) {\n this.__editor.setEditable(!isDisabled);\n }\n cleanup() {\n var _this___enterHandlerCleanup, _this;\n this.deactivateContentCallbacks();\n this.deactivateTrimWhitespace();\n (_this___enterHandlerCleanup = (_this = this).__enterHandlerCleanup) === null || _this___enterHandlerCleanup === void 0 ? void 0 : _this___enterHandlerCleanup.call(_this);\n this.__enterHandlerCleanup = undefined;\n }\n constructor(editor) {\n _define_property(this, \"__editor\", void 0);\n _define_property(this, \"__contentChangeCleanup\", void 0);\n _define_property(this, \"__trimWhitespaceCleanup\", void 0);\n _define_property(this, \"__enterHandlerCleanup\", void 0);\n this.__editor = editor;\n this.__enterHandlerCleanup = this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_CRITICAL);\n }\n}\n//# sourceMappingURL=BasicFunctionality.base.js.map"],"names":["BasicFunctionalityBase","__enterHandler","event","selection","$getSelection","$isRangeSelection","preventDefault","shiftKey","__editor","dispatchCommand","INSERT_PARAGRAPH_COMMAND","undefined","insertDefaultValue","defaultValue","update","$insertNodes","$createTextNode","activateContentCallbacks","onContentChange","onCountChanged","deactivateContentCallbacks","__contentChangeCleanup","registerTextContentListener","text","length","_this___contentChangeCleanup","_this","call","activateTrimWhitespace","deactivateTrimWhitespace","__trimWhitespaceCleanup","trim","$getRoot","getAllTextNodes","forEach","node","remove","tag","_this___trimWhitespaceCleanup","setIsDisabled","isDisabled","setEditable","cleanup","_this___enterHandlerCleanup","__enterHandlerCleanup","constructor","editor","_define_property","registerCommand","KEY_ENTER_COMMAND","bind","COMMAND_PRIORITY_CRITICAL"],"mappings":"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"}
1
+ {"version":3,"sources":["BasicFunctionality.base.ts"],"sourcesContent":["import type { LexicalEditor } from '@fluentui-copilot/text-editor';\nimport {\n $createTextNode,\n $getLeafNodes,\n $getRoot,\n $getSelection,\n $insertNodes,\n $isRangeSelection,\n $normalizeSelection__EXPERIMENTAL,\n $setSelection,\n COMMAND_PRIORITY_CRITICAL,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\nimport { $createSentinelNode, $isSentinelNode, SentinelNode } from './SentinelNode';\n\nexport interface IBasicFunctionalityBase {\n insertDefaultValue: (defaultValue: string) => void;\n setIsDisabled: (isDisabled: boolean) => void;\n activateContentCallbacks(onContentChange?: (value: string) => void, onCountChanged?: (count: number) => void): void;\n deactivateContentCallbacks(): void;\n activateTrimWhitespace(): void;\n deactivateTrimWhitespace(): void;\n activatePasteCallback(onPaste: (event: ClipboardEvent) => void): void;\n deactivatePasteCallback(): void;\n cleanup(): void;\n}\n\nexport class BasicFunctionalityBase implements IBasicFunctionalityBase {\n private __editor: LexicalEditor;\n private __contentChangeCleanup?: () => void;\n private __trimWhitespaceCleanup?: () => void;\n private __baseHandlersCleanup?: () => void;\n private __pasteHandlerCleanup?: () => void;\n\n private __enterHandler(event: KeyboardEvent) {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return false;\n }\n\n if (event === null) {\n return false;\n }\n\n event.preventDefault();\n\n if (event.shiftKey) {\n return this.__editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined);\n }\n\n // Mark event handled to override default behavior\n return true;\n }\n\n constructor(editor: LexicalEditor) {\n this.__editor = editor;\n\n this.__baseHandlersCleanup = mergeRegister(\n this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_CRITICAL),\n\n // Add a sentinel node at the end of the input when there is content.\n // This sentinel node fixes a number of issues.\n // In Safari, Lexical's behaviour of adding <br /> tags to the end of the input when it ends\n // in a decorator node causes cursor location issues: https://github.com/facebook/lexical/issues/4487\n // Otherwise, when a decorator node is the last node in the input, the cursor can't move past it.\n // Adding an invisible text node that doesn't contribute to the content and can't be selected to the end of the input\n // mitigates these issues.\n this.__editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const leaves = $getLeafNodes($getRoot());\n if (leaves.length === 0) {\n return;\n }\n\n const sentinel = leaves[leaves.length - 1];\n\n // If the last node isn't a sentinel, add one\n if (!$isSentinelNode(sentinel)) {\n this.__editor.update(\n () => {\n sentinel.insertAfter($createSentinelNode());\n },\n { discrete: true },\n );\n return;\n }\n\n // If the sentinel node is not selected, we're done\n const previous = sentinel.getPreviousSibling();\n if (!previous || !sentinel.isSelected()) {\n return;\n }\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n // If the cursor is inside the sentinel node, move it out (next to the beginning)\n // We allow selection on the boundary of the sentinel in case the adjacent node is a decorator node\n // where selection is ill-defined.\n if (selection.isCollapsed() && selection.anchor.offset > 0) {\n this.__editor.update(\n () => {\n sentinel.selectStart();\n },\n { discrete: true },\n );\n return;\n }\n\n // If the selection is a range which includes the sentinel, modify the range to exclude it\n if (!selection.isCollapsed()) {\n let selectionChanged = false;\n const newSelection = selection.clone();\n\n if (newSelection.anchor.getNode() === sentinel && newSelection.anchor.offset > 0) {\n newSelection.anchor.set(sentinel.getKey(), 0, 'text');\n selectionChanged = true;\n }\n if (newSelection.focus.getNode() === sentinel && newSelection.focus.offset > 0) {\n newSelection.focus.set(sentinel.getKey(), 0, 'text');\n selectionChanged = true;\n }\n\n if (selectionChanged) {\n this.__editor.update(\n () => {\n $setSelection($normalizeSelection__EXPERIMENTAL(newSelection));\n },\n { discrete: true },\n );\n }\n }\n });\n }),\n this.__editor.registerNodeTransform(SentinelNode, node => {\n if (!node.getPreviousSibling() || node.getNextSibling()) {\n node.remove();\n return;\n }\n }),\n );\n }\n\n insertDefaultValue(defaultValue: string) {\n if (defaultValue) {\n this.__editor.update(() => {\n $insertNodes([$createTextNode(defaultValue)]);\n });\n }\n }\n\n activateContentCallbacks(\n onContentChange?: ((value: string) => void) | undefined,\n onCountChanged?: ((count: number) => void) | undefined,\n ) {\n this.deactivateContentCallbacks();\n this.__contentChangeCleanup = this.__editor.registerTextContentListener(text => {\n // Remove the sentinel node\n const processed = text.replace('\\u200b\\u200c', '');\n onContentChange?.(processed);\n onCountChanged?.(processed.length);\n });\n }\n\n deactivateContentCallbacks() {\n this.__contentChangeCleanup?.();\n this.__contentChangeCleanup = undefined;\n }\n\n activatePasteCallback(onPaste: (event: ClipboardEvent) => void) {\n this.__pasteHandlerCleanup = this.__editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n onPaste(event);\n\n if (event.defaultPrevented) {\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n }\n\n deactivatePasteCallback() {\n this.__pasteHandlerCleanup?.();\n this.__pasteHandlerCleanup = undefined;\n }\n\n activateTrimWhitespace() {\n this.deactivateTrimWhitespace();\n this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener(text => {\n if (text.trim() === '') {\n this.__editor.update(\n () => {\n $getRoot()\n .getAllTextNodes()\n .forEach(node => {\n node.remove();\n });\n },\n // Don't allow undoing this action\n { tag: 'historic' },\n );\n }\n });\n }\n\n deactivateTrimWhitespace() {\n this.__trimWhitespaceCleanup?.();\n this.__trimWhitespaceCleanup = undefined;\n }\n\n setIsDisabled(isDisabled: boolean) {\n this.__editor.setEditable(!isDisabled);\n }\n\n cleanup() {\n this.deactivateContentCallbacks();\n this.deactivateTrimWhitespace();\n this.deactivatePasteCallback();\n this.__baseHandlersCleanup?.();\n this.__baseHandlersCleanup = undefined;\n }\n}\n"],"names":["BasicFunctionalityBase","__enterHandler","event","selection","$getSelection","$isRangeSelection","preventDefault","shiftKey","__editor","dispatchCommand","INSERT_PARAGRAPH_COMMAND","insertDefaultValue","defaultValue","update","$insertNodes","onContentChange","onCountChanged","deactivateContentCallbacks","activateContentCallbacks","text","processed","__contentChangeCleanup","registerTextContentListener","length","_this___contentChangeCleanup","_this","call","undefined","__pasteHandlerCleanup","registerCommand","PASTE_COMMAND","activatePasteCallback","onPaste","COMMAND_PRIORITY_CRITICAL","_this___pasteHandlerCleanup","deactivatePasteCallback","deactivateTrimWhitespace","activateTrimWhitespace","__trimWhitespaceCleanup","trim","forEach","node","remove","_this___trimWhitespaceCleanup","isDisabled","setIsDisabled","cleanup","__baseHandlersCleanup","_this___baseHandlersCleanup","editor","constructor","registerUpdateListener","editorState","read","leaves","$getLeafNodes","$getRoot","$isSentinelNode","sentinel","insertAfter","discrete","getPreviousSibling","isSelected","selectStart","anchor","offset","isCollapsed","newSelection","set","selectionChanged","getKey","focus","$setSelection","SentinelNode","getNextSibling"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ $createSentinelNode: function() {
13
+ return $createSentinelNode;
14
+ },
15
+ $isSentinelNode: function() {
16
+ return $isSentinelNode;
17
+ },
18
+ SentinelNode: function() {
19
+ return SentinelNode;
20
+ }
21
+ });
22
+ const _texteditor = require("@fluentui-copilot/text-editor");
23
+ class SentinelNode extends _texteditor.TextNode {
24
+ static getType() {
25
+ return 'sentinel';
26
+ }
27
+ static clone(node) {
28
+ return new SentinelNode(node.__key);
29
+ }
30
+ isToken() {
31
+ return true;
32
+ }
33
+ constructor(key){
34
+ // 2 zero width characters will not be visible in the editor.
35
+ // These also happen to be markers for CIQ to ignore the following content.
36
+ super('\u200b\u200c', key);
37
+ }
38
+ }
39
+ function $createSentinelNode(key) {
40
+ return new SentinelNode(key);
41
+ }
42
+ function $isSentinelNode(node) {
43
+ return node instanceof SentinelNode;
44
+ } //# sourceMappingURL=SentinelNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["SentinelNode.ts"],"sourcesContent":["import type { LexicalNode, NodeKey } from '@fluentui-copilot/text-editor';\nimport { TextNode } from '@fluentui-copilot/text-editor';\n\nexport class SentinelNode extends TextNode {\n constructor(key?: NodeKey) {\n // 2 zero width characters will not be visible in the editor.\n // These also happen to be markers for CIQ to ignore the following content.\n super('\\u200b\\u200c', key);\n }\n\n static getType() {\n return 'sentinel';\n }\n static clone(node: SentinelNode) {\n return new SentinelNode(node.__key);\n }\n\n isToken() {\n return true;\n }\n}\n\nexport function $createSentinelNode(key?: NodeKey) {\n return new SentinelNode(key);\n}\n\nexport function $isSentinelNode(node: LexicalNode | null): node is SentinelNode {\n return node instanceof SentinelNode;\n}\n"],"names":["$createSentinelNode","$isSentinelNode","SentinelNode","TextNode","getType","clone","node","__key","isToken","constructor","key"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAsBgBA,mBAAAA;eAAAA;;IAIAC,eAAAA;eAAAA;;IAvBHC,YAAAA;eAAAA;;;4BAFY;AAElB,MAAMA,qBAAqBC,oBAAAA;WAOhCC,UAAOA;eACL;;WAEFC,MAAOA,IAAMC,EAAkB;eAC7B,IAAOJ,aAAIA,KAAaI,KAAKC;;cAG/BC;eACE;;gBAdFC,GAAYC,CAAa;qEACvB;mFACA;aACA,CAAA,gBAAMA;;AAaV;AAEO,SAASV,oBAAoBU,GAAa;WAC/C,IAAOR,aAAIA;AACb;AAEO,SAASD,gBAAgBK,IAAwB;WACtDA,gBAAOA;AACT"}
@@ -4,4 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  const _export_star = require("@swc/helpers/_/_export_star");
6
6
  _export_star._(require("./BasicFunctionality.base"), exports);
7
+ _export_star._(require("./SentinelNode"), exports);
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"sourcesContent":["export * from './BasicFunctionality.base';\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":";;;;;uBAAc;CACd,iCAAiC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './BasicFunctionality.base';\nexport * from './SentinelNode';\n"],"names":[],"rangeMappings":";;;;;;","mappings":";;;;;uBAAc;uBACA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ChatInputEntityPlugin.base.js"],"sourcesContent":["import { _ as _define_property } from \"@swc/helpers/_/_define_property\";\nimport { $createParagraphNode, $createTextNode, $getNodeByKey, $getSelection, $insertNodes, $isDecoratorNode, $isRangeSelection, $isRootOrShadowRoot, $nodesOfType, $wrapNodeInElement, COMMAND_PRIORITY_CRITICAL, DELETE_CHARACTER_COMMAND, mergeRegister } from '@fluentui-copilot/text-editor';\nexport class ChatInputEntityPluginBase {\n cleanup() {\n this._cleanup();\n }\n insertChatInputEntity(props) {\n let key = undefined;\n this.__editor.update(() => {\n const {\n text,\n data,\n entityProps\n } = props;\n const entityNode = this.__$createNode(this.__id, text, data, entityProps);\n $insertNodes([entityNode]);\n entityNode.selectEnd();\n if ($isRootOrShadowRoot(entityNode.getParentOrThrow())) {\n $wrapNodeInElement(entityNode, $createParagraphNode).selectEnd();\n }\n key = entityNode.getKey();\n });\n return key;\n }\n removeChatInputEntity(keyOrPredicate) {\n this.__editor.update(() => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass).filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i)).forEach(node => node.remove());\n } else {\n var _$getNodeByKey;\n (_$getNodeByKey = $getNodeByKey(keyOrPredicate)) === null || _$getNodeByKey === void 0 ? void 0 : _$getNodeByKey.remove();\n }\n });\n }\n updateChatInputEntityProps(keyOrPredicate, props) {\n const updateNode = node => {\n const newProps = typeof props === 'function' ? props(node.getEntityData()) : props;\n node.updateEntityData(newProps);\n };\n this.__editor.update(() => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass).filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i)).forEach(updateNode);\n } else {\n const node = $getNodeByKey(keyOrPredicate);\n if (node) {\n updateNode(node);\n }\n }\n }, {\n tag: 'historic'\n });\n }\n getActiveEntities() {\n return this.__editor.getEditorState().read(() => $nodesOfType(this.__nodeClass).filter(node => node.__pluginId === this.__id).map(node => node.getEntityData()));\n }\n constructor(editor, id, nodeClass, $createNode, $isChatInputEntityNode, onChatInputEntityAdded, onChatInputEntityDeleted) {\n _define_property(this, \"__nodeClass\", void 0);\n _define_property(this, \"__editor\", void 0);\n _define_property(this, \"__id\", void 0);\n _define_property(this, \"__deleteDirection\", null);\n _define_property(this, \"__$createNode\", void 0);\n _define_property(this, \"_cleanup\", void 0);\n this.__$createNode = $createNode;\n this.__editor = editor;\n this.__id = id;\n this.__nodeClass = nodeClass;\n this._cleanup = mergeRegister(\n // Keep track of delete direction so we know where to put the selection after adding back a space\n editor.registerCommand(DELETE_CHARACTER_COMMAND, isBackward => {\n this.__deleteDirection = isBackward ? 'backward' : 'forward';\n return false;\n }, COMMAND_PRIORITY_CRITICAL),\n // Always maintain a space before, after, and between entities in order for selection to work properly\n editor.registerNodeTransform(this.__nodeClass, node => {\n const nextSibling = node.getNextSibling();\n if (!nextSibling || $isDecoratorNode(nextSibling)) {\n const selection = $getSelection();\n // If selection is between the two nodes, that means the user is trying to delete the space\n // If they deleted to the left, we should move the cursor to the end of the entity\n // If they delete to the right, we should move the cursor to the end of the newly added space\n // This mimics changing the delete into a cursor move action\n const shouldMoveSelection = selection && $isRangeSelection(selection) && selection.isCollapsed() && selection.anchor.offset === node.getIndexWithinParent() + 1;\n const text = $createTextNode(' ');\n node.insertAfter(text);\n if (shouldMoveSelection) {\n if (this.__deleteDirection === 'forward') {\n text.selectEnd();\n } else {\n node.selectEnd();\n }\n }\n }\n // In the case the entity is the first node, we need a space before it.\n if (!node.getPreviousSibling()) {\n const text = $createTextNode(' ');\n node.insertBefore(text);\n }\n }), onChatInputEntityAdded || onChatInputEntityDeleted ? editor.registerMutationListener(this.__nodeClass, (nodes, payload) => {\n for (const [nodeKey, mutation] of nodes) {\n if (onChatInputEntityDeleted && mutation === 'destroyed') {\n payload.prevEditorState.read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityDeleted(node.getEntityData());\n }\n });\n } else if (onChatInputEntityAdded && mutation === 'created') {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityAdded(node.getEntityData());\n }\n });\n }\n }\n }) : noop);\n }\n}\nfunction noop() {\n return;\n}\n//# sourceMappingURL=ChatInputEntityPlugin.base.js.map"],"names":["ChatInputEntityPluginBase","cleanup","_cleanup","insertChatInputEntity","props","key","undefined","__editor","update","text","data","entityProps","entityNode","__$createNode","__id","$insertNodes","selectEnd","$isRootOrShadowRoot","getParentOrThrow","$wrapNodeInElement","$createParagraphNode","getKey","removeChatInputEntity","keyOrPredicate","$nodesOfType","__nodeClass","filter","node","i","__pluginId","getEntityData","forEach","remove","_$getNodeByKey","$getNodeByKey","updateChatInputEntityProps","updateNode","newProps","updateEntityData","tag","getActiveEntities","getEditorState","read","map","constructor","editor","id","nodeClass","$createNode","$isChatInputEntityNode","onChatInputEntityAdded","onChatInputEntityDeleted","_define_property","mergeRegister","registerCommand","DELETE_CHARACTER_COMMAND","isBackward","__deleteDirection","COMMAND_PRIORITY_CRITICAL","registerNodeTransform","nextSibling","getNextSibling","$isDecoratorNode","selection","$getSelection","shouldMoveSelection","$isRangeSelection","isCollapsed","anchor","offset","getIndexWithinParent","$createTextNode","insertAfter","getPreviousSibling","insertBefore","registerMutationListener","nodes","payload","nodeKey","mutation","prevEditorState","noop"],"mappings":"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"}
1
+ {"version":3,"sources":["ChatInputEntityPlugin.base.ts"],"sourcesContent":["import type { LexicalEditor, LexicalNode, NodeKey, Klass } from '@fluentui-copilot/text-editor';\nimport {\n $createParagraphNode,\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $insertNodes,\n $isDecoratorNode,\n $isRangeSelection,\n $isRootOrShadowRoot,\n $nodesOfType,\n $wrapNodeInElement,\n COMMAND_PRIORITY_CRITICAL,\n DELETE_CHARACTER_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\nimport type { ChatInputEntityData, IChatInputEntityPluginBase, IEntityNode } from './ChatInputEntityPlugin.types';\n\nexport class ChatInputEntityPluginBase<\n ExtraDataType,\n NodePropsType,\n NodeType extends IEntityNode<ExtraDataType, NodePropsType>,\n> implements IChatInputEntityPluginBase<ExtraDataType, NodePropsType>\n{\n private __nodeClass: Klass<NodeType>;\n private __editor: LexicalEditor;\n private __id: string;\n\n private __deleteDirection: 'forward' | 'backward' | null = null;\n private __$createNode: (\n pluginId: string,\n text: string,\n data?: ExtraDataType,\n entityProps?: NodePropsType,\n key?: NodeKey,\n ) => NodeType;\n\n private _cleanup: () => void;\n\n cleanup() {\n this._cleanup();\n }\n\n constructor(\n editor: LexicalEditor,\n id: string,\n nodeClass: Klass<NodeType>,\n $createNode: (\n pluginId: string,\n text: string,\n data?: ExtraDataType,\n entityProps?: NodePropsType,\n key?: NodeKey,\n ) => NodeType,\n $isChatInputEntityNode: (node: LexicalNode | null) => node is NodeType,\n onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void,\n onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void,\n ) {\n this.__$createNode = $createNode;\n this.__editor = editor;\n this.__id = id;\n this.__nodeClass = nodeClass;\n\n this._cleanup = mergeRegister(\n // Keep track of delete direction so we know where to put the selection after adding back a space\n editor.registerCommand(\n DELETE_CHARACTER_COMMAND,\n isBackward => {\n this.__deleteDirection = isBackward ? 'backward' : 'forward';\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n ),\n // Always maintain a space before, after, and between entities in order for selection to work properly\n editor.registerNodeTransform(this.__nodeClass, node => {\n const nextSibling = node.getNextSibling();\n if (!nextSibling || $isDecoratorNode(nextSibling)) {\n const selection = $getSelection();\n\n // If selection is between the two nodes, that means the user is trying to delete the space\n // If they deleted to the left, we should move the cursor to the end of the entity\n // If they delete to the right, we should move the cursor to the end of the newly added space\n // This mimics changing the delete into a cursor move action\n const shouldMoveSelection =\n selection &&\n $isRangeSelection(selection) &&\n selection.isCollapsed() &&\n selection.anchor.offset === node.getIndexWithinParent() + 1;\n const text = $createTextNode(' ');\n node.insertAfter(text);\n if (shouldMoveSelection) {\n if (this.__deleteDirection === 'forward') {\n text.selectEnd();\n } else {\n node.selectEnd();\n }\n }\n }\n\n // In the case the entity is the first node, we need a space before it.\n if (!node.getPreviousSibling()) {\n const text = $createTextNode(' ');\n node.insertBefore(text);\n }\n }),\n onChatInputEntityAdded || onChatInputEntityDeleted\n ? editor.registerMutationListener(this.__nodeClass, (nodes, payload) => {\n for (const [nodeKey, mutation] of nodes) {\n if (onChatInputEntityDeleted && mutation === 'destroyed') {\n payload.prevEditorState.read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityDeleted(node.getEntityData());\n }\n });\n } else if (onChatInputEntityAdded && mutation === 'created') {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isChatInputEntityNode(node) && node.__pluginId === id) {\n onChatInputEntityAdded(node.getEntityData());\n }\n });\n }\n }\n })\n : noop,\n );\n }\n insertChatInputEntity(props: ChatInputEntityData<ExtraDataType, NodePropsType>): string | undefined {\n let key: string | undefined = undefined;\n this.__editor.update(() => {\n const { text, data, entityProps } = props;\n\n const entityNode = this.__$createNode(this.__id, text, data, entityProps);\n\n $insertNodes([entityNode]);\n entityNode.selectEnd();\n if ($isRootOrShadowRoot(entityNode.getParentOrThrow())) {\n $wrapNodeInElement(entityNode, $createParagraphNode).selectEnd();\n }\n\n key = entityNode.getKey();\n });\n\n return key;\n }\n removeChatInputEntity(\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n ) {\n this.__editor.update(() => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass)\n .filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i))\n .forEach(node => node.remove());\n } else {\n $getNodeByKey(keyOrPredicate)?.remove();\n }\n });\n }\n updateChatInputEntityProps(\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n props:\n | ChatInputEntityData<ExtraDataType, NodePropsType>\n | ((\n oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>,\n ) => ChatInputEntityData<ExtraDataType, NodePropsType>),\n ) {\n const updateNode = (node: NodeType) => {\n const newProps = typeof props === 'function' ? props(node.getEntityData()) : props;\n node.updateEntityData(newProps);\n };\n\n this.__editor.update(\n () => {\n if (typeof keyOrPredicate === 'function') {\n $nodesOfType(this.__nodeClass)\n .filter((node, i) => node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i))\n .forEach(updateNode);\n } else {\n const node = $getNodeByKey<NodeType>(keyOrPredicate);\n if (node) {\n updateNode(node);\n }\n }\n },\n { tag: 'historic' },\n );\n }\n\n getActiveEntities(): ChatInputEntityData<ExtraDataType, NodePropsType>[] {\n return this.__editor.getEditorState().read(() =>\n $nodesOfType(this.__nodeClass)\n .filter(node => node.__pluginId === this.__id)\n .map(node => node.getEntityData()),\n );\n }\n}\n\nfunction noop() {\n return;\n}\n"],"names":["ChatInputEntityPluginBase","cleanup","_cleanup","insertChatInputEntity","props","key","__editor","update","$insertNodes","entityNode","selectEnd","__id","text","data","entityProps","$isRootOrShadowRoot","$wrapNodeInElement","getParentOrThrow","$createParagraphNode","removeChatInputEntity","keyOrPredicate","$nodesOfType","$getNodeByKey","_$getNodeByKey","remove","updateChatInputEntityProps","updateEntityData","newProps","node","getEntityData","updateNode","tag","getActiveEntities","constructor","editor","id","$createNode","$isChatInputEntityNode","onChatInputEntityAdded","onChatInputEntityDeleted","map","nodeClass","__deleteDirection","__$createNode","__nodeClass","registerCommand","COMMAND_PRIORITY_CRITICAL","isBackward","registerNodeTransform","$isDecoratorNode","$getSelection","getNextSibling","nextSibling","isCollapsed","$isRangeSelection","selection","anchor","offset","getIndexWithinParent","$createTextNode","mutation","nodeKey","read","getEditorState","__pluginId","noop"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ChatInputEntityPlugin.types.js"],"sourcesContent":["export {};\n//# sourceMappingURL=ChatInputEntityPlugin.types.js.map"],"names":[],"mappings":";;;;CACA,uDAAuD"}
1
+ {"version":3,"sources":["ChatInputEntityPlugin.types.ts"],"sourcesContent":["import type { LexicalNode } from '@fluentui-copilot/text-editor';\n\nexport type ChatInputEntityData<ExtraDataType, NodePropsType> = {\n // Represents the string content of the entity that will returned inside the ChatInput's text content\n text: string;\n // Props to pass to the component rendered by the node\n // By default, `text` will be used as the entity's text content.\n // If entityProps contains information for rendering children, that will take priority\n entityProps?: NodePropsType;\n // Optional extra data that can be associated with the entity\n data?: ExtraDataType;\n};\n\nexport type ChatInputEntityPluginProps<ExtraDataType, NodePropsType> = {\n // An identifier for an instance of the ChatInputEntityPlugin\n // Only entities created by this instance of the plugin will be handled by it\n id: string;\n onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n};\n\n/**\n * A lexical node representing an entity should conform to this interface\n */\nexport interface IEntityNode<ExtraDataType, NodePropsType> extends LexicalNode {\n getEntityData: () => ChatInputEntityData<ExtraDataType, NodePropsType>;\n updateEntityData: (data: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;\n __pluginId: string;\n}\n\nexport interface IChatInputEntityPluginBase<ExtraDataType, NodePropsType> {\n // Inserts a new entity and returns its key, to be used by removeChatInputEntity or updateChatInputEntityProps\n insertChatInputEntity: (props: ChatInputEntityData<ExtraDataType, NodePropsType>) => string | undefined;\n // Removes an entity by its key, or removes all entities that match a predicate function\n removeChatInputEntity: (\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n ) => void;\n // Updates an entity by its key, or removes all entities that match a predicate function\n updateChatInputEntityProps: (\n keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean),\n props:\n | ChatInputEntityData<ExtraDataType, NodePropsType>\n | ((\n oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>,\n ) => ChatInputEntityData<ExtraDataType, NodePropsType>),\n ) => void;\n getActiveEntities: () => ChatInputEntityData<ExtraDataType, NodePropsType>[];\n}\n"],"names":[],"rangeMappings":"","mappings":""}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"sourcesContent":["export * from './ChatInputEntityPlugin.types';\nexport * from './ChatInputEntityPlugin.base';\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":";;;;;uBAAc;uBACA;CACd,iCAAiC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ChatInputEntityPlugin.types';\nexport * from './ChatInputEntityPlugin.base';\n"],"names":[],"rangeMappings":";;;;;;","mappings":";;;;;uBAAc;uBACA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["GhostText.base.js"],"sourcesContent":["import { _ as _define_property } from \"@swc/helpers/_/_define_property\";\nimport { $createTextNode, $getNodeByKey, $getSelection, $setSelection, COMMAND_PRIORITY_LOW, KEY_TAB_COMMAND, mergeRegister } from '@fluentui-copilot/text-editor';\nexport class GhostTextPluginBase {\n cleanup() {\n var _this___cleanup, _this;\n (_this___cleanup = (_this = this).__cleanup) === null || _this___cleanup === void 0 ? void 0 : _this___cleanup.call(_this);\n }\n setExposeText(exposeText) {\n this.__exposeText = exposeText;\n }\n setComponentProps(componentProps) {\n this.__componentProps = componentProps;\n }\n setGetGhostText($getGhostText) {\n this.__$getGhostText = $getGhostText;\n }\n setAllowCompletion(allowCompletion) {\n this.__allowCompletion = allowCompletion;\n }\n constructor(editor, id, $getGhostText, nodeClass, createNode, componentProps,\n // Whether or not the ghost text should count as text inside the input for submitting and character count\n exposeText, allowCompletion) {\n _define_property(this, \"__id\", void 0);\n _define_property(this, \"__$getGhostText\", void 0);\n _define_property(this, \"__componentProps\", void 0);\n _define_property(this, \"__exposeText\", void 0);\n _define_property(this, \"__allowCompletion\", void 0);\n _define_property(this, \"__cleanup\", void 0);\n this.__id = id;\n this.__$getGhostText = $getGhostText;\n this.__componentProps = componentProps;\n this.__exposeText = exposeText;\n this.__allowCompletion = allowCompletion;\n let ghostTextNodeKey = null;\n let lastText = undefined;\n let justRemovedGhostText = false;\n function $clearGhostText() {\n const ghostTextNode = ghostTextNodeKey !== null ? $getNodeByKey(ghostTextNodeKey) : null;\n ghostTextNodeKey = null;\n lastText = undefined;\n if (ghostTextNode && ghostTextNode.isAttached()) {\n ghostTextNode.remove();\n }\n }\n function handleGhostTextNodeTransform(node) {\n const key = node.getKey();\n if (node.__id === id && key !== ghostTextNodeKey) {\n // Only one ghost text\n node.remove();\n $clearGhostText();\n }\n }\n const handleGhostTextResponse = text => {\n if (text === lastText) {\n return;\n }\n editor.update(() => {\n $clearGhostText();\n const selection = $getSelection();\n if (!text || !selection) {\n justRemovedGhostText = true;\n return;\n }\n const selectionCopy = selection.clone();\n const node = createNode(this.__id, text, this.__exposeText, this.__componentProps);\n ghostTextNodeKey = node.getKey();\n lastText = text;\n selection.insertNodes([node]);\n $setSelection(selectionCopy);\n }, {\n tag: 'historic'\n });\n };\n const handleUpdate = props => {\n const {\n editorState,\n prevEditorState\n } = props;\n // If this update was caused by deleting the previous ghost text, don't create a new one until a subsequent update\n if (justRemovedGhostText) {\n justRemovedGhostText = false;\n return;\n }\n editorState.read(() => {\n const promise = this.__$getGhostText(editor, editorState, prevEditorState);\n promise.then(handleGhostTextResponse).catch(e => console.error(e));\n });\n };\n function unmountGhostText() {\n if (ghostTextNodeKey) {\n editor.update(() => {\n $clearGhostText();\n }, {\n tag: 'historic'\n });\n }\n }\n function $handleTabCommand(e) {\n if (ghostTextNodeKey === null || lastText === null) {\n return false;\n }\n const ghostTextNode = $getNodeByKey(ghostTextNodeKey);\n if (!ghostTextNode) {\n return false;\n }\n e.preventDefault();\n const textNode = $createTextNode(lastText);\n ghostTextNode.replace(textNode);\n textNode.selectEnd();\n $clearGhostText();\n return true;\n }\n this.__cleanup = mergeRegister(editor.registerNodeTransform(nodeClass, handleGhostTextNodeTransform), editor.registerUpdateListener(handleUpdate), this.__allowCompletion ? editor.registerCommand(KEY_TAB_COMMAND, $handleTabCommand, COMMAND_PRIORITY_LOW) : noop, unmountGhostText);\n }\n}\nfunction noop() {\n return;\n}\n//# sourceMappingURL=GhostText.base.js.map"],"names":["GhostTextPluginBase","cleanup","_this___cleanup","_this","__cleanup","call","setExposeText","exposeText","__exposeText","setComponentProps","componentProps","__componentProps","setGetGhostText","$getGhostText","__$getGhostText","setAllowCompletion","allowCompletion","__allowCompletion","constructor","editor","id","nodeClass","createNode","_define_property","__id","ghostTextNodeKey","lastText","undefined","justRemovedGhostText","$clearGhostText","ghostTextNode","$getNodeByKey","isAttached","remove","handleGhostTextNodeTransform","node","key","getKey","handleGhostTextResponse","text","update","selection","$getSelection","selectionCopy","clone","insertNodes","$setSelection","tag","handleUpdate","props","editorState","prevEditorState","read","promise","then","catch","e","console","error","unmountGhostText","$handleTabCommand","preventDefault","textNode","$createTextNode","replace","selectEnd","mergeRegister","registerNodeTransform","registerUpdateListener","registerCommand","KEY_TAB_COMMAND","COMMAND_PRIORITY_LOW","noop"],"mappings":"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"}
1
+ {"version":3,"sources":["GhostText.base.ts"],"sourcesContent":["import type { EditorState, Klass, LexicalEditor, LexicalNode, UpdateListener } from '@fluentui-copilot/text-editor';\nimport {\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n KEY_TAB_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\n\nexport type GetGhostTextFunction = (\n editor: LexicalEditor,\n editorState: EditorState,\n prevEditorState: EditorState,\n) => Promise<string | undefined>;\n\nexport interface IGhostTextNode<ComponentPropsType> extends LexicalNode {\n __content: string;\n __id: string;\n __allowCommitting?: boolean;\n __componentProps?: ComponentPropsType;\n __exposeText?: boolean;\n}\n\nexport class GhostTextPluginBase<ComponentPropsType> {\n private __id: string;\n private __$getGhostText: GetGhostTextFunction;\n private __componentProps?: ComponentPropsType;\n private __exposeText?: boolean;\n private __allowCompletion?: boolean;\n\n private __cleanup?: () => void;\n\n cleanup() {\n this.__cleanup?.();\n }\n\n constructor(\n editor: LexicalEditor,\n id: string,\n $getGhostText: GetGhostTextFunction,\n nodeClass: Klass<IGhostTextNode<ComponentPropsType>>,\n createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>,\n componentProps?: ComponentPropsType,\n // Whether or not the ghost text should count as text inside the input for submitting and character count\n exposeText?: boolean,\n allowCompletion?: boolean,\n ) {\n this.__id = id;\n this.__$getGhostText = $getGhostText;\n this.__componentProps = componentProps;\n this.__exposeText = exposeText;\n this.__allowCompletion = allowCompletion;\n\n let ghostTextNodeKey: string | null = null;\n let lastText: string | undefined = undefined;\n let justRemovedGhostText = false;\n\n function $clearGhostText() {\n const ghostTextNode = ghostTextNodeKey !== null ? $getNodeByKey(ghostTextNodeKey) : null;\n ghostTextNodeKey = null;\n lastText = undefined;\n if (ghostTextNode && ghostTextNode.isAttached()) {\n ghostTextNode.remove();\n }\n }\n function handleGhostTextNodeTransform(node: IGhostTextNode<ComponentPropsType>) {\n const key = node.getKey();\n\n if (node.__id === id && key !== ghostTextNodeKey) {\n // Only one ghost text\n node.remove();\n $clearGhostText();\n }\n }\n\n const handleGhostTextResponse = (text?: string) => {\n if (text === lastText) {\n return;\n }\n\n editor.update(\n () => {\n $clearGhostText();\n\n const selection = $getSelection();\n if (!text || !selection) {\n justRemovedGhostText = true;\n return;\n }\n\n const selectionCopy = selection.clone();\n\n const node = createNode(this.__id, text, this.__exposeText, this.__componentProps);\n ghostTextNodeKey = node.getKey();\n lastText = text;\n\n selection.insertNodes([node]);\n $setSelection(selectionCopy);\n },\n { tag: 'historic' },\n );\n };\n\n const handleUpdate: UpdateListener = props => {\n const { editorState, prevEditorState } = props;\n // If this update was caused by deleting the previous ghost text, don't create a new one until a subsequent update\n if (justRemovedGhostText) {\n justRemovedGhostText = false;\n return;\n }\n editorState.read(() => {\n const promise = this.__$getGhostText(editor, editorState, prevEditorState);\n promise.then(handleGhostTextResponse).catch(e => console.error(e));\n });\n };\n\n function unmountGhostText() {\n if (ghostTextNodeKey) {\n editor.update(\n () => {\n $clearGhostText();\n },\n { tag: 'historic' },\n );\n }\n }\n\n function $handleTabCommand(e: KeyboardEvent) {\n if (ghostTextNodeKey === null || lastText === null) {\n return false;\n }\n\n const ghostTextNode = $getNodeByKey(ghostTextNodeKey);\n if (!ghostTextNode) {\n return false;\n }\n\n e.preventDefault();\n\n const textNode = $createTextNode(lastText);\n ghostTextNode.replace(textNode);\n textNode.selectEnd();\n $clearGhostText();\n return true;\n }\n\n this.__cleanup = mergeRegister(\n editor.registerNodeTransform(nodeClass, handleGhostTextNodeTransform),\n editor.registerUpdateListener(handleUpdate),\n this.__allowCompletion ? editor.registerCommand(KEY_TAB_COMMAND, $handleTabCommand, COMMAND_PRIORITY_LOW) : noop,\n unmountGhostText,\n );\n }\n\n setExposeText(exposeText?: boolean) {\n this.__exposeText = exposeText;\n }\n\n setComponentProps(componentProps?: ComponentPropsType) {\n this.__componentProps = componentProps;\n }\n\n setGetGhostText($getGhostText: GetGhostTextFunction) {\n this.__$getGhostText = $getGhostText;\n }\n\n setAllowCompletion(allowCompletion?: boolean) {\n this.__allowCompletion = allowCompletion;\n }\n}\nfunction noop(): void {\n return;\n}\n"],"names":["GhostTextPluginBase","cleanup","_this","__cleanup","_this___cleanup","call","setExposeText","exposeText","__exposeText","setComponentProps","componentProps","__componentProps","setGetGhostText","$getGhostText","__$getGhostText","setAllowCompletion","allowCompletion","__allowCompletion","constructor","editor","id","nodeClass","createNode","__id","ghostTextNodeKey","undefined","lastText","justRemovedGhostText","$clearGhostText","$getNodeByKey","ghostTextNode","isAttached","remove","handleGhostTextNodeTransform","node","key","text","selection","clone","getKey","selectionCopy","handleUpdate","props","promise","editorState","prevEditorState","then","handleGhostTextResponse","catch","e","console","error","preventDefault","textNode","selectEnd","mergeRegister","registerNodeTransform","registerUpdateListener","registerCommand","KEY_TAB_COMMAND","$handleTabCommand","COMMAND_PRIORITY_LOW","noop","unmountGhostText"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAyBaA;;;eAAAA;;;;4BAhBN;AAgBA,MAAMA;cASXC;6BACEC;2BAAA,AAAAA,CAAAA,QAAA,IAAA,EAAAC,SAAKA,MAAS,QAAAC,oBAAd,KAAA,IAAA,KAAA,IAAAA,gBAAAC,IAAA,CAAAH;;kBA8HFI,UAAcC,EAAoB;YAChC,CAAAC,YAAKA,GAAAA;;sBAGPC,cAAkBC,EAAmC;YACnD,CAAAC,gBAAKA,GAAAA;;oBAGPC,aAAgBC,EAAmC;YACjD,CAAAC,eAAKA,GAAAA;;uBAGPC,eAAmBC,EAAyB;YAC1C,CAAAC,iBAAKA,GAAAA;;gBAxIPC,MACEC,EAAqBC,EACrBA,EAAUP,aACVA,EAAmCQ,SACnCA,EAAoDC,UACpDA,EAKuCZ,cACvCA,2GAIA;cA3BF,EAAAM,eAAA,CAAQO;8BACR,EAAA,IAAA,EAAA,QAAQT,KAAAA;8BACR,EAAA,IAAA,EAAA,mBAAQH,KAAR;8BACA,EAAA,IAAA,EAAA,oBAAA,KAAA;8BACA,EAAA,IAAA,EAAA,gBAAQM,KAAAA;8BAER,EAAA,IAAA,EAAA,qBAAA,KAAA;8BAsBcG,EAAAA,IAAAA,EAAAA,aAAAA,KAAAA;YACZ,CAAAG,IAAKT,GAAAA;YACL,CAAAA,eAAKH,GAAAA;YACL,CAAAA,gBAAiB,GAAGJ;YACpB,CAAAC,YAAKS,GAAAA;YAEL,CAAAA,iBAAIO,GAAAA;YACJA,mBAAmCC;YACnCC,WAAIC;YAEJA,uBAASC;iBACPA;kBACAJ,gBAAAA,qBAAmB,OAAAK,IAAAA,yBAAA,EAAAL,oBAAA;+BACRC;uBACPK;iCACFA,cAAoBC,UAAA,IAAA;8BACtBC,MAAA;;;iBAGAC,6BAAuBC,IAAA;kBAEvBC,MAAID,KAAKX,MAAI;yBACX,KAAAH,MAAAe,QAAsBX,kBAAA;sCACX;2BACXI;;;;wCAKqBQ,CAAAA;yBACrBV,UAAA;;;yBAKEE,CAAAA;;kCAGKQ,IAAAA,yBAASC;6BACZV,CAAAA,WAAAA;2CACA;;;sCAKWL,UAAWgB,KAAKf;6BAC7BC,WAAAA,IAAmBU,CAAAA,IAAKK,EAAAA,MAAM,IAAA,CAAA/B,YAAA,EAAA,IAAA,CAAAG,gBAAA;mCACnByB,KAAAA,MAAAA;2BAEXC;qCAAuBH,CAAAA;oBAAAA;iBAAAA;6CAAK,EAAAM;;qBAE9B;;;cAGJC,eAAAC,CAAAA;kBAEA,aACQ,iBACN;8HAEyB;sCACvB;uCACF;;;wBAGEC,IAAAA,CAAAA;sBACFA,UAAA,IAAA,CAAA7B,eAAA,CAAAK,QAAAyB,aAAAC;gBACFF,QAAAG,IAAA,CAAAC,yBAAAC,KAAA,CAAAC,CAAAA,IAAAC,QAAAC,KAAA,CAAAF;;;;kCAMQrB;6BAEF,CAAA;;;yBAEJ;gBACF;;;mCAIWqB,CAAA;qCACT,QAAAvB,aAAA,MAAA;uBAEA;;kCAESG,IAAAA,yBAAA,EAAAL;gCACT;uBAEE4B;;4BAGFtB;kBACAuB,WAASC,IAAAA,2BAAS,EAAA5B;0BAClBE,OAAAA,CAAAA;qBACA0B,SAAO;;mBAGJnD;QAMP;QAiBF,IAAA,CAAAA,SAAA,GAAAoD,IAAAA,yBAAA,EAAApC,OAAAqC,qBAAA,CAAAnC,WAAAY,+BAAAd,OAAAsC,sBAAA,CAAAhB,eAAA,IAAA,CAAAxB,iBAAA,GAAAE,OAAAuC,eAAA,CAAAC,2BAAA,EAAAC,mBAAAC,gCAAA,IAAAC,MAAAC;IACA;;AAEA,SAAAD"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"sourcesContent":["export * from './GhostText.base';\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":";;;;;uBAAc;CACd,iCAAiC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './GhostText.base';\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;uBAAc"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ImperativeControl.base.js"],"sourcesContent":["import { _ as _define_property } from \"@swc/helpers/_/_define_property\";\nimport { $createParagraphNode, $createRangeSelection, $createTextNode, $getLeafNodes, $getRoot, $getSelection, $isTextNode, $normalizeSelection__EXPERIMENTAL, $setSelection } from '@fluentui-copilot/text-editor';\nexport class ImperativeControlBase {\n moveCursor(location) {\n this.__editor.update(() => {\n const children = $getLeafNodes($getRoot());\n let baseOffset = 0;\n let currentNode = children.shift();\n while (baseOffset < location && currentNode) {\n const nodeLength = $isTextNode(currentNode) && !currentNode.isToken() ? currentNode.getTextContent().length : 1;\n if (baseOffset + nodeLength >= location) {\n const elementType = $isTextNode(currentNode) ? 'text' : 'element';\n const localOffset = location - baseOffset;\n const nodeKey = currentNode.getKey();\n const selection = $createRangeSelection();\n selection.anchor.set(nodeKey, localOffset, elementType);\n selection.focus.set(nodeKey, localOffset, elementType);\n $setSelection($normalizeSelection__EXPERIMENTAL(selection));\n return;\n }\n baseOffset += nodeLength;\n currentNode = children.shift();\n }\n if (location > baseOffset) {\n $getRoot().selectEnd();\n }\n });\n }\n setInputText(inputText) {\n this.__editor.update(() => {\n const root = $getRoot();\n root.clear();\n if (inputText !== '') {\n const newParagraph = $createParagraphNode();\n const newText = $createTextNode(inputText);\n newParagraph.append(newText);\n root.append(newParagraph);\n root.selectEnd();\n }\n });\n }\n appendText(text) {\n this.__editor.update(() => {\n $getRoot().selectEnd().insertText(text);\n });\n }\n prependText(text) {\n this.__editor.update(() => {\n $getRoot().selectStart().insertText(text);\n });\n }\n insertTextAtCursor(text) {\n this.__editor.update(() => {\n var _$getSelection;\n (_$getSelection = $getSelection()) === null || _$getSelection === void 0 ? void 0 : _$getSelection.insertText(text);\n });\n }\n getInputText() {\n return this.__editor.getEditorState().read(() => {\n return $getRoot().getTextContent();\n });\n }\n scrollToBottom() {\n var _this___editor_getRootElement;\n (_this___editor_getRootElement = this.__editor.getRootElement()) === null || _this___editor_getRootElement === void 0 ? void 0 : _this___editor_getRootElement.scrollIntoView({\n behavior: 'smooth',\n block: 'end'\n });\n return;\n }\n constructor(editor) {\n _define_property(this, \"__editor\", void 0);\n this.__editor = editor;\n }\n}\n//# sourceMappingURL=ImperativeControl.base.js.map"],"names":["ImperativeControlBase","moveCursor","location","__editor","update","children","$getLeafNodes","$getRoot","baseOffset","currentNode","shift","nodeLength","$isTextNode","isToken","getTextContent","length","elementType","localOffset","nodeKey","getKey","selection","$createRangeSelection","anchor","set","focus","$setSelection","$normalizeSelection__EXPERIMENTAL","selectEnd","setInputText","inputText","root","clear","newParagraph","$createParagraphNode","newText","$createTextNode","append","appendText","text","insertText","prependText","selectStart","insertTextAtCursor","_$getSelection","$getSelection","getInputText","getEditorState","read","scrollToBottom","_this___editor_getRootElement","getRootElement","scrollIntoView","behavior","block","constructor","editor","_define_property"],"mappings":";;;;+BAEaA;;;eAAAA;;;iCAFyB;4BAC8I;AAC7K,MAAMA;IACXC,WAAWC,QAAQ,EAAE;QACnB,IAAI,CAACC,QAAQ,CAACC,MAAM,CAAC;YACnB,MAAMC,WAAWC,IAAAA,yBAAa,EAACC,IAAAA,oBAAQ;YACvC,IAAIC,aAAa;YACjB,IAAIC,cAAcJ,SAASK,KAAK;YAChC,MAAOF,aAAaN,YAAYO,YAAa;gBAC3C,MAAME,aAAaC,IAAAA,uBAAW,EAACH,gBAAgB,CAACA,YAAYI,OAAO,KAAKJ,YAAYK,cAAc,GAAGC,MAAM,GAAG;gBAC9G,IAAIP,aAAaG,cAAcT,UAAU;oBACvC,MAAMc,cAAcJ,IAAAA,uBAAW,EAACH,eAAe,SAAS;oBACxD,MAAMQ,cAAcf,WAAWM;oBAC/B,MAAMU,UAAUT,YAAYU,MAAM;oBAClC,MAAMC,YAAYC,IAAAA,iCAAqB;oBACvCD,UAAUE,MAAM,CAACC,GAAG,CAACL,SAASD,aAAaD;oBAC3CI,UAAUI,KAAK,CAACD,GAAG,CAACL,SAASD,aAAaD;oBAC1CS,IAAAA,yBAAa,EAACC,IAAAA,6CAAiC,EAACN;oBAChD;gBACF;gBACAZ,cAAcG;gBACdF,cAAcJ,SAASK,KAAK;YAC9B;YACA,IAAIR,WAAWM,YAAY;gBACzBD,IAAAA,oBAAQ,IAAGoB,SAAS;YACtB;QACF;IACF;IACAC,aAAaC,SAAS,EAAE;QACtB,IAAI,CAAC1B,QAAQ,CAACC,MAAM,CAAC;YACnB,MAAM0B,OAAOvB,IAAAA,oBAAQ;YACrBuB,KAAKC,KAAK;YACV,IAAIF,cAAc,IAAI;gBACpB,MAAMG,eAAeC,IAAAA,gCAAoB;gBACzC,MAAMC,UAAUC,IAAAA,2BAAe,EAACN;gBAChCG,aAAaI,MAAM,CAACF;gBACpBJ,KAAKM,MAAM,CAACJ;gBACZF,KAAKH,SAAS;YAChB;QACF;IACF;IACAU,WAAWC,IAAI,EAAE;QACf,IAAI,CAACnC,QAAQ,CAACC,MAAM,CAAC;YACnBG,IAAAA,oBAAQ,IAAGoB,SAAS,GAAGY,UAAU,CAACD;QACpC;IACF;IACAE,YAAYF,IAAI,EAAE;QAChB,IAAI,CAACnC,QAAQ,CAACC,MAAM,CAAC;YACnBG,IAAAA,oBAAQ,IAAGkC,WAAW,GAAGF,UAAU,CAACD;QACtC;IACF;IACAI,mBAAmBJ,IAAI,EAAE;QACvB,IAAI,CAACnC,QAAQ,CAACC,MAAM,CAAC;YACnB,IAAIuC;YACHA,CAAAA,iBAAiBC,IAAAA,yBAAa,GAAC,MAAO,QAAQD,mBAAmB,KAAK,IAAI,KAAK,IAAIA,eAAeJ,UAAU,CAACD;QAChH;IACF;IACAO,eAAe;QACb,OAAO,IAAI,CAAC1C,QAAQ,CAAC2C,cAAc,GAAGC,IAAI,CAAC;YACzC,OAAOxC,IAAAA,oBAAQ,IAAGO,cAAc;QAClC;IACF;IACAkC,iBAAiB;QACf,IAAIC;QACHA,CAAAA,gCAAgC,IAAI,CAAC9C,QAAQ,CAAC+C,cAAc,EAAC,MAAO,QAAQD,kCAAkC,KAAK,IAAI,KAAK,IAAIA,8BAA8BE,cAAc,CAAC;YAC5KC,UAAU;YACVC,OAAO;QACT;QACA;IACF;IACAC,YAAYC,MAAM,CAAE;QAClBC,IAAAA,kBAAgB,EAAC,IAAI,EAAE,YAAY,KAAK;QACxC,IAAI,CAACrD,QAAQ,GAAGoD;IAClB;AACF,EACA,kDAAkD"}
1
+ {"version":3,"sources":["ImperativeControl.base.ts"],"sourcesContent":["import type { LexicalEditor } from '@fluentui-copilot/text-editor';\nimport {\n $createParagraphNode,\n $createRangeSelection,\n $createTextNode,\n $getLeafNodes,\n $getRoot,\n $getSelection,\n $isTextNode,\n $normalizeSelection__EXPERIMENTAL,\n $setSelection,\n} from '@fluentui-copilot/text-editor';\n\nexport interface IImperativeControlBase {\n setInputText: (inputText: string) => void;\n appendText: (text: string) => void;\n prependText: (text: string) => void;\n insertTextAtCursor: (text: string) => void;\n getInputText: () => string;\n scrollToBottom: () => void;\n moveCursor: (location: number) => void;\n}\n\nexport class ImperativeControlBase implements IImperativeControlBase {\n private __editor: LexicalEditor;\n\n constructor(editor: LexicalEditor) {\n this.__editor = editor;\n }\n\n moveCursor(location: number): void {\n this.__editor.update(() => {\n const children = $getLeafNodes($getRoot());\n\n let baseOffset = 0;\n let currentNode = children.shift();\n while (baseOffset < location && currentNode) {\n const nodeLength =\n $isTextNode(currentNode) && !currentNode.isToken()\n ? currentNode.getTextContent().length\n : // Token text nodes and non-text nodes are considered to be a single entry in the input\n 1;\n\n if (baseOffset + nodeLength >= location) {\n const elementType = $isTextNode(currentNode) ? 'text' : 'element';\n const localOffset = location - baseOffset;\n const nodeKey = currentNode.getKey();\n\n const selection = $createRangeSelection();\n selection.anchor.set(nodeKey, localOffset, elementType);\n selection.focus.set(nodeKey, localOffset, elementType);\n\n $setSelection($normalizeSelection__EXPERIMENTAL(selection));\n return;\n }\n\n baseOffset += nodeLength;\n currentNode = children.shift();\n }\n\n if (location > baseOffset) {\n $getRoot().selectEnd();\n }\n });\n }\n setInputText(inputText: string) {\n this.__editor.update(() => {\n const root = $getRoot();\n root.clear();\n if (inputText !== '') {\n const newParagraph = $createParagraphNode();\n const newText = $createTextNode(inputText);\n\n newParagraph.append(newText);\n root.append(newParagraph);\n root.selectEnd();\n }\n });\n }\n appendText(text: string) {\n this.__editor.update(() => {\n $getRoot().selectEnd().insertText(text);\n });\n }\n prependText(text: string) {\n this.__editor.update(() => {\n $getRoot().selectStart().insertText(text);\n });\n }\n insertTextAtCursor(text: string) {\n this.__editor.update(() => {\n $getSelection()?.insertText(text);\n });\n }\n getInputText() {\n return this.__editor.getEditorState().read(() => {\n return $getRoot().getTextContent();\n });\n }\n scrollToBottom() {\n this.__editor.getRootElement()?.scrollIntoView({ behavior: 'smooth', block: 'end' });\n return;\n }\n}\n"],"names":["ImperativeControlBase","moveCursor","location","__editor","update","children","$getLeafNodes","$getRoot","baseOffset","currentNode","nodeLength","$isTextNode","isToken","getTextContent","length","elementType","localOffset","nodeKey","selection","$createRangeSelection","anchor","focus","$setSelection","$normalizeSelection__EXPERIMENTAL","selectEnd","setInputText","inputText","root","newParagraph","$createParagraphNode","newText","$createTextNode","appendText","text","insertText","prependText","selectStart","insertTextAtCursor","$getSelection","getInputText","getEditorState","read","scrollToBottom","getRootElement","_this___editor_getRootElement","scrollIntoView","behavior","block","constructor","editor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAuBaA;;;eAAAA;;;;4BAZN;AAYA,MAAMA;eAOXC,QAAWC,EAAgB;YACzB,CAAAC,QAAKA,CAAAA,MAASC,CAAAA;kBACZC,WAAMA,IAAAA,yBAAWC,EAAAA,IAAAA,oBAAcC;6BAE3BC;8BACAC,SAAcJ,KAAAA;kBAClBG,aAAOA,YAAaN,YAAYO;mCACxBC,IAAAA,uBACJC,EAAAA,gBAAYF,CAAAA,YAAiBA,OAAAA,KAAYG,YACrCH,cAAYI,GAAAA,MAAc,GAAGC;iCAI/BN,cAAaE,UAAcR;wCACvBa,IAAAA,uBAAcJ,EAAAA,eAAYF,SAAAA;wCAC1BO,WAAcd;oCACde,YAAUR,MAAAA;sCAEVS,IAAAA,iCAAYC;8BAClBD,MAAAA,CAAAA,GAAUE,CAAAA,SAAUJ,aAAUA;8BAC9BE,KAAAA,CAAAA,GAAAA,CAAUG,SAASL,aAAUA;iDAE7BM,EAAAA,IAAAA,6CAAcC,EAAAA;;;8BAIhBf;8BACAC,SAAcJ,KAAAA;;2BAGZH,YAAWM;wCACbD,IAAAA,SAAWiB;;;;iBAIjBC,SAAaC,EAAiB;YAC5B,CAAAvB,QAAKA,CAAAA,MAASC,CAAAA;kBACZuB,OAAMA,IAAAA,oBAAOpB;sBACboB;8BACID,IAAAA;qCACIE,IAAAA,gCAAeC;gCACfC,IAAAA,2BAAUC,EAAAA;6BAEhBH,MAAAA,CAAAA;2BACAD,CAAAA;8BACKH;;;;eAIXQ,IAAWC,EAAY;YACrB,CAAA9B,QAAKA,CAAAA,MAASC,CAAAA;oCACZG,IAAAA,SAAWiB,GAAAA,UAAYU,CAAAA;;;gBAG3BC,IAAYF,EAAY;YACtB,CAAA9B,QAAKA,CAAAA,MAASC,CAAAA;oCACZG,IAAAA,WAAW6B,GAAAA,UAAcF,CAAAA;;;uBAG7BG,IAAmBJ,EAAY;YAC7B,CAAA9B,QAAKA,CAAAA,MAASC,CAAAA;;8BACZkC,IAAAA,yBAAAA,GAAAA,MAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAAA,UAAiBJ,CAAAA;;;mBAGrBK;eACE,IAAO,CAAApC,QAAKA,CAAAA,cAASqC,GAAAA,IAAiBC,CAAAA;mBACpClC,IAAAA,oBAAOA,IAAAA,cAAWM;;;qBAGtB6B;;yCACE,IAAA,CAAAvC,QAAKA,CAAAA,cAASwC,EAAAA,MAAc,QAAAC,kCAA5B,KAAA,IAAA,KAAA,IAAAA,8BAAAC,cAAgCA,CAAAA;sBAAiBC;mBAAoBC;;;;gBA1EvEC,MAAYC,CAAqB;8BAFjC,EAAA,IAAA,EAAA,YAAQ9C,KAAR;YAGE,CAAAA,QAAKA,GAAAA;;AA4ET"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"sourcesContent":["export * from './ImperativeControl.base';\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":";;;;;uBAAc;CACd,iCAAiC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ImperativeControl.base';\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;uBAAc"}
@@ -1 +1 @@
1
- {"version":3,"sources":["ManualGhostText.base.js"],"sourcesContent":["import { _ as _define_property } from \"@swc/helpers/_/_define_property\";\nimport { $createTextNode, $getNodeByKey, $insertNodes } from '@fluentui-copilot/text-editor';\nexport class ManualGhostTextBase {\n getGhostText() {\n return this.__editor.getEditorState().read(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n return node.__content;\n }\n }\n });\n }\n setGhostText(text, exposeText, componentProps) {\n this.__editor.update(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.getWritable().__content = text;\n return;\n }\n }\n const node = this.__$createNode(this.__id, text, exposeText, componentProps);\n this.__nodeKey = node.getKey();\n $insertNodes([node]);\n node.selectStart();\n }, {\n tag: 'historic'\n });\n }\n commitGhostText(finalText) {\n if (this.__nodeKey) {\n this.__editor.update(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n const textNode = $createTextNode(finalText);\n node.replace(textNode);\n textNode.selectEnd();\n }\n }\n });\n this.__nodeKey = undefined;\n }\n }\n cancelGhostText() {\n if (this.__nodeKey) {\n this.__editor.update(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.remove();\n }\n }\n }, {\n tag: 'historic'\n });\n this.__nodeKey = undefined;\n }\n }\n constructor(editor, id, $isNodeType, $createNode) {\n _define_property(this, \"__editor\", void 0);\n _define_property(this, \"__nodeKey\", void 0);\n _define_property(this, \"__id\", void 0);\n _define_property(this, \"__$isNodeType\", void 0);\n _define_property(this, \"__$createNode\", void 0);\n this.__editor = editor;\n this.__id = id;\n this.__$isNodeType = $isNodeType;\n this.__$createNode = $createNode;\n }\n}\n//# sourceMappingURL=ManualGhostText.base.js.map"],"names":["ManualGhostTextBase","getGhostText","__editor","getEditorState","read","__nodeKey","node","$getNodeByKey","__$isNodeType","__content","setGhostText","text","exposeText","componentProps","update","getWritable","__$createNode","__id","getKey","$insertNodes","selectStart","tag","commitGhostText","finalText","textNode","$createTextNode","replace","selectEnd","undefined","cancelGhostText","remove","constructor","editor","id","$isNodeType","$createNode","_define_property"],"mappings":";;;;+BAEaA;;;eAAAA;;;iCAFyB;4BACuB;AACtD,MAAMA;IACXC,eAAe;QACb,OAAO,IAAI,CAACC,QAAQ,CAACC,cAAc,GAAGC,IAAI,CAAC;YACzC,IAAI,IAAI,CAACC,SAAS,EAAE;gBAClB,MAAMC,OAAOC,IAAAA,yBAAa,EAAC,IAAI,CAACF,SAAS;gBACzC,IAAI,IAAI,CAACG,aAAa,CAACF,OAAO;oBAC5B,OAAOA,KAAKG,SAAS;gBACvB;YACF;QACF;IACF;IACAC,aAAaC,IAAI,EAAEC,UAAU,EAAEC,cAAc,EAAE;QAC7C,IAAI,CAACX,QAAQ,CAACY,MAAM,CAAC;YACnB,IAAI,IAAI,CAACT,SAAS,EAAE;gBAClB,MAAMC,OAAOC,IAAAA,yBAAa,EAAC,IAAI,CAACF,SAAS;gBACzC,IAAI,IAAI,CAACG,aAAa,CAACF,OAAO;oBAC5BA,KAAKS,WAAW,GAAGN,SAAS,GAAGE;oBAC/B;gBACF;YACF;YACA,MAAML,OAAO,IAAI,CAACU,aAAa,CAAC,IAAI,CAACC,IAAI,EAAEN,MAAMC,YAAYC;YAC7D,IAAI,CAACR,SAAS,GAAGC,KAAKY,MAAM;YAC5BC,IAAAA,wBAAY,EAAC;gBAACb;aAAK;YACnBA,KAAKc,WAAW;QAClB,GAAG;YACDC,KAAK;QACP;IACF;IACAC,gBAAgBC,SAAS,EAAE;QACzB,IAAI,IAAI,CAAClB,SAAS,EAAE;YAClB,IAAI,CAACH,QAAQ,CAACY,MAAM,CAAC;gBACnB,IAAI,IAAI,CAACT,SAAS,EAAE;oBAClB,MAAMC,OAAOC,IAAAA,yBAAa,EAAC,IAAI,CAACF,SAAS;oBACzC,IAAI,IAAI,CAACG,aAAa,CAACF,OAAO;wBAC5B,MAAMkB,WAAWC,IAAAA,2BAAe,EAACF;wBACjCjB,KAAKoB,OAAO,CAACF;wBACbA,SAASG,SAAS;oBACpB;gBACF;YACF;YACA,IAAI,CAACtB,SAAS,GAAGuB;QACnB;IACF;IACAC,kBAAkB;QAChB,IAAI,IAAI,CAACxB,SAAS,EAAE;YAClB,IAAI,CAACH,QAAQ,CAACY,MAAM,CAAC;gBACnB,IAAI,IAAI,CAACT,SAAS,EAAE;oBAClB,MAAMC,OAAOC,IAAAA,yBAAa,EAAC,IAAI,CAACF,SAAS;oBACzC,IAAI,IAAI,CAACG,aAAa,CAACF,OAAO;wBAC5BA,KAAKwB,MAAM;oBACb;gBACF;YACF,GAAG;gBACDT,KAAK;YACP;YACA,IAAI,CAAChB,SAAS,GAAGuB;QACnB;IACF;IACAG,YAAYC,MAAM,EAAEC,EAAE,EAAEC,WAAW,EAAEC,WAAW,CAAE;QAChDC,IAAAA,kBAAgB,EAAC,IAAI,EAAE,YAAY,KAAK;QACxCA,IAAAA,kBAAgB,EAAC,IAAI,EAAE,aAAa,KAAK;QACzCA,IAAAA,kBAAgB,EAAC,IAAI,EAAE,QAAQ,KAAK;QACpCA,IAAAA,kBAAgB,EAAC,IAAI,EAAE,iBAAiB,KAAK;QAC7CA,IAAAA,kBAAgB,EAAC,IAAI,EAAE,iBAAiB,KAAK;QAC7C,IAAI,CAAClC,QAAQ,GAAG8B;QAChB,IAAI,CAACf,IAAI,GAAGgB;QACZ,IAAI,CAACzB,aAAa,GAAG0B;QACrB,IAAI,CAAClB,aAAa,GAAGmB;IACvB;AACF,EACA,gDAAgD"}
1
+ {"version":3,"sources":["ManualGhostText.base.ts"],"sourcesContent":["import {\n $createTextNode,\n $getNodeByKey,\n $insertNodes,\n type LexicalEditor,\n type LexicalNode,\n} from '@fluentui-copilot/text-editor';\nimport type { IGhostTextNode } from '../GhostText';\n\nexport interface IManualGhostTextBase<ComponentPropsType> {\n getGhostText: () => string | undefined;\n setGhostText: (text: string, componentProps?: ComponentPropsType) => void;\n commitGhostText: (finalText: string) => void;\n cancelGhostText: () => void;\n}\n\nexport class ManualGhostTextBase<ComponentPropsType> {\n private __editor: LexicalEditor;\n private __nodeKey?: string;\n\n private __id: string;\n private __$isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>;\n private __$createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>;\n\n constructor(\n editor: LexicalEditor,\n id: string,\n $isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>,\n $createNode: (\n id: string,\n content: string,\n exposeText?: boolean,\n componentProps?: ComponentPropsType,\n ) => IGhostTextNode<ComponentPropsType>,\n ) {\n this.__editor = editor;\n this.__id = id;\n this.__$isNodeType = $isNodeType;\n this.__$createNode = $createNode;\n }\n\n getGhostText(): string | undefined {\n return this.__editor.getEditorState().read(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n return node.__content;\n }\n }\n });\n }\n\n setGhostText(text: string, exposeText?: boolean, componentProps?: ComponentPropsType): void {\n this.__editor.update(\n () => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.getWritable().__content = text;\n return;\n }\n }\n\n const node = this.__$createNode(this.__id, text, exposeText, componentProps);\n this.__nodeKey = node.getKey();\n $insertNodes([node]);\n node.selectStart();\n },\n { tag: 'historic' },\n );\n }\n\n commitGhostText(finalText: string): void {\n if (this.__nodeKey) {\n this.__editor.update(() => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n const textNode = $createTextNode(finalText);\n node.replace(textNode);\n textNode.selectEnd();\n }\n }\n });\n this.__nodeKey = undefined;\n }\n }\n\n cancelGhostText(): void {\n if (this.__nodeKey) {\n this.__editor.update(\n () => {\n if (this.__nodeKey) {\n const node = $getNodeByKey(this.__nodeKey);\n if (this.__$isNodeType(node)) {\n node.remove();\n }\n }\n },\n { tag: 'historic' },\n );\n this.__nodeKey = undefined;\n }\n }\n}\n"],"names":["ManualGhostTextBase","getGhostText","__editor","getEditorState","read","__nodeKey","$getNodeByKey","__$isNodeType","__content","node","setGhostText","text","exposeText","componentProps","update","getWritable","__$createNode","__id","getKey","$insertNodes","finalText","commitGhostText","textNode","undefined","cancelGhostText","tag","editor","id","$isNodeType","$createNode","_define_property","constructor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAgBaA;;;eAAAA;;;;4BAVN;AAUA,MAAMA;mBA8BXC;eACE,IAAO,CAAAC,QAAKA,CAAAA,cAASC,GAAAA,IAAiBC,CAAAA;oBACpC,CAAAC,SAASA,EAAAA;6BACPC,IAAAA,yBAAaA,EAAAA,IAAAA,CAAAA,SAAmBD;wBAChC,CAAAE,aAASA,CAAAA,OAAa;gCACpBC,SAAOC;;;;;iBAMfC,IAAaC,EAAYC,UAAEA,EAAoBC,cAAEA,EAAmC;YAClF,CAAAX,QAAKA,CAAAA,MAASY,CAAAA;oBAEV,CAAAT,SAASA,EAAAA;6BACPC,IAAAA,yBAAaA,EAAAA,IAAAA,CAAAA,SAAmBD;wBAChC,CAAAE,aAASA,CAAAA,OAAa;oCACfQ,GAAAA,SAAW,GAAGP;;;;kBAKvBC,OAAMA,IAAAA,CAAAA,aAAYO,CAAAA,IAAAA,CAAaC,IAAC,EAAKA,MAAMN,YAAMC;0BAC5CP,GAAAA,KAASa,MAAQA;wCACtBC,EAAAA;gBAAAA;aAAa;4BAACV;;;;;oBAGEW,SAAA,EAAA;QAEtB,IAAA,IAAA,CAAAf,SAAA,EAAA;YAEAgB,IAAAA,CAAAA,QAAAA,CAAgBD,MAAAA,CAAAA;gBACd,IAAI,IAAI,CAACf,SAAS,EAAE;0BACdI,OAACP,IAAAA,yBAAgB,EAAA,IAAA,CAAAG,SAAA;4BACnB,CAAAE,aAASF,CAAAA,OAAW;yCACZI,IAAAA,2BAAOH,EAAAA;oCACT,CAAAgB;0CACIA;;;;0BAIV,GAAAC;;;sBAGJ;QACF,IAAA,IAAA,CAAAlB,SAAA,EAAA;YAEAmB,IAAAA,CAAAA,QAAAA,CAAAA,MAAwB,CAAA;gBACtB,IAAI,IAAI,CAACnB,SAAS,EAAE;0BACdI,OAACP,IAAAA,yBACH,EAAA,IAAA,CAAAG,SAAA;4BACE,CAAAE,aAASF,CAAAA,OAAW;mCAClB;;;;;;0BAMFoB,GAAKF;;;gBAGXG,MAAA,EAAAC,EAAA,EAAAC,WAAA,EAAAC,WAAA,CAAA;QACFC,IAAAA,kBAAA,EAAA,IAAA,EAAA,YAAA,KAAA;QA/EAC,IAAAA,kBACEL,EAAAA,IACAC,EAAU,aAC2E,KACrFE;8BAhBF,EAAA,IAAA,EAAA,QAAQ3B,KAAAA;8BACR,EAAA,IAAA,EAAA,iBAAA,KAAA;8BAEA,EAAA,IAAA,EAAA,iBAAA,KAAA;YACA,CAAAA,QAAA,GAAAwB;YACA,CAAAT,IAAA,GAAAU;YAkBE,CAAApB,aAAa,GAAGmB;YAChB,CAAAV,aAAYW,GAAAA;;kDAGd"}
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"sourcesContent":["export * from './ManualGhostText.base';\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":";;;;;uBAAc;CACd,iCAAiC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export * from './ManualGhostText.base';\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;uBAAc"}
@@ -9,6 +9,12 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ $createSentinelNode: function() {
13
+ return _BasicFunctionality.$createSentinelNode;
14
+ },
15
+ $isSentinelNode: function() {
16
+ return _BasicFunctionality.$isSentinelNode;
17
+ },
12
18
  BasicFunctionalityBase: function() {
13
19
  return _BasicFunctionality.BasicFunctionalityBase;
14
20
  },
@@ -23,6 +29,9 @@ _export(exports, {
23
29
  },
24
30
  ManualGhostTextBase: function() {
25
31
  return _ManualGhostText.ManualGhostTextBase;
32
+ },
33
+ SentinelNode: function() {
34
+ return _BasicFunctionality.SentinelNode;
26
35
  }
27
36
  });
28
37
  const _BasicFunctionality = require("./BasicFunctionality");
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"sourcesContent":["export { BasicFunctionalityBase } from './BasicFunctionality';\nexport { ChatInputEntityPluginBase } from './ChatInputEntity';\nexport { GhostTextPluginBase } from './GhostText';\nexport { ImperativeControlBase } from './ImperativeControl';\nexport { ManualGhostTextBase } from './ManualGhostText';\n//# sourceMappingURL=index.js.map"],"names":["BasicFunctionalityBase","ChatInputEntityPluginBase","GhostTextPluginBase","ImperativeControlBase","ManualGhostTextBase"],"mappings":";;;;;;;;;;;IAASA,sBAAsB;eAAtBA,0CAAsB;;IACtBC,yBAAyB;eAAzBA,0CAAyB;;IACzBC,mBAAmB;eAAnBA,8BAAmB;;IACnBC,qBAAqB;eAArBA,wCAAqB;;IACrBC,mBAAmB;eAAnBA,oCAAmB;;;oCAJW;iCACG;2BACN;mCACE;iCACF;CACpC,iCAAiC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export { BasicFunctionalityBase, SentinelNode, $createSentinelNode, $isSentinelNode } from './BasicFunctionality';\nexport type { IBasicFunctionalityBase } from './BasicFunctionality';\n\nexport { ChatInputEntityPluginBase } from './ChatInputEntity';\nexport type {\n ChatInputEntityData,\n ChatInputEntityPluginProps,\n IChatInputEntityPluginBase,\n IEntityNode,\n} from './ChatInputEntity';\n\nexport { GhostTextPluginBase } from './GhostText';\nexport type { GetGhostTextFunction, IGhostTextNode } from './GhostText';\n\nexport { ImperativeControlBase } from './ImperativeControl';\nexport type { IImperativeControlBase } from './ImperativeControl';\n\nexport { ManualGhostTextBase } from './ManualGhostText';\nexport type { IManualGhostTextBase } from './ManualGhostText';\n"],"names":["$createSentinelNode","$isSentinelNode","BasicFunctionalityBase","ChatInputEntityPluginBase","GhostTextPluginBase","ImperativeControlBase","ManualGhostTextBase","SentinelNode"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAA+CA,mBAAmB;eAAnBA,uCAAmB;;IAAEC,eAAe;eAAfA,mCAAe;;IAA1EC,sBAAsB;eAAtBA,0CAAsB;;IAGtBC,yBAAyB;eAAzBA,0CAAyB;;IAQzBC,mBAAmB;eAAnBA,8BAAmB;;IAGnBC,qBAAqB;eAArBA,wCAAqB;;IAGrBC,mBAAmB;eAAnBA,oCAAmB;;IAjBKC,YAAY;eAAZA,gCAAY;;;oCAA8C;iCAGjD;2BAQN;mCAGE;iCAGF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-copilot/chat-input-plugins",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "A Fluent AI package for non-react specific chat input plugins.",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
- "@fluentui-copilot/text-editor": "^0.0.2",
15
+ "@fluentui-copilot/text-editor": "^0.0.3",
16
16
  "@swc/helpers": "^0.5.1"
17
17
  },
18
18
  "beachball": {