@fluentui-copilot/chat-input-plugins 0.0.0-nightly-20251002-0405-17b34fb7.1 → 0.0.0-nightly-20251010-0406-7df7c6d1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.json +3 -3
  2. package/CHANGELOG.md +4 -4
  3. package/package.json +2 -2
  4. package/dist/index.d.ts +0 -192
  5. package/lib/BasicFunctionality/BasicFunctionality.base.js +0 -107
  6. package/lib/BasicFunctionality/BasicFunctionality.base.js.map +0 -1
  7. package/lib/BasicFunctionality/SentinelNode.js +0 -41
  8. package/lib/BasicFunctionality/SentinelNode.js.map +0 -1
  9. package/lib/BasicFunctionality/SentinelNodeHandlers.js +0 -79
  10. package/lib/BasicFunctionality/SentinelNodeHandlers.js.map +0 -1
  11. package/lib/BasicFunctionality/index.js +0 -2
  12. package/lib/BasicFunctionality/index.js.map +0 -1
  13. package/lib/ChatInputEntity/ChatInputEntityPlugin.base.js +0 -117
  14. package/lib/ChatInputEntity/ChatInputEntityPlugin.base.js.map +0 -1
  15. package/lib/ChatInputEntity/ChatInputEntityPlugin.types.js +0 -1
  16. package/lib/ChatInputEntity/ChatInputEntityPlugin.types.js.map +0 -1
  17. package/lib/ChatInputEntity/index.js +0 -1
  18. package/lib/ChatInputEntity/index.js.map +0 -1
  19. package/lib/GhostText/GhostText.base.js +0 -158
  20. package/lib/GhostText/GhostText.base.js.map +0 -1
  21. package/lib/GhostText/index.js +0 -1
  22. package/lib/GhostText/index.js.map +0 -1
  23. package/lib/ImperativeControl/ImperativeControl.base.js +0 -87
  24. package/lib/ImperativeControl/ImperativeControl.base.js.map +0 -1
  25. package/lib/ImperativeControl/index.js +0 -1
  26. package/lib/ImperativeControl/index.js.map +0 -1
  27. package/lib/ManualGhostText/ManualGhostText.base.js +0 -78
  28. package/lib/ManualGhostText/ManualGhostText.base.js.map +0 -1
  29. package/lib/ManualGhostText/index.js +0 -1
  30. package/lib/ManualGhostText/index.js.map +0 -1
  31. package/lib/PasteUnfurling/PasteUnfurling.base.js +0 -60
  32. package/lib/PasteUnfurling/PasteUnfurling.base.js.map +0 -1
  33. package/lib/PasteUnfurling/PasteUnfurling.types.js +0 -1
  34. package/lib/PasteUnfurling/PasteUnfurling.types.js.map +0 -1
  35. package/lib/PasteUnfurling/PasteUnfurlingTestUtils.js +0 -162
  36. package/lib/PasteUnfurling/PasteUnfurlingTestUtils.js.map +0 -1
  37. package/lib/PasteUnfurling/index.js +0 -1
  38. package/lib/PasteUnfurling/index.js.map +0 -1
  39. package/lib/index.js +0 -6
  40. package/lib/index.js.map +0 -1
  41. package/lib-commonjs/BasicFunctionality/BasicFunctionality.base.js +0 -115
  42. package/lib-commonjs/BasicFunctionality/BasicFunctionality.base.js.map +0 -1
  43. package/lib-commonjs/BasicFunctionality/SentinelNode.js +0 -61
  44. package/lib-commonjs/BasicFunctionality/SentinelNode.js.map +0 -1
  45. package/lib-commonjs/BasicFunctionality/SentinelNodeHandlers.js +0 -87
  46. package/lib-commonjs/BasicFunctionality/SentinelNodeHandlers.js.map +0 -1
  47. package/lib-commonjs/BasicFunctionality/index.js +0 -29
  48. package/lib-commonjs/BasicFunctionality/index.js.map +0 -1
  49. package/lib-commonjs/ChatInputEntity/ChatInputEntityPlugin.base.js +0 -125
  50. package/lib-commonjs/ChatInputEntity/ChatInputEntityPlugin.base.js.map +0 -1
  51. package/lib-commonjs/ChatInputEntity/ChatInputEntityPlugin.types.js +0 -4
  52. package/lib-commonjs/ChatInputEntity/ChatInputEntityPlugin.types.js.map +0 -1
  53. package/lib-commonjs/ChatInputEntity/index.js +0 -11
  54. package/lib-commonjs/ChatInputEntity/index.js.map +0 -1
  55. package/lib-commonjs/GhostText/GhostText.base.js +0 -167
  56. package/lib-commonjs/GhostText/GhostText.base.js.map +0 -1
  57. package/lib-commonjs/GhostText/index.js +0 -11
  58. package/lib-commonjs/GhostText/index.js.map +0 -1
  59. package/lib-commonjs/ImperativeControl/ImperativeControl.base.js +0 -97
  60. package/lib-commonjs/ImperativeControl/ImperativeControl.base.js.map +0 -1
  61. package/lib-commonjs/ImperativeControl/index.js +0 -11
  62. package/lib-commonjs/ImperativeControl/index.js.map +0 -1
  63. package/lib-commonjs/ManualGhostText/ManualGhostText.base.js +0 -88
  64. package/lib-commonjs/ManualGhostText/ManualGhostText.base.js.map +0 -1
  65. package/lib-commonjs/ManualGhostText/index.js +0 -11
  66. package/lib-commonjs/ManualGhostText/index.js.map +0 -1
  67. package/lib-commonjs/PasteUnfurling/PasteUnfurling.base.js +0 -70
  68. package/lib-commonjs/PasteUnfurling/PasteUnfurling.base.js.map +0 -1
  69. package/lib-commonjs/PasteUnfurling/PasteUnfurling.types.js +0 -4
  70. package/lib-commonjs/PasteUnfurling/PasteUnfurling.types.js.map +0 -1
  71. package/lib-commonjs/PasteUnfurling/PasteUnfurlingTestUtils.js +0 -197
  72. package/lib-commonjs/PasteUnfurling/PasteUnfurlingTestUtils.js.map +0 -1
  73. package/lib-commonjs/PasteUnfurling/index.js +0 -11
  74. package/lib-commonjs/PasteUnfurling/index.js.map +0 -1
  75. package/lib-commonjs/index.js +0 -48
  76. package/lib-commonjs/index.js.map +0 -1
package/CHANGELOG.json CHANGED
@@ -2,9 +2,9 @@
2
2
  "name": "@fluentui-copilot/chat-input-plugins",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 02 Oct 2025 04:13:19 GMT",
6
- "tag": "@fluentui-copilot/chat-input-plugins_v0.0.0-nightly-20251002-0405-17b34fb7.1",
7
- "version": "0.0.0-nightly-20251002-0405-17b34fb7.1",
5
+ "date": "Fri, 10 Oct 2025 04:08:17 GMT",
6
+ "tag": "@fluentui-copilot/chat-input-plugins_v0.0.0-nightly-20251010-0406-7df7c6d1.1",
7
+ "version": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
8
8
  "comments": {
9
9
  "prerelease": [
10
10
  {
package/CHANGELOG.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Change Log - @fluentui-copilot/chat-input-plugins
2
2
 
3
- This log was last generated on Thu, 02 Oct 2025 04:13:19 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 10 Oct 2025 04:08:17 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## [0.0.0-nightly-20251002-0405-17b34fb7.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/chat-input-plugins_v0.0.0-nightly-20251002-0405-17b34fb7.1)
7
+ ## [0.0.0-nightly-20251010-0406-7df7c6d1.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/chat-input-plugins_v0.0.0-nightly-20251010-0406-7df7c6d1.1)
8
8
 
9
- Thu, 02 Oct 2025 04:13:19 GMT
10
- [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/chat-input-plugins_v0.5.1..@fluentui-copilot/chat-input-plugins_v0.0.0-nightly-20251002-0405-17b34fb7.1)
9
+ Fri, 10 Oct 2025 04:08:17 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/chat-input-plugins_v0.5.1..@fluentui-copilot/chat-input-plugins_v0.0.0-nightly-20251010-0406-7df7c6d1.1)
11
11
 
12
12
  ### Changes
13
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-copilot/chat-input-plugins",
3
- "version": "0.0.0-nightly-20251002-0405-17b34fb7.1",
3
+ "version": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
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.0-nightly-20251002-0405-17b34fb7.1",
15
+ "@fluentui-copilot/text-editor": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
16
16
  "@swc/helpers": "^0.5.1"
17
17
  },
18
18
  "beachball": {},
package/dist/index.d.ts DELETED
@@ -1,192 +0,0 @@
1
- import type { EditorConfig } from '@fluentui-copilot/text-editor';
2
- import type { EditorState } from '@fluentui-copilot/text-editor';
3
- import type { Klass } from '@fluentui-copilot/text-editor';
4
- import { LexicalEditor } from '@fluentui-copilot/text-editor';
5
- import { LexicalNode } from '@fluentui-copilot/text-editor';
6
- import type { NodeKey } from '@fluentui-copilot/text-editor';
7
- import type { SerializedTextNode } from '@fluentui-copilot/text-editor';
8
- import { TextNode } from '@fluentui-copilot/text-editor';
9
-
10
- export declare function $createSentinelNode(key?: NodeKey): SentinelNode;
11
-
12
- export declare function $isSentinelNode(node: LexicalNode | null): node is SentinelNode;
13
-
14
- export declare class BasicFunctionalityBase implements IBasicFunctionalityBase {
15
- private __editor;
16
- private __contentChangeCleanup?;
17
- private __trimWhitespaceCleanup?;
18
- private __baseHandlersCleanup?;
19
- private __pasteHandlerCleanup?;
20
- private __enterHandler;
21
- constructor(editor: LexicalEditor, isSentinelNodeEnabled?: boolean);
22
- activateContentCallbacks(onContentChange?: ((value: string) => void) | undefined, onCountChanged?: ((count: number) => void) | undefined): void;
23
- deactivateContentCallbacks(): void;
24
- activatePasteCallback(onPaste: (event: ClipboardEvent) => void): void;
25
- deactivatePasteCallback(): void;
26
- activateTrimWhitespace(): void;
27
- deactivateTrimWhitespace(): void;
28
- setIsDisabled(isDisabled: boolean): void;
29
- cleanup(): void;
30
- }
31
-
32
- export declare type ChatInputEntityData<ExtraDataType, NodePropsType> = {
33
- text: string;
34
- entityProps?: NodePropsType;
35
- data?: ExtraDataType;
36
- };
37
-
38
- export declare class ChatInputEntityPluginBase<ExtraDataType, NodePropsType, NodeType extends IEntityNode<ExtraDataType, NodePropsType>> implements IChatInputEntityPluginBase<ExtraDataType, NodePropsType> {
39
- private __nodeClass;
40
- private __editor;
41
- private __id;
42
- private __deleteDirection;
43
- private __$createNode;
44
- private _cleanup;
45
- cleanup(): void;
46
- constructor(editor: LexicalEditor, id: string, nodeClass: Klass<NodeType>, $createNode: (pluginId: string, text: string, data?: ExtraDataType, entityProps?: NodePropsType, key?: NodeKey) => NodeType, $isChatInputEntityNode: (node: LexicalNode | null) => node is NodeType, onChatInputEntityAdded?: ChatInputEntityPluginProps<ExtraDataType, NodePropsType>['onChatInputEntityAdded'], onChatInputEntityDeleted?: ChatInputEntityPluginProps<ExtraDataType, NodePropsType>['onChatInputEntityDeleted']);
47
- insertChatInputEntity(props: ChatInputEntityData<ExtraDataType, NodePropsType>): string | undefined;
48
- removeChatInputEntity(keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean)): void;
49
- updateChatInputEntityProps(keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean), props: ChatInputEntityData<ExtraDataType, NodePropsType> | ((oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>) => ChatInputEntityData<ExtraDataType, NodePropsType>)): void;
50
- getActiveEntities(): ChatInputEntityData<ExtraDataType, NodePropsType>[];
51
- }
52
-
53
- export declare type ChatInputEntityPluginProps<ExtraDataType, NodePropsType> = {
54
- id: string;
55
- onChatInputEntityAdded?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>, nodeKey: NodeKey) => void;
56
- onChatInputEntityDeleted?: (entity: ChatInputEntityData<ExtraDataType, NodePropsType>, nodeKey: NodeKey) => void;
57
- skipInitialization?: boolean;
58
- };
59
-
60
- export declare type GetGhostTextFunction = (editor: LexicalEditor, editorState: EditorState, prevEditorState: EditorState) => Promise<string | undefined>;
61
-
62
- export declare class GhostTextPluginBase<ComponentPropsType> {
63
- private __id;
64
- private __$getGhostText;
65
- private __componentProps?;
66
- private __exposeText?;
67
- private __allowCompletion?;
68
- private __cleanup?;
69
- cleanup(): void;
70
- constructor(editor: LexicalEditor, id: string, $getGhostText: GetGhostTextFunction, nodeClass: Klass<IGhostTextNode<ComponentPropsType>>, createNode: (id: string, content: string, exposeText?: boolean, componentProps?: ComponentPropsType) => IGhostTextNode<ComponentPropsType>, componentProps?: ComponentPropsType, exposeText?: boolean, allowCompletion?: boolean);
71
- setExposeText(exposeText?: boolean): void;
72
- setComponentProps(componentProps?: ComponentPropsType): void;
73
- setGetGhostText($getGhostText: GetGhostTextFunction): void;
74
- setAllowCompletion(allowCompletion?: boolean): void;
75
- }
76
-
77
- export declare interface IBasicFunctionalityBase {
78
- setIsDisabled: (isDisabled: boolean) => void;
79
- activateContentCallbacks(onContentChange?: (value: string) => void, onCountChanged?: (count: number) => void): void;
80
- deactivateContentCallbacks(): void;
81
- activateTrimWhitespace(): void;
82
- deactivateTrimWhitespace(): void;
83
- activatePasteCallback(onPaste: (event: ClipboardEvent) => void): void;
84
- deactivatePasteCallback(): void;
85
- cleanup(): void;
86
- }
87
-
88
- export declare interface IChatInputEntityPluginBase<ExtraDataType, NodePropsType> {
89
- insertChatInputEntity: (props: ChatInputEntityData<ExtraDataType, NodePropsType>) => string | undefined;
90
- removeChatInputEntity: (keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean)) => void;
91
- updateChatInputEntityProps: (keyOrPredicate: string | ((entity: ChatInputEntityData<ExtraDataType, NodePropsType>, i: number) => boolean), props: ChatInputEntityData<ExtraDataType, NodePropsType> | ((oldProps: ChatInputEntityData<ExtraDataType, NodePropsType>) => ChatInputEntityData<ExtraDataType, NodePropsType>)) => void;
92
- getActiveEntities: () => ChatInputEntityData<ExtraDataType, NodePropsType>[];
93
- }
94
-
95
- /**
96
- * A lexical node representing an entity should conform to this interface
97
- */
98
- export declare interface IEntityNode<ExtraDataType, NodePropsType> extends LexicalNode {
99
- getEntityData: () => ChatInputEntityData<ExtraDataType, NodePropsType>;
100
- updateEntityData: (data: ChatInputEntityData<ExtraDataType, NodePropsType>) => void;
101
- __pluginId: string;
102
- }
103
-
104
- export declare interface IGhostTextNode<ComponentPropsType> extends LexicalNode {
105
- __content: string;
106
- __id: string;
107
- __allowCommitting?: boolean;
108
- __componentProps?: ComponentPropsType;
109
- __exposeText?: boolean;
110
- }
111
-
112
- export declare interface IImperativeControlBase {
113
- setInputText: (inputText: string) => void;
114
- appendText: (text: string) => void;
115
- prependText: (text: string) => void;
116
- insertTextAtCursor: (text: string) => void;
117
- /**
118
- * @param transform will be called for each Lexical node in the input. This enables custom string representation for each node.
119
- */
120
- getInputText: (transform?: (node: LexicalNode) => string) => string;
121
- scrollToBottom: () => void;
122
- moveCursor: (location: number) => void;
123
- }
124
-
125
- export declare interface IManualGhostTextBase<ComponentPropsType> {
126
- getGhostText: () => string | undefined;
127
- setGhostText: (text: string, exposeText?: boolean, componentProps?: ComponentPropsType, discrete?: boolean) => void;
128
- commitGhostText: (finalText: string, discrete?: boolean) => void;
129
- cancelGhostText: (discrete?: boolean) => void;
130
- }
131
-
132
- export declare class ImperativeControlBase implements IImperativeControlBase {
133
- private __editor;
134
- constructor(editor: LexicalEditor);
135
- moveCursor(location: number): void;
136
- setInputText(inputText: string): void;
137
- appendText(text: string): void;
138
- prependText(text: string): void;
139
- insertTextAtCursor(text: string): void;
140
- getInputText(transform?: (node: LexicalNode) => string): string;
141
- scrollToBottom(): void;
142
- }
143
-
144
- export declare class ManualGhostTextBase<ComponentPropsType> implements IManualGhostTextBase<ComponentPropsType> {
145
- private __editor;
146
- private __nodeKey?;
147
- private __id;
148
- private __$isNodeType;
149
- private __$createNode;
150
- constructor(editor: LexicalEditor, id: string, $isNodeType: (node: LexicalNode | null) => node is IGhostTextNode<ComponentPropsType>, $createNode: (id: string, content: string, exposeText?: boolean, componentProps?: ComponentPropsType) => IGhostTextNode<ComponentPropsType>);
151
- getGhostText(): string | undefined;
152
- setGhostText(text: string, exposeText?: boolean, componentProps?: ComponentPropsType, discrete?: boolean): void;
153
- commitGhostText(finalText: string, discrete?: boolean): void;
154
- cancelGhostText(discrete?: boolean): void;
155
- }
156
-
157
- export declare type PasteUnfurlingPluginBaseProps<ExtraDataType, NodePropsType> = {
158
- entityPluginId: string;
159
- transforms: PasteUnfurlingTransformFunction<ExtraDataType, NodePropsType>[];
160
- $createEntityNode: (pluginId: string, text: string, data?: ExtraDataType, entityProps?: NodePropsType, key?: NodeKey) => LexicalNode;
161
- };
162
-
163
- export declare type PasteUnfurlingTransformedPart<ExtraDataType, NodePropsType> = {
164
- type: 'text';
165
- value: string;
166
- } | {
167
- type: 'entity';
168
- value: ChatInputEntityData<ExtraDataType, NodePropsType>;
169
- };
170
-
171
- export declare type PasteUnfurlingTransformFunction<ExtraDataType, NodePropsType> = (event: ClipboardEvent, editor: LexicalEditor) => PasteUnfurlingTransformResult<ExtraDataType, NodePropsType> | Promise<PasteUnfurlingTransformResult<ExtraDataType, NodePropsType>>;
172
-
173
- export declare type PasteUnfurlingTransformResult<ExtraDataType, NodePropsType> = {
174
- handled: boolean;
175
- transformedParts?: PasteUnfurlingTransformedPart<ExtraDataType, NodePropsType>[];
176
- };
177
-
178
- export declare function registerPasteUnfurlingPlugin<ExtraDataType, NodePropsType>(editor: LexicalEditor, props: PasteUnfurlingPluginBaseProps<ExtraDataType, NodePropsType>): () => void;
179
-
180
- export declare const SENTINEL_VALUE = "\u200B\u200C";
181
-
182
- export declare class SentinelNode extends TextNode {
183
- constructor(key?: NodeKey);
184
- static getType(): string;
185
- static clone(node: SentinelNode): SentinelNode;
186
- createDOM(config: EditorConfig): HTMLElement;
187
- isToken(): boolean;
188
- exportJSON(): SerializedTextNode;
189
- static importJSON(serializedNode: SerializedTextNode): SentinelNode;
190
- }
191
-
192
- export { }
@@ -1,107 +0,0 @@
1
- import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import { COMMAND_PRIORITY_HIGH } from '@fluentui-copilot/text-editor';
3
- import { $getRoot, $getSelection, $isRangeSelection, INSERT_PARAGRAPH_COMMAND, KEY_ENTER_COMMAND, PASTE_COMMAND, mergeRegister } from '@fluentui-copilot/text-editor';
4
- import { SENTINEL_VALUE } from './SentinelNode';
5
- import { registerSentinelNodeHandlers } from './SentinelNodeHandlers';
6
- function isClipboardEvent(event) {
7
- return event.type === 'paste';
8
- }
9
- function getTextFromEditorState(state) {
10
- // Remove the sentinel node whenever getting the text
11
- return state.read(()=>$getRoot().getTextContent()).replace(SENTINEL_VALUE, '');
12
- }
13
- export class BasicFunctionalityBase {
14
- __enterHandler(event) {
15
- const selection = $getSelection();
16
- if (!$isRangeSelection(selection)) {
17
- return false;
18
- }
19
- if (event === null) {
20
- return false;
21
- }
22
- event.preventDefault();
23
- if (event.shiftKey) {
24
- return this.__editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined);
25
- }
26
- // Mark event handled to override default behavior
27
- return true;
28
- }
29
- activateContentCallbacks(onContentChange, onCountChanged) {
30
- this.deactivateContentCallbacks();
31
- this.__contentChangeCleanup = this.__editor.registerUpdateListener(({ editorState, prevEditorState, tags })=>{
32
- const prevText = getTextFromEditorState(prevEditorState);
33
- const newText = getTextFromEditorState(editorState);
34
- // If the text has not changed, don't trigger callbacks
35
- if (prevText === newText) {
36
- return;
37
- }
38
- onContentChange === null || onContentChange === void 0 ? void 0 : onContentChange(newText);
39
- onCountChanged === null || onCountChanged === void 0 ? void 0 : onCountChanged(newText.length);
40
- });
41
- }
42
- deactivateContentCallbacks() {
43
- var _this___contentChangeCleanup, _this;
44
- (_this___contentChangeCleanup = (_this = this).__contentChangeCleanup) === null || _this___contentChangeCleanup === void 0 ? void 0 : _this___contentChangeCleanup.call(_this);
45
- this.__contentChangeCleanup = undefined;
46
- }
47
- activatePasteCallback(onPaste) {
48
- this.__pasteHandlerCleanup = this.__editor.registerCommand(PASTE_COMMAND, (event)=>{
49
- if (!isClipboardEvent(event)) {
50
- return false;
51
- }
52
- onPaste(event);
53
- if (event.defaultPrevented) {
54
- return true;
55
- }
56
- return false;
57
- }, COMMAND_PRIORITY_HIGH);
58
- }
59
- deactivatePasteCallback() {
60
- var _this___pasteHandlerCleanup, _this;
61
- (_this___pasteHandlerCleanup = (_this = this).__pasteHandlerCleanup) === null || _this___pasteHandlerCleanup === void 0 ? void 0 : _this___pasteHandlerCleanup.call(_this);
62
- this.__pasteHandlerCleanup = undefined;
63
- }
64
- activateTrimWhitespace() {
65
- this.deactivateTrimWhitespace();
66
- this.__trimWhitespaceCleanup = this.__editor.registerTextContentListener((text)=>{
67
- if (text.trim() === '') {
68
- this.__editor.update(()=>{
69
- $getRoot().getAllTextNodes().forEach((node)=>{
70
- node.remove();
71
- });
72
- }, // Don't allow undoing this action
73
- {
74
- tag: 'historic'
75
- });
76
- }
77
- });
78
- }
79
- deactivateTrimWhitespace() {
80
- var _this___trimWhitespaceCleanup, _this;
81
- (_this___trimWhitespaceCleanup = (_this = this).__trimWhitespaceCleanup) === null || _this___trimWhitespaceCleanup === void 0 ? void 0 : _this___trimWhitespaceCleanup.call(_this);
82
- this.__trimWhitespaceCleanup = undefined;
83
- }
84
- setIsDisabled(isDisabled) {
85
- this.__editor.setEditable(!isDisabled);
86
- }
87
- cleanup() {
88
- var _this___baseHandlersCleanup, _this;
89
- this.deactivateContentCallbacks();
90
- this.deactivateTrimWhitespace();
91
- this.deactivatePasteCallback();
92
- (_this___baseHandlersCleanup = (_this = this).__baseHandlersCleanup) === null || _this___baseHandlersCleanup === void 0 ? void 0 : _this___baseHandlersCleanup.call(_this);
93
- this.__baseHandlersCleanup = undefined;
94
- }
95
- constructor(editor, isSentinelNodeEnabled = true){
96
- _define_property(this, "__editor", void 0);
97
- _define_property(this, "__contentChangeCleanup", void 0);
98
- _define_property(this, "__trimWhitespaceCleanup", void 0);
99
- _define_property(this, "__baseHandlersCleanup", void 0);
100
- _define_property(this, "__pasteHandlerCleanup", void 0);
101
- this.__editor = editor;
102
- this.__baseHandlersCleanup = mergeRegister(this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_HIGH), isSentinelNodeEnabled ? registerSentinelNodeHandlers(editor) : noop);
103
- }
104
- }
105
- function noop() {
106
- return;
107
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["BasicFunctionality.base.ts"],"sourcesContent":["import type { EditorState, LexicalEditor } from '@fluentui-copilot/text-editor';\nimport { COMMAND_PRIORITY_HIGH } from '@fluentui-copilot/text-editor';\nimport {\n $getRoot,\n $getSelection,\n $isRangeSelection,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n mergeRegister,\n} from '@fluentui-copilot/text-editor';\nimport { SENTINEL_VALUE } from './SentinelNode';\nimport { registerSentinelNodeHandlers } from './SentinelNodeHandlers';\n\nfunction isClipboardEvent(event: ClipboardEvent | KeyboardEvent | InputEvent): event is ClipboardEvent {\n return event.type === 'paste';\n}\n\nexport interface IBasicFunctionalityBase {\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\nfunction getTextFromEditorState(state: EditorState): string {\n // Remove the sentinel node whenever getting the text\n return state.read(() => $getRoot().getTextContent()).replace(SENTINEL_VALUE, '');\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, isSentinelNodeEnabled = true) {\n this.__editor = editor;\n\n this.__baseHandlersCleanup = mergeRegister(\n this.__editor.registerCommand(KEY_ENTER_COMMAND, this.__enterHandler.bind(this), COMMAND_PRIORITY_HIGH),\n isSentinelNodeEnabled ? registerSentinelNodeHandlers(editor) : noop,\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.registerUpdateListener(({ editorState, prevEditorState, tags }) => {\n const prevText = getTextFromEditorState(prevEditorState);\n const newText = getTextFromEditorState(editorState);\n\n // If the text has not changed, don't trigger callbacks\n if (prevText === newText) {\n return;\n }\n\n onContentChange?.(newText);\n onCountChanged?.(newText.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 | KeyboardEvent | InputEvent) => {\n if (!isClipboardEvent(event)) {\n return false;\n }\n\n onPaste(event);\n\n if (event.defaultPrevented) {\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_HIGH,\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\nfunction noop() {\n return;\n}\n"],"names":["COMMAND_PRIORITY_HIGH","$getRoot","$getSelection","$isRangeSelection","INSERT_PARAGRAPH_COMMAND","KEY_ENTER_COMMAND","PASTE_COMMAND","mergeRegister","SENTINEL_VALUE","registerSentinelNodeHandlers","isClipboardEvent","event","type","getTextFromEditorState","state","read","getTextContent","replace","BasicFunctionalityBase","__enterHandler","selection","preventDefault","shiftKey","__editor","dispatchCommand","undefined","activateContentCallbacks","onContentChange","onCountChanged","deactivateContentCallbacks","__contentChangeCleanup","registerUpdateListener","editorState","prevEditorState","tags","prevText","newText","length","activatePasteCallback","onPaste","__pasteHandlerCleanup","registerCommand","defaultPrevented","deactivatePasteCallback","activateTrimWhitespace","deactivateTrimWhitespace","__trimWhitespaceCleanup","registerTextContentListener","text","trim","update","getAllTextNodes","forEach","node","remove","tag","setIsDisabled","isDisabled","setEditable","cleanup","__baseHandlersCleanup","constructor","editor","isSentinelNodeEnabled","bind","noop"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1,41 +0,0 @@
1
- import { TextNode } from '@fluentui-copilot/text-editor';
2
- // 2 zero width characters will not be visible in the editor.
3
- // \u200b is the zero width space character which can allow line wrapping in a word
4
- // \u200c is the zero width non-joiner character which prevents ligatures from connecting the two surrounding characters
5
- // These two characters together are a no-op and should not be present together in any legitimate user input.
6
- export const SENTINEL_VALUE = '\u200b\u200c';
7
- export class SentinelNode extends TextNode {
8
- static getType() {
9
- return 'sentinel';
10
- }
11
- static clone(node) {
12
- return new SentinelNode(node.__key);
13
- }
14
- createDOM(config) {
15
- const element = super.createDOM(config);
16
- element.ariaHidden = 'true';
17
- return element;
18
- }
19
- isToken() {
20
- return true;
21
- }
22
- exportJSON() {
23
- return {
24
- ...super.exportJSON(),
25
- type: 'sentinel',
26
- version: 1
27
- };
28
- }
29
- static importJSON(serializedNode) {
30
- return $createSentinelNode();
31
- }
32
- constructor(key){
33
- super(SENTINEL_VALUE, key);
34
- }
35
- }
36
- export function $createSentinelNode(key) {
37
- return new SentinelNode(key);
38
- }
39
- export function $isSentinelNode(node) {
40
- return node instanceof SentinelNode;
41
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["SentinelNode.ts"],"sourcesContent":["import type { EditorConfig, LexicalNode, NodeKey, SerializedTextNode } from '@fluentui-copilot/text-editor';\nimport { TextNode } from '@fluentui-copilot/text-editor';\n\n// 2 zero width characters will not be visible in the editor.\n// \\u200b is the zero width space character which can allow line wrapping in a word\n// \\u200c is the zero width non-joiner character which prevents ligatures from connecting the two surrounding characters\n// These two characters together are a no-op and should not be present together in any legitimate user input.\nexport const SENTINEL_VALUE = '\\u200b\\u200c';\n\nexport class SentinelNode extends TextNode {\n constructor(key?: NodeKey) {\n super(SENTINEL_VALUE, key);\n }\n\n static getType() {\n return 'sentinel';\n }\n static clone(node: SentinelNode) {\n return new SentinelNode(node.__key);\n }\n\n createDOM(config: EditorConfig): HTMLElement {\n const element = super.createDOM(config);\n element.ariaHidden = 'true';\n return element;\n }\n\n isToken() {\n return true;\n }\n\n exportJSON(): SerializedTextNode {\n return {\n ...super.exportJSON(),\n type: 'sentinel',\n version: 1,\n };\n }\n\n static importJSON(serializedNode: SerializedTextNode): SentinelNode {\n return $createSentinelNode();\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","SENTINEL_VALUE","SentinelNode","getType","clone","node","__key","createDOM","config","element","ariaHidden","isToken","exportJSON","type","version","importJSON","serializedNode","$createSentinelNode","constructor","key","$isSentinelNode"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AACA,SAASA,QAAQ,QAAQ,gCAAgC;AAEzD,6DAA6D;AAC7D,mFAAmF;AACnF,wHAAwH;AACxH,6GAA6G;AAC7G,OAAO,MAAMC,iBAAiB,eAAe;AAE7C,OAAO,MAAMC,qBAAqBF;IAKhC,OAAOG,UAAU;QACf,OAAO;IACT;IACA,OAAOC,MAAMC,IAAkB,EAAE;QAC/B,OAAO,IAAIH,aAAaG,KAAKC,KAAK;IACpC;IAEAC,UAAUC,MAAoB,EAAe;QAC3C,MAAMC,UAAU,KAAK,CAACF,UAAUC;QAChCC,QAAQC,UAAU,GAAG;QACrB,OAAOD;IACT;IAEAE,UAAU;QACR,OAAO;IACT;IAEAC,aAAiC;QAC/B,OAAO;YACL,GAAG,KAAK,CAACA,YAAY;YACrBC,MAAM;YACNC,SAAS;QACX;IACF;IAEA,OAAOC,WAAWC,cAAkC,EAAgB;QAClE,OAAOC;IACT;IA/BAC,YAAYC,GAAa,CAAE;QACzB,KAAK,CAAClB,gBAAgBkB;IACxB;AA8BF;AAEA,OAAO,SAASF,oBAAoBE,GAAa;IAC/C,OAAO,IAAIjB,aAAaiB;AAC1B;AAEA,OAAO,SAASC,gBAAgBf,IAAwB;IACtD,OAAOA,gBAAgBH;AACzB"}
@@ -1,79 +0,0 @@
1
- import { $getLeafNodes, $getNodeByKey, $getRoot, $getSelection, $isRangeSelection, $normalizeSelection__EXPERIMENTAL, $setSelection, mergeRegister } from '@fluentui-copilot/text-editor';
2
- import { $isSentinelNode, $createSentinelNode, SentinelNode } from './SentinelNode';
3
- export function registerSentinelNodeHandlers(editor) {
4
- // Add a sentinel node at the end of the input when there is content.
5
- // This sentinel node fixes a number of issues.
6
- // In Safari, Lexical's behaviour of adding <br /> tags to the end of the input when it ends
7
- // in a decorator node causes cursor location issues: https://github.com/facebook/lexical/issues/4487
8
- // Otherwise, when a decorator node is the last node in the input, the cursor can't move past it.
9
- // Adding an invisible text node that doesn't contribute to the content and can't be selected to the end of the input
10
- // mitigates these issues.
11
- const sentinelNodeUpdateHandler = ({ editorState })=>{
12
- editorState.read(()=>{
13
- const leaves = $getLeafNodes($getRoot());
14
- if (leaves.length === 0) {
15
- return;
16
- }
17
- const lastNode = leaves[leaves.length - 1];
18
- const lastNodeKey = lastNode.getKey();
19
- // If the last node isn't a sentinel, add one
20
- if (!$isSentinelNode(lastNode)) {
21
- editor.update(()=>{
22
- var // We find the node by its key again in case the node was removed before this update runs
23
- _$getNodeByKey;
24
- (_$getNodeByKey = $getNodeByKey(lastNodeKey)) === null || _$getNodeByKey === void 0 ? void 0 : _$getNodeByKey.insertAfter($createSentinelNode());
25
- }, // historic tag prevents every sentinel node addition from being added to LexicalHistoryPlugin undo stack
26
- {
27
- discrete: true,
28
- tag: 'historic'
29
- });
30
- return;
31
- }
32
- // If the sentinel node is not selected, we're done
33
- const previous = lastNode.getPreviousSibling();
34
- if (!previous || !lastNode.isSelected()) {
35
- return;
36
- }
37
- const selection = $getSelection();
38
- if (!$isRangeSelection(selection)) {
39
- return;
40
- }
41
- // If the cursor is inside the sentinel node, move it out (next to the beginning)
42
- // We allow selection on the boundary of the sentinel in case the adjacent node is a decorator node
43
- // where selection is ill-defined.
44
- if (selection.isCollapsed() && selection.anchor.offset > 0) {
45
- editor.update(()=>{
46
- var _$getNodeByKey;
47
- (_$getNodeByKey = $getNodeByKey(lastNodeKey)) === null || _$getNodeByKey === void 0 ? void 0 : _$getNodeByKey.selectStart();
48
- });
49
- return;
50
- }
51
- // If the selection is a range which includes the sentinel, modify the range to exclude it
52
- if (!selection.isCollapsed()) {
53
- let selectionChanged = false;
54
- const newSelection = selection.clone();
55
- if (newSelection.anchor.getNode() === lastNode && newSelection.anchor.offset > 0) {
56
- newSelection.anchor.set(lastNodeKey, 0, 'text');
57
- selectionChanged = true;
58
- }
59
- if (newSelection.focus.getNode() === lastNode && newSelection.focus.offset > 0) {
60
- newSelection.focus.set(lastNodeKey, 0, 'text');
61
- selectionChanged = true;
62
- }
63
- if (selectionChanged) {
64
- editor.update(()=>{
65
- if ($getNodeByKey(lastNodeKey) !== null) {
66
- $setSelection($normalizeSelection__EXPERIMENTAL(newSelection));
67
- }
68
- });
69
- }
70
- }
71
- });
72
- };
73
- return mergeRegister(editor.registerUpdateListener(sentinelNodeUpdateHandler), editor.registerNodeTransform(SentinelNode, (node)=>{
74
- if (!node.getPreviousSibling() || node.getNextSibling()) {
75
- node.remove();
76
- return;
77
- }
78
- }));
79
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["SentinelNodeHandlers.ts"],"sourcesContent":["import type {\n LexicalEditor,\n UpdateListener} from '@fluentui-copilot/text-editor';\nimport {\n $getLeafNodes,\n $getNodeByKey,\n $getRoot,\n $getSelection,\n $isRangeSelection,\n $normalizeSelection__EXPERIMENTAL,\n $setSelection,\n mergeRegister\n} from '@fluentui-copilot/text-editor';\nimport { $isSentinelNode, $createSentinelNode, SentinelNode } from './SentinelNode';\n\nexport function registerSentinelNodeHandlers(editor: LexicalEditor) {\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 const sentinelNodeUpdateHandler: UpdateListener = ({ editorState }) => {\n editorState.read(() => {\n const leaves = $getLeafNodes($getRoot());\n if (leaves.length === 0) {\n return;\n }\n\n const lastNode = leaves[leaves.length - 1];\n const lastNodeKey = lastNode.getKey();\n\n // If the last node isn't a sentinel, add one\n if (!$isSentinelNode(lastNode)) {\n editor.update(\n () => {\n // We find the node by its key again in case the node was removed before this update runs\n $getNodeByKey(lastNodeKey)?.insertAfter($createSentinelNode());\n },\n // historic tag prevents every sentinel node addition from being added to LexicalHistoryPlugin undo stack\n { discrete: true, tag: 'historic' },\n );\n return;\n }\n\n // If the sentinel node is not selected, we're done\n const previous = lastNode.getPreviousSibling();\n if (!previous || !lastNode.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 editor.update(() => {\n $getNodeByKey(lastNodeKey)?.selectStart();\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() === lastNode && newSelection.anchor.offset > 0) {\n newSelection.anchor.set(lastNodeKey, 0, 'text');\n selectionChanged = true;\n }\n if (newSelection.focus.getNode() === lastNode && newSelection.focus.offset > 0) {\n newSelection.focus.set(lastNodeKey, 0, 'text');\n selectionChanged = true;\n }\n\n if (selectionChanged) {\n editor.update(() => {\n if ($getNodeByKey(lastNodeKey) !== null) {\n $setSelection($normalizeSelection__EXPERIMENTAL(newSelection));\n }\n });\n }\n }\n });\n };\n\n return mergeRegister(\n editor.registerUpdateListener(sentinelNodeUpdateHandler),\n editor.registerNodeTransform(SentinelNode, node => {\n if (!node.getPreviousSibling() || node.getNextSibling()) {\n node.remove();\n return;\n }\n }),\n );\n}\n"],"names":["$getLeafNodes","$getNodeByKey","$getRoot","$getSelection","$isRangeSelection","$normalizeSelection__EXPERIMENTAL","$setSelection","mergeRegister","$isSentinelNode","$createSentinelNode","SentinelNode","registerSentinelNodeHandlers","editor","sentinelNodeUpdateHandler","editorState","read","leaves","length","lastNode","lastNodeKey","getKey","update","insertAfter","discrete","tag","previous","getPreviousSibling","isSelected","selection","isCollapsed","anchor","offset","selectStart","selectionChanged","newSelection","clone","getNode","set","focus","registerUpdateListener","registerNodeTransform","node","getNextSibling","remove"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAGA,SACEA,aAAa,EACbC,aAAa,EACbC,QAAQ,EACRC,aAAa,EACbC,iBAAiB,EACjBC,iCAAiC,EACjCC,aAAa,EACbC,aAAa,QACR,gCAAgC;AACvC,SAASC,eAAe,EAAEC,mBAAmB,EAAEC,YAAY,QAAQ,iBAAiB;AAEpF,OAAO,SAASC,6BAA6BC,MAAqB;IAChE,qEAAqE;IACrE,+CAA+C;IAC/C,4FAA4F;IAC5F,qGAAqG;IACrG,iGAAiG;IACjG,qHAAqH;IACrH,0BAA0B;IAC1B,MAAMC,4BAA4C,CAAC,EAAEC,WAAW,EAAE;QAChEA,YAAYC,IAAI,CAAC;YACf,MAAMC,SAAShB,cAAcE;YAC7B,IAAIc,OAAOC,MAAM,KAAK,GAAG;gBACvB;YACF;YAEA,MAAMC,WAAWF,MAAM,CAACA,OAAOC,MAAM,GAAG,EAAE;YAC1C,MAAME,cAAcD,SAASE,MAAM;YAEnC,6CAA6C;YAC7C,IAAI,CAACZ,gBAAgBU,WAAW;gBAC9BN,OAAOS,MAAM,CACX;wBACE,yFAAyF;oBACzFpB;qBAAAA,iBAAAA,cAAckB,0BAAdlB,qCAAAA,eAA4BqB,WAAW,CAACb;gBAC1C,GACA,yGAAyG;gBACzG;oBAAEc,UAAU;oBAAMC,KAAK;gBAAW;gBAEpC;YACF;YAEA,mDAAmD;YACnD,MAAMC,WAAWP,SAASQ,kBAAkB;YAC5C,IAAI,CAACD,YAAY,CAACP,SAASS,UAAU,IAAI;gBACvC;YACF;YAEA,MAAMC,YAAYzB;YAClB,IAAI,CAACC,kBAAkBwB,YAAY;gBACjC;YACF;YAEA,iFAAiF;YACjF,mGAAmG;YACnG,kCAAkC;YAClC,IAAIA,UAAUC,WAAW,MAAMD,UAAUE,MAAM,CAACC,MAAM,GAAG,GAAG;gBAC1DnB,OAAOS,MAAM,CAAC;wBACZpB;qBAAAA,iBAAAA,cAAckB,0BAAdlB,qCAAAA,eAA4B+B,WAAW;gBACzC;gBACA;YACF;YAEA,0FAA0F;YAC1F,IAAI,CAACJ,UAAUC,WAAW,IAAI;gBAC5B,IAAII,mBAAmB;gBACvB,MAAMC,eAAeN,UAAUO,KAAK;gBAEpC,IAAID,aAAaJ,MAAM,CAACM,OAAO,OAAOlB,YAAYgB,aAAaJ,MAAM,CAACC,MAAM,GAAG,GAAG;oBAChFG,aAAaJ,MAAM,CAACO,GAAG,CAAClB,aAAa,GAAG;oBACxCc,mBAAmB;gBACrB;gBACA,IAAIC,aAAaI,KAAK,CAACF,OAAO,OAAOlB,YAAYgB,aAAaI,KAAK,CAACP,MAAM,GAAG,GAAG;oBAC9EG,aAAaI,KAAK,CAACD,GAAG,CAAClB,aAAa,GAAG;oBACvCc,mBAAmB;gBACrB;gBAEA,IAAIA,kBAAkB;oBACpBrB,OAAOS,MAAM,CAAC;wBACZ,IAAIpB,cAAckB,iBAAiB,MAAM;4BACvCb,cAAcD,kCAAkC6B;wBAClD;oBACF;gBACF;YACF;QACF;IACF;IAEA,OAAO3B,cACLK,OAAO2B,sBAAsB,CAAC1B,4BAC9BD,OAAO4B,qBAAqB,CAAC9B,cAAc+B,CAAAA;QACzC,IAAI,CAACA,KAAKf,kBAAkB,MAAMe,KAAKC,cAAc,IAAI;YACvDD,KAAKE,MAAM;YACX;QACF;IACF;AAEJ"}
@@ -1,2 +0,0 @@
1
- export { BasicFunctionalityBase } from './BasicFunctionality.base';
2
- export { $createSentinelNode, $isSentinelNode, SENTINEL_VALUE, SentinelNode } from './SentinelNode';
@@ -1 +0,0 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export type { IBasicFunctionalityBase } from './BasicFunctionality.base';\nexport { BasicFunctionalityBase } from './BasicFunctionality.base';\nexport { $createSentinelNode, $isSentinelNode, SENTINEL_VALUE, SentinelNode } from './SentinelNode';\n"],"names":["BasicFunctionalityBase","$createSentinelNode","$isSentinelNode","SENTINEL_VALUE","SentinelNode"],"rangeMappings":";","mappings":"AACA,SAASA,sBAAsB,QAAQ,4BAA4B;AACnE,SAASC,mBAAmB,EAAEC,eAAe,EAAEC,cAAc,EAAEC,YAAY,QAAQ,iBAAiB"}
@@ -1,117 +0,0 @@
1
- import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import { $createParagraphNode, $createTextNode, $getNodeByKey, $getSelection, $insertNodes, $isDecoratorNode, $isRangeSelection, $isRootOrShadowRoot, $nodesOfType, $wrapNodeInElement, COMMAND_PRIORITY_CRITICAL, DELETE_CHARACTER_COMMAND, mergeRegister } from '@fluentui-copilot/text-editor';
3
- export class ChatInputEntityPluginBase {
4
- cleanup() {
5
- this._cleanup();
6
- }
7
- insertChatInputEntity(props) {
8
- let key = undefined;
9
- this.__editor.update(()=>{
10
- const { text, data, entityProps } = props;
11
- const entityNode = this.__$createNode(this.__id, text, data, entityProps);
12
- $insertNodes([
13
- entityNode
14
- ]);
15
- entityNode.selectEnd();
16
- if ($isRootOrShadowRoot(entityNode.getParentOrThrow())) {
17
- $wrapNodeInElement(entityNode, $createParagraphNode).selectEnd();
18
- }
19
- key = entityNode.getKey();
20
- });
21
- return key;
22
- }
23
- removeChatInputEntity(keyOrPredicate) {
24
- this.__editor.update(()=>{
25
- if (typeof keyOrPredicate === 'function') {
26
- $nodesOfType(this.__nodeClass).filter((node, i)=>node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i)).forEach((node)=>node.remove());
27
- } else {
28
- var _$getNodeByKey;
29
- (_$getNodeByKey = $getNodeByKey(keyOrPredicate)) === null || _$getNodeByKey === void 0 ? void 0 : _$getNodeByKey.remove();
30
- }
31
- });
32
- }
33
- updateChatInputEntityProps(keyOrPredicate, props) {
34
- const updateNode = (node)=>{
35
- const newProps = typeof props === 'function' ? props(node.getEntityData()) : props;
36
- node.updateEntityData(newProps);
37
- };
38
- this.__editor.update(()=>{
39
- if (typeof keyOrPredicate === 'function') {
40
- $nodesOfType(this.__nodeClass).filter((node, i)=>node.__pluginId === this.__id && keyOrPredicate(node.getEntityData(), i)).forEach(updateNode);
41
- } else {
42
- const node = $getNodeByKey(keyOrPredicate);
43
- if (node) {
44
- updateNode(node);
45
- }
46
- }
47
- }, {
48
- tag: 'historic'
49
- });
50
- }
51
- getActiveEntities() {
52
- return this.__editor.getEditorState().read(()=>$nodesOfType(this.__nodeClass).filter((node)=>node.__pluginId === this.__id).map((node)=>node.getEntityData()));
53
- }
54
- constructor(editor, id, nodeClass, $createNode, $isChatInputEntityNode, onChatInputEntityAdded, onChatInputEntityDeleted){
55
- _define_property(this, "__nodeClass", void 0);
56
- _define_property(this, "__editor", void 0);
57
- _define_property(this, "__id", void 0);
58
- _define_property(this, "__deleteDirection", null);
59
- _define_property(this, "__$createNode", void 0);
60
- _define_property(this, "_cleanup", void 0);
61
- this.__$createNode = $createNode;
62
- this.__editor = editor;
63
- this.__id = id;
64
- this.__nodeClass = nodeClass;
65
- this._cleanup = mergeRegister(// Keep track of delete direction so we know where to put the selection after adding back a space
66
- editor.registerCommand(DELETE_CHARACTER_COMMAND, (isBackward)=>{
67
- this.__deleteDirection = isBackward ? 'backward' : 'forward';
68
- return false;
69
- }, COMMAND_PRIORITY_CRITICAL), // Always maintain a space before, after, and between entities in order for selection to work properly
70
- editor.registerNodeTransform(this.__nodeClass, (node)=>{
71
- const nextSibling = node.getNextSibling();
72
- if (!nextSibling || $isDecoratorNode(nextSibling)) {
73
- const selection = $getSelection();
74
- // If selection is between the two nodes, that means the user is trying to delete the space
75
- // If they deleted to the left, we should move the cursor to the end of the entity
76
- // If they delete to the right, we should move the cursor to the end of the newly added space
77
- // This mimics changing the delete into a cursor move action
78
- const shouldMoveSelection = selection && $isRangeSelection(selection) && selection.isCollapsed() && selection.anchor.offset === node.getIndexWithinParent() + 1;
79
- const text = $createTextNode(' ');
80
- node.insertAfter(text);
81
- if (shouldMoveSelection) {
82
- if (this.__deleteDirection === 'forward') {
83
- text.selectEnd();
84
- } else {
85
- node.selectEnd();
86
- }
87
- }
88
- }
89
- // In the case the entity is the first node, we need a space before it.
90
- if (!node.getPreviousSibling()) {
91
- const text = $createTextNode(' ');
92
- node.insertBefore(text);
93
- }
94
- }), onChatInputEntityAdded || onChatInputEntityDeleted ? editor.registerMutationListener(this.__nodeClass, (nodes, payload)=>{
95
- for (const [nodeKey, mutation] of nodes){
96
- if (onChatInputEntityDeleted && mutation === 'destroyed') {
97
- payload.prevEditorState.read(()=>{
98
- const node = $getNodeByKey(nodeKey);
99
- if ($isChatInputEntityNode(node) && node.__pluginId === id) {
100
- onChatInputEntityDeleted(node.getEntityData(), nodeKey);
101
- }
102
- });
103
- } else if (onChatInputEntityAdded && mutation === 'created') {
104
- editor.getEditorState().read(()=>{
105
- const node = $getNodeByKey(nodeKey);
106
- if ($isChatInputEntityNode(node) && node.__pluginId === id) {
107
- onChatInputEntityAdded(node.getEntityData(), nodeKey);
108
- }
109
- });
110
- }
111
- }
112
- }) : noop);
113
- }
114
- }
115
- function noop() {
116
- return;
117
- }