1188.js.map (85527B)
1 {"version":3,"file":"bundles/9cacd6575f4c8ee1aedb/1188.js","mappings":"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","sources":["webpack://element-web/./src/components/views/rooms/CollapsibleButton.tsx","webpack://element-web/./src/components/views/rooms/EmojiButton.tsx","webpack://element-web/./src/components/views/rooms/MessageComposerButtons.tsx","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/useSuggestion.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/components/PlainTextComposer.tsx","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/useComposerFunctions.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextInitialization.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/components/Emoji.tsx","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/useWysiwygSendActionHandler.ts","webpack://element-web/./node_modules/@vector-im/compound-design-tokens/assets/web/icons/lock-off.js","webpack://element-web/./node_modules/@vector-im/compound-design-tokens/assets/web/icons/mic-on.js","webpack://element-web/./node_modules/@vector-im/compound-design-tokens/assets/web/icons/reaction.js","webpack://element-web/./node_modules/@vector-im/compound-design-tokens/assets/web/icons/sticker.js","webpack://element-web/./node_modules/@vector-im/compound-design-tokens/assets/web/icons/text-formatting.js"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type RefObject, useContext } from \"react\";\n\nimport AccessibleButton, { type ButtonProps } from \"../elements/AccessibleButton\";\nimport { OverflowMenuContext } from \"./MessageComposerButtons\";\nimport { IconizedContextMenuOption } from \"../context_menus/IconizedContextMenu\";\n\ninterface Props extends Omit<ButtonProps<\"div\">, \"element\"> {\n inputRef?: RefObject<HTMLElement | null>;\n title: string;\n}\n\nexport const CollapsibleButton: React.FC<Props> = ({ title, children, className, inputRef, ...props }) => {\n const inOverflowMenu = !!useContext(OverflowMenuContext);\n if (inOverflowMenu) {\n return <IconizedContextMenuOption {...props} icon={children} label={title} inputRef={inputRef} />;\n }\n\n return (\n <AccessibleButton {...props} title={title} className={className} ref={inputRef}>\n {children}\n </AccessibleButton>\n );\n};\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classNames from \"classnames\";\nimport React, { type JSX, useContext } from \"react\";\nimport { ReactionIcon } from \"@vector-im/compound-design-tokens/assets/web/icons\";\n\nimport { _t } from \"../../../languageHandler\";\nimport ContextMenu, { aboveLeftOf, type MenuProps, useContextMenu } from \"../../structures/ContextMenu\";\nimport EmojiPicker from \"../emojipicker/EmojiPicker\";\nimport { CollapsibleButton } from \"./CollapsibleButton\";\nimport { OverflowMenuContext } from \"./MessageComposerButtons\";\n\ninterface IEmojiButtonProps {\n addEmoji: (unicode: string) => boolean;\n menuPosition?: MenuProps;\n className?: string;\n}\n\nexport function EmojiButton({ addEmoji, menuPosition, className }: IEmojiButtonProps): JSX.Element {\n const overflowMenuCloser = useContext(OverflowMenuContext);\n const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();\n\n let contextMenu: React.ReactElement | null = null;\n if (menuDisplayed && button.current) {\n const position = menuPosition ?? aboveLeftOf(button.current.getBoundingClientRect());\n const onFinished = (): void => {\n closeMenu();\n overflowMenuCloser?.();\n };\n\n contextMenu = (\n <ContextMenu {...position} onFinished={onFinished} managed={false} focusLock>\n <EmojiPicker onChoose={addEmoji} onFinished={onFinished} />\n </ContextMenu>\n );\n }\n\n const computedClassName = classNames(\"mx_EmojiButton\", className, {\n mx_EmojiButton_highlight: menuDisplayed,\n });\n\n // TODO: replace ContextMenuTooltipButton with a unified representation of\n // the header buttons and the right panel buttons\n return (\n <>\n <CollapsibleButton\n className={computedClassName}\n onClick={openMenu}\n title={_t(\"common|emoji\")}\n inputRef={button}\n >\n <ReactionIcon />\n </CollapsibleButton>\n\n {contextMenu}\n </>\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classNames from \"classnames\";\nimport {\n type IEventRelation,\n type Room,\n type MatrixClient,\n THREAD_RELATION_TYPE,\n M_POLL_START,\n} from \"matrix-js-sdk/src/matrix\";\nimport React, { type JSX, createContext, type ReactElement, type ReactNode, useContext, useRef } from \"react\";\nimport {\n AttachmentIcon,\n MicOnIcon,\n OverflowHorizontalIcon,\n PollsIcon,\n StickerIcon,\n TextFormattingIcon,\n} from \"@vector-im/compound-design-tokens/assets/web/icons\";\n\nimport { _t } from \"../../../languageHandler\";\nimport { CollapsibleButton } from \"./CollapsibleButton\";\nimport { type MenuProps } from \"../../structures/ContextMenu\";\nimport dis from \"../../../dispatcher/dispatcher\";\nimport ErrorDialog from \"../dialogs/ErrorDialog\";\nimport { LocationButton } from \"../location\";\nimport Modal from \"../../../Modal\";\nimport PollCreateDialog from \"../elements/PollCreateDialog\";\nimport { MatrixClientPeg } from \"../../../MatrixClientPeg\";\nimport ContentMessages from \"../../../ContentMessages\";\nimport MatrixClientContext from \"../../../contexts/MatrixClientContext\";\nimport { useDispatcher } from \"../../../hooks/useDispatcher\";\nimport { chromeFileInputFix } from \"../../../utils/BrowserWorkarounds\";\nimport IconizedContextMenu, { IconizedContextMenuOptionList } from \"../context_menus/IconizedContextMenu\";\nimport { EmojiButton } from \"./EmojiButton\";\nimport { filterBoolean } from \"../../../utils/arrays\";\nimport { useSettingValue } from \"../../../hooks/useSettings\";\nimport AccessibleButton, { type ButtonEvent } from \"../elements/AccessibleButton\";\nimport { useScopedRoomContext } from \"../../../contexts/ScopedRoomContext.tsx\";\n\ninterface IProps {\n addEmoji: (emoji: string) => boolean;\n haveRecording: boolean;\n isMenuOpen: boolean;\n isStickerPickerOpen: boolean;\n menuPosition?: MenuProps;\n onRecordStartEndClick: () => void;\n relation?: IEventRelation;\n setStickerPickerOpen: (isStickerPickerOpen: boolean) => void;\n showLocationButton: boolean;\n showPollsButton: boolean;\n showStickersButton: boolean;\n toggleButtonMenu: () => void;\n isRichTextEnabled: boolean;\n onComposerModeClick: () => void;\n}\n\ntype OverflowMenuCloser = () => void;\nexport const OverflowMenuContext = createContext<OverflowMenuCloser | null>(null);\n\nconst MessageComposerButtons: React.FC<IProps> = (props: IProps) => {\n const matrixClient = useContext(MatrixClientContext);\n const { room, narrow } = useScopedRoomContext(\"room\", \"narrow\");\n\n const isWysiwygLabEnabled = useSettingValue(\"feature_wysiwyg_composer\");\n\n if (!matrixClient || !room || props.haveRecording) {\n return null;\n }\n\n let mainButtons: ReactNode[];\n let moreButtons: ReactNode[];\n if (narrow) {\n mainButtons = [\n isWysiwygLabEnabled ? (\n <ComposerModeButton\n key=\"composerModeButton\"\n isRichTextEnabled={props.isRichTextEnabled}\n onClick={props.onComposerModeClick}\n />\n ) : (\n emojiButton(props)\n ),\n ];\n moreButtons = [\n uploadButton(), // props passed via UploadButtonContext\n showStickersButton(props),\n voiceRecordingButton(props, narrow),\n props.showPollsButton ? pollButton(room, props.relation) : null,\n showLocationButton(props, room, matrixClient),\n ];\n } else {\n mainButtons = [\n isWysiwygLabEnabled ? (\n <ComposerModeButton\n key=\"composerModeButton\"\n isRichTextEnabled={props.isRichTextEnabled}\n onClick={props.onComposerModeClick}\n />\n ) : (\n emojiButton(props)\n ),\n uploadButton(), // props passed via UploadButtonContext\n ];\n moreButtons = [\n showStickersButton(props),\n voiceRecordingButton(props, narrow),\n props.showPollsButton ? pollButton(room, props.relation) : null,\n showLocationButton(props, room, matrixClient),\n ];\n }\n\n mainButtons = filterBoolean(mainButtons);\n moreButtons = filterBoolean(moreButtons);\n\n const moreOptionsClasses = classNames({\n mx_MessageComposer_button: true,\n mx_MessageComposer_buttonMenu: true,\n mx_MessageComposer_closeButtonMenu: props.isMenuOpen,\n });\n\n return (\n <UploadButtonContextProvider roomId={room.roomId} relation={props.relation}>\n {mainButtons}\n {moreButtons.length > 0 && (\n <AccessibleButton\n className={moreOptionsClasses}\n onClick={props.toggleButtonMenu}\n title={_t(\"quick_settings|sidebar_settings\")}\n >\n <OverflowHorizontalIcon />\n </AccessibleButton>\n )}\n {props.isMenuOpen && (\n <IconizedContextMenu\n onFinished={props.toggleButtonMenu}\n {...props.menuPosition}\n wrapperClassName=\"mx_MessageComposer_Menu\"\n compact={true}\n >\n <OverflowMenuContext.Provider value={props.toggleButtonMenu}>\n <IconizedContextMenuOptionList>{moreButtons}</IconizedContextMenuOptionList>\n </OverflowMenuContext.Provider>\n </IconizedContextMenu>\n )}\n </UploadButtonContextProvider>\n );\n};\n\nfunction emojiButton(props: IProps): ReactElement {\n return (\n <EmojiButton\n key=\"emoji_button\"\n addEmoji={props.addEmoji}\n menuPosition={props.menuPosition}\n className=\"mx_MessageComposer_button\"\n />\n );\n}\n\nfunction uploadButton(): ReactElement {\n return <UploadButton key=\"controls_upload\" />;\n}\n\ntype UploadButtonFn = () => void;\nexport const UploadButtonContext = createContext<UploadButtonFn | null>(null);\n\ninterface IUploadButtonProps {\n roomId: string;\n relation?: IEventRelation;\n children: ReactNode;\n}\n\n// We put the file input outside the UploadButton component so that it doesn't get killed when the context menu closes.\nconst UploadButtonContextProvider: React.FC<IUploadButtonProps> = ({ roomId, relation, children }) => {\n const cli = useContext(MatrixClientContext);\n const roomContext = useScopedRoomContext(\"timelineRenderingType\", \"replyToEvent\");\n const uploadInput = useRef<HTMLInputElement>(null);\n\n const onUploadClick = (): void => {\n if (cli?.isGuest()) {\n dis.dispatch({ action: \"require_registration\" });\n return;\n }\n uploadInput.current?.click();\n };\n\n useDispatcher(dis, (payload) => {\n if (roomContext.timelineRenderingType === payload.context && payload.action === \"upload_file\") {\n onUploadClick();\n }\n });\n\n const onUploadFileInputChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {\n if (ev.target.files?.length === 0) return;\n\n // Take a copy, so we can safely reset the value of the form control\n ContentMessages.sharedInstance().sendContentListToRoom(\n Array.from(ev.target.files!),\n roomId,\n relation,\n roomContext.replyToEvent,\n cli,\n roomContext.timelineRenderingType,\n );\n\n // This is the onChange handler for a file form control, but we're\n // not keeping any state, so reset the value of the form control\n // to empty.\n // NB. we need to set 'value': the 'files' property is immutable.\n ev.target.value = \"\";\n };\n\n const uploadInputStyle = { display: \"none\" };\n return (\n <UploadButtonContext.Provider value={onUploadClick}>\n {children}\n\n <input\n ref={uploadInput}\n type=\"file\"\n style={uploadInputStyle}\n multiple\n onClick={chromeFileInputFix}\n onChange={onUploadFileInputChange}\n />\n </UploadButtonContext.Provider>\n );\n};\n\n// Must be rendered within an UploadButtonContextProvider\nconst UploadButton: React.FC = () => {\n const overflowMenuCloser = useContext(OverflowMenuContext);\n const uploadButtonFn = useContext(UploadButtonContext);\n\n const onClick = (): void => {\n uploadButtonFn?.();\n overflowMenuCloser?.(); // close overflow menu\n };\n\n return (\n <CollapsibleButton className=\"mx_MessageComposer_button\" onClick={onClick} title={_t(\"common|attachment\")}>\n <AttachmentIcon />\n </CollapsibleButton>\n );\n};\n\nfunction showStickersButton(props: IProps): ReactElement | null {\n return props.showStickersButton ? (\n <CollapsibleButton\n id=\"stickersButton\"\n key=\"controls_stickers\"\n className=\"mx_MessageComposer_button\"\n onClick={() => props.setStickerPickerOpen(!props.isStickerPickerOpen)}\n title={props.isStickerPickerOpen ? _t(\"composer|close_sticker_picker\") : _t(\"common|sticker\")}\n >\n <StickerIcon />\n </CollapsibleButton>\n ) : null;\n}\n\nfunction voiceRecordingButton(props: IProps, narrow: boolean): ReactElement | null {\n // XXX: recording UI does not work well in narrow mode, so hide for now\n return narrow ? null : (\n <CollapsibleButton\n key=\"voice_message_send\"\n className=\"mx_MessageComposer_button\"\n onClick={props.onRecordStartEndClick}\n title={_t(\"composer|voice_message_button\")}\n >\n <MicOnIcon />\n </CollapsibleButton>\n );\n}\n\nfunction pollButton(room: Room, relation?: IEventRelation): ReactElement {\n return <PollButton key=\"polls\" room={room} relation={relation} />;\n}\n\ninterface IPollButtonProps {\n room: Room;\n relation?: IEventRelation;\n}\n\nclass PollButton extends React.PureComponent<IPollButtonProps> {\n public static contextType = OverflowMenuContext;\n declare public context: React.ContextType<typeof OverflowMenuContext>;\n\n private onCreateClick = (): void => {\n this.context?.(); // close overflow menu\n const canSend = this.props.room.currentState.maySendEvent(\n M_POLL_START.name,\n MatrixClientPeg.safeGet().getSafeUserId(),\n );\n if (!canSend) {\n Modal.createDialog(ErrorDialog, {\n title: _t(\"composer|poll_button_no_perms_title\"),\n description: _t(\"composer|poll_button_no_perms_description\"),\n });\n } else {\n const threadId =\n this.props.relation?.rel_type === THREAD_RELATION_TYPE.name ? this.props.relation.event_id : undefined;\n\n Modal.createDialog(\n PollCreateDialog,\n {\n room: this.props.room,\n threadId,\n },\n \"mx_CompoundDialog\",\n false, // isPriorityModal\n true, // isStaticModal\n );\n }\n };\n\n public render(): React.ReactNode {\n // do not allow sending polls within threads at this time\n if (this.props.relation?.rel_type === THREAD_RELATION_TYPE.name) return null;\n\n return (\n <CollapsibleButton\n className=\"mx_MessageComposer_button\"\n onClick={this.onCreateClick}\n title={_t(\"composer|poll_button\")}\n >\n <PollsIcon />\n </CollapsibleButton>\n );\n }\n}\n\nfunction showLocationButton(props: IProps, room: Room, matrixClient: MatrixClient): ReactElement | null {\n const sender = room.getMember(matrixClient.getSafeUserId());\n\n return props.showLocationButton && sender ? (\n <LocationButton\n key=\"location\"\n roomId={room.roomId}\n relation={props.relation}\n sender={sender}\n menuPosition={props.menuPosition}\n />\n ) : null;\n}\n\ninterface WysiwygToggleButtonProps {\n isRichTextEnabled: boolean;\n onClick: (ev: ButtonEvent) => void;\n}\n\nfunction ComposerModeButton({ isRichTextEnabled, onClick }: WysiwygToggleButtonProps): JSX.Element {\n const title = isRichTextEnabled ? _t(\"composer|mode_plain\") : _t(\"composer|mode_rich_text\");\n\n return (\n <CollapsibleButton className=\"mx_MessageComposer_button\" onClick={onClick} title={title}>\n <TextFormattingIcon />\n </CollapsibleButton>\n );\n}\n\nexport default MessageComposerButtons;\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { EMOTICON_TO_EMOJI } from \"@matrix-org/emojibase-bindings\";\nimport { type AllowedMentionAttributes, type MappedSuggestion } from \"@vector-im/matrix-wysiwyg\";\nimport { type SyntheticEvent, useState, type SetStateAction } from \"react\";\nimport { logger } from \"matrix-js-sdk/src/logger\";\n\nimport { isNotNull } from \"../../../../../Typeguards\";\n\n/**\n * Information about the current state of the `useSuggestion` hook.\n */\nexport type Suggestion = {\n mappedSuggestion: MappedSuggestion;\n /* The information in a `MappedSuggestion` is sufficient to generate a query for the autocomplete\n component but more information is required to allow manipulation of the correct part of the DOM\n when selecting an option from the autocomplete. These three pieces of information allow us to\n do that.\n */\n node: Node;\n startOffset: number;\n endOffset: number;\n};\ntype SuggestionState = Suggestion | null;\n\n/**\n * React hook to allow tracking and replacing of mentions and commands in a div element\n *\n * @param editorRef - a ref to the div that is the composer textbox\n * @param setText - setter function to set the content of the composer\n * @param isAutoReplaceEmojiEnabled - whether plain text emoticons should be auto replaced with emojis\n * @returns\n * - `handleMention`: a function that will insert @ or # mentions which are selected from\n * the autocomplete into the composer, given an href, the text to display, and any additional attributes\n * - `handleCommand`: a function that will replace the content of the composer with the given replacement text.\n * Can be used to process autocomplete of slash commands\n * - `onSelect`: a selection change listener to be attached to the plain text composer\n * - `suggestion`: if the cursor is inside something that could be interpreted as a command or a mention,\n * this will be an object representing that command or mention, otherwise it is null\n */\nexport function useSuggestion(\n editorRef: React.RefObject<HTMLDivElement | null>,\n setText: (text?: string) => void,\n isAutoReplaceEmojiEnabled?: boolean,\n): {\n handleMention: (href: string, displayName: string, attributes: AllowedMentionAttributes) => void;\n handleAtRoomMention: (attributes: AllowedMentionAttributes) => void;\n handleCommand: (text: string) => void;\n handleEmojiSuggestion: (text: string) => void;\n handleEmojiReplacement: () => void;\n onSelect: (event: SyntheticEvent<HTMLDivElement>) => void;\n suggestion: MappedSuggestion | null;\n} {\n const [suggestionData, setSuggestionData0] = useState<SuggestionState>(null);\n\n // debug for https://github.com/vector-im/element-web/issues/26037\n const setSuggestionData = (suggestionData: SetStateAction<SuggestionState>): void => {\n // setState allows either the data itself or a callback which returns the data\n logger.log(\n `## 26037 ## wysiwyg useSuggestion hook setting suggestion data to ${\n suggestionData === null || suggestionData instanceof Function\n ? suggestionData\n : suggestionData.mappedSuggestion.keyChar + suggestionData.mappedSuggestion.text\n }`,\n );\n setSuggestionData0(suggestionData);\n };\n\n // We create a `selectionchange` handler here because we need to know when the user has moved the cursor,\n // we can not depend on input events only\n const onSelect = (): void => processSelectionChange(editorRef, setSuggestionData, isAutoReplaceEmojiEnabled);\n\n const handleMention = (href: string, displayName: string, attributes: AllowedMentionAttributes): void =>\n processMention(href, displayName, attributes, suggestionData, setSuggestionData, setText);\n\n const handleAtRoomMention = (attributes: AllowedMentionAttributes): void =>\n processMention(\"#\", \"@room\", attributes, suggestionData, setSuggestionData, setText);\n\n const handleCommand = (replacementText: string): void =>\n processCommand(replacementText, suggestionData, setSuggestionData, setText);\n\n const handleEmojiReplacement = (): void => processEmojiReplacement(suggestionData, setSuggestionData, setText);\n\n const handleEmojiSuggestion = (emoji: string): void =>\n processTextReplacement(emoji, suggestionData, setSuggestionData, setText);\n\n return {\n suggestion: suggestionData?.mappedSuggestion ?? null,\n handleCommand,\n handleMention,\n handleAtRoomMention,\n handleEmojiSuggestion,\n handleEmojiReplacement,\n onSelect,\n };\n}\n\n/**\n * When the selection changes inside the current editor, check to see if the cursor is inside\n * something that could be a command or a mention and update the suggestion state if so\n *\n * @param editorRef - ref to the composer\n * @param setSuggestionData - the setter for the suggestion state\n * @param isAutoReplaceEmojiEnabled - whether plain text emoticons should be auto replaced with emojis\n */\nexport function processSelectionChange(\n editorRef: React.RefObject<HTMLDivElement | null>,\n setSuggestionData: React.Dispatch<React.SetStateAction<SuggestionState>>,\n isAutoReplaceEmojiEnabled?: boolean,\n): void {\n const selection = document.getSelection();\n\n // return early if we do not have a current editor ref with a cursor selection inside a text node\n if (\n editorRef.current === null ||\n selection === null ||\n !selection.isCollapsed ||\n selection.anchorNode?.nodeName !== \"#text\"\n ) {\n setSuggestionData(null);\n return;\n }\n\n // from here onwards we have a cursor inside a text node\n const { anchorNode: currentNode, anchorOffset: currentOffset } = selection;\n\n // if we have no text content, return, clearing the suggestion state\n if (currentNode.textContent === null) {\n setSuggestionData(null);\n return;\n }\n\n const firstTextNode = document.createNodeIterator(editorRef.current, NodeFilter.SHOW_TEXT).nextNode();\n const isFirstTextNode = currentNode === firstTextNode;\n const foundSuggestion = findSuggestionInText(\n currentNode.textContent,\n currentOffset,\n isFirstTextNode,\n isAutoReplaceEmojiEnabled,\n );\n\n // if we have not found a suggestion, return, clearing the suggestion state\n if (foundSuggestion === null) {\n setSuggestionData(null);\n return;\n }\n\n setSuggestionData({\n mappedSuggestion: foundSuggestion.mappedSuggestion,\n node: currentNode,\n startOffset: foundSuggestion.startOffset,\n endOffset: foundSuggestion.endOffset,\n });\n}\n\n/**\n * Replaces the relevant part of the editor text with a link representing a mention after it\n * is selected from the autocomplete.\n *\n * @param href - the href that the inserted link will use\n * @param displayName - the text content of the link\n * @param attributes - additional attributes to add to the link, can include data-* attributes\n * @param suggestionData - representation of the part of the DOM that will be replaced\n * @param setSuggestionData - setter function to set the suggestion state\n * @param setText - setter function to set the content of the composer\n */\nexport function processMention(\n href: string,\n displayName: string,\n attributes: AllowedMentionAttributes, // these will be used when formatting the link as a pill\n suggestionData: SuggestionState,\n setSuggestionData: React.Dispatch<React.SetStateAction<SuggestionState>>,\n setText: (text?: string) => void,\n): void {\n // if we do not have a suggestion, return early\n if (suggestionData === null) {\n return;\n }\n\n const { node } = suggestionData;\n\n // create an <a> element with the required attributes to allow us to interpret the mention as being a pill\n const linkElement = document.createElement(\"a\");\n const linkTextNode = document.createTextNode(displayName);\n linkElement.setAttribute(\"href\", href);\n linkElement.setAttribute(\"contenteditable\", \"false\");\n\n for (const [attr, value] of attributes.entries()) {\n linkElement.setAttribute(attr, value);\n }\n\n linkElement.appendChild(linkTextNode);\n\n // create text nodes to go before and after the link\n const leadingTextNode = document.createTextNode(node.textContent?.slice(0, suggestionData.startOffset) || \"\\u200b\");\n const trailingTextNode = document.createTextNode(` ${node.textContent?.slice(suggestionData.endOffset) ?? \"\"}`);\n\n // now add the leading text node, link element and trailing text node before removing the node we are replacing\n const parentNode = node.parentNode;\n if (isNotNull(parentNode)) {\n parentNode.insertBefore(leadingTextNode, node);\n parentNode.insertBefore(linkElement, node);\n parentNode.insertBefore(trailingTextNode, node);\n parentNode.removeChild(node);\n }\n\n // move the selection to the trailing text node\n document.getSelection()?.setBaseAndExtent(trailingTextNode, 1, trailingTextNode, 1);\n\n // set the text content to be the innerHTML of the current editor ref and clear the suggestion state\n setText();\n setSuggestionData(null);\n}\n\n/**\n * Replaces the relevant part of the editor text with the replacement text after a command is selected\n * from the autocomplete.\n *\n * @param replacementText - the text that we will insert into the DOM\n * @param suggestionData - representation of the part of the DOM that will be replaced\n * @param setSuggestionData - setter function to set the suggestion state\n * @param setText - setter function to set the content of the composer\n */\nexport function processCommand(\n replacementText: string,\n suggestionData: SuggestionState,\n setSuggestionData: React.Dispatch<React.SetStateAction<SuggestionState>>,\n setText: (text?: string) => void,\n): void {\n // if we do not have a suggestion, return early\n if (suggestionData === null) {\n return;\n }\n\n const { node } = suggestionData;\n\n // for a command, we know we start at the beginning of the text node, so build the replacement\n // string (note trailing space) and manually adjust the node's textcontent\n const newContent = `${replacementText} `;\n node.textContent = newContent;\n\n // then set the cursor to the end of the node, update the `content` state in the usePlainTextListeners\n // hook and clear the suggestion from state\n document.getSelection()?.setBaseAndExtent(node, newContent.length, node, newContent.length);\n setText(newContent);\n setSuggestionData(null);\n}\n\n/**\n * Replaces the relevant part of the editor text, replacing the plain text emoitcon with the suggested emoji.\n *\n * @param suggestionData - representation of the part of the DOM that will be replaced\n * @param setSuggestionData - setter function to set the suggestion state\n * @param setText - setter function to set the content of the composer\n */\nexport function processEmojiReplacement(\n suggestionData: SuggestionState,\n setSuggestionData: React.Dispatch<React.SetStateAction<SuggestionState>>,\n setText: (text?: string) => void,\n): void {\n // if we do not have a suggestion of the correct type, return early\n if (suggestionData?.mappedSuggestion?.type !== `custom`) {\n return;\n }\n\n processTextReplacement(suggestionData.mappedSuggestion.text, suggestionData, setSuggestionData, setText);\n}\n\n/**\n * Replaces the relevant part of the editor text, replacing the suggestionData selection with the replacement text.\n * @param replacementText - the text that we will insert into the DOM\n * @param suggestionData - representation of the part of the DOM that will be replaced\n * @param setSuggestionData - setter function to set the suggestion state\n * @param setText - setter function to set the content of the composer\n */\nexport function processTextReplacement(\n replacementText: string,\n suggestionData: SuggestionState,\n setSuggestionData: React.Dispatch<React.SetStateAction<SuggestionState>>,\n setText: (text?: string) => void,\n): void {\n // if we do not have suggestion data return early\n if (suggestionData === null) {\n return;\n }\n const { node } = suggestionData;\n const existingContent = node.textContent;\n\n if (existingContent == null) {\n return;\n }\n\n // replace the emoticon with the suggesed emoji\n const newContent =\n existingContent.slice(0, suggestionData.startOffset) +\n replacementText +\n existingContent.slice(suggestionData.endOffset);\n\n node.textContent = newContent;\n\n document.getSelection()?.setBaseAndExtent(node, newContent.length, node, newContent.length);\n setText(newContent);\n setSuggestionData(null);\n}\n\n/**\n * Given some text content from a node and the cursor position, find the word that the cursor is currently inside\n * and then test that word to see if it is a suggestion. Return the `MappedSuggestion` with start and end offsets if\n * the cursor is inside a valid suggestion, null otherwise.\n *\n * @param text - the text content of a node\n * @param offset - the current cursor offset position within the node\n * @param isFirstTextNode - whether or not the node is the first text node in the editor. Used to determine\n * if a command suggestion is found or not\n * @param isAutoReplaceEmojiEnabled - whether plain text emoticons should be auto replaced with emojis\n * @returns the `MappedSuggestion` along with its start and end offsets if found, otherwise null\n */\nexport function findSuggestionInText(\n text: string,\n offset: number,\n isFirstTextNode: boolean,\n isAutoReplaceEmojiEnabled?: boolean,\n): { mappedSuggestion: MappedSuggestion; startOffset: number; endOffset: number } | null {\n // Return null early if the offset is outside the content\n if (offset < 0 || offset > text.length) {\n return null;\n }\n\n // Variables to keep track of the indices we will be slicing from and to in order to create\n // a substring of the word that the cursor is currently inside\n let startSliceIndex = offset;\n let endSliceIndex = offset;\n\n // Search backwards from the current cursor position to find the start index of the word\n // containing the cursor\n while (shouldDecrementStartIndex(text, startSliceIndex)) {\n startSliceIndex--;\n }\n\n // Search forwards from the current cursor position to find the end index of the word\n // containing the cursor\n while (shouldIncrementEndIndex(text, endSliceIndex)) {\n endSliceIndex++;\n }\n\n // Get the word at the cursor then check if it contains a suggestion or not\n const wordAtCursor = text.slice(startSliceIndex, endSliceIndex);\n const mappedSuggestion = getMappedSuggestion(wordAtCursor, isAutoReplaceEmojiEnabled);\n\n /**\n * If we have a word that could be a command, it is not a valid command if:\n * - the node we're looking at isn't the first text node in the editor (adding paragraphs can\n * result in nested <p> tags inside the editor <div>)\n * - the starting index is anything other than 0 (they can only appear at the start of a message)\n * - there is more text following the command (eg `/spo asdf|` should not be interpreted as\n * something requiring autocomplete)\n */\n if (\n mappedSuggestion === null ||\n (mappedSuggestion.type === \"command\" &&\n (!isFirstTextNode || startSliceIndex !== 0 || endSliceIndex !== text.length))\n ) {\n return null;\n }\n\n return { mappedSuggestion, startOffset: startSliceIndex, endOffset: startSliceIndex + wordAtCursor.length };\n}\n\n/**\n * Associated function for findSuggestionInText. Checks the character at the preceding index\n * to determine if the search loop should continue.\n *\n * @param text - text content to check for mentions or commands\n * @param index - the current index to check\n * @returns true if check should keep moving backwards, false otherwise\n */\nfunction shouldDecrementStartIndex(text: string, index: number): boolean {\n // If the index is at or outside the beginning of the string, return false\n if (index <= 0) return false;\n\n // We are inside the string so can guarantee that there is a preceding character\n // Keep searching backwards if the preceding character is not a space\n return !/\\s/.test(text[index - 1]);\n}\n\n/**\n * Associated function for findSuggestionInText. Checks the character at the current index\n * to determine if the search loop should continue.\n *\n * @param text - text content to check for mentions or commands\n * @param index - the current index to check\n * @returns true if check should keep moving forwards, false otherwise\n */\nfunction shouldIncrementEndIndex(text: string, index: number): boolean {\n // If the index is at or outside the end of the string, return false\n if (index >= text.length) return false;\n\n // Keep searching forwards if the current character is not a space\n return !/\\s/.test(text[index]);\n}\n\n/**\n * Given a string, return a `MappedSuggestion` if the string contains a suggestion. Otherwise return null.\n *\n * @param text - string to check for a suggestion\n * @param isAutoReplaceEmojiEnabled - whether plain text emoticons should be auto replaced with emojis\n * @returns a `MappedSuggestion` if a suggestion is present, null otherwise\n */\nexport function getMappedSuggestion(text: string, isAutoReplaceEmojiEnabled?: boolean): MappedSuggestion | null {\n if (isAutoReplaceEmojiEnabled) {\n // variations of plaintext emoitcons(E.g. :P vs :p vs :-P) are handled upstream by the emojibase-bindings/emojibase libraries.\n // See rules for variations here https://github.com/milesj/emojibase/blob/master/packages/core/src/generateEmoticonPermutations.ts#L3-L32\n const emoji = EMOTICON_TO_EMOJI.get(text);\n if (emoji?.unicode) {\n return { keyChar: \"\", text: emoji.unicode, type: \"custom\" };\n }\n }\n\n const firstChar = text.charAt(0);\n const restOfString = text.slice(1);\n\n switch (firstChar) {\n case \"/\":\n return { keyChar: firstChar, text: restOfString, type: \"command\" };\n case \"#\":\n case \"@\":\n return { keyChar: firstChar, text: restOfString, type: \"mention\" };\n case \":\":\n return { keyChar: firstChar, text: restOfString, type: \"emoji\" };\n default:\n return null;\n }\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type KeyboardEvent, type RefObject, type SyntheticEvent, useCallback, useRef, useState } from \"react\";\nimport { type AllowedMentionAttributes, type MappedSuggestion } from \"@vector-im/matrix-wysiwyg\";\nimport { type IEventRelation } from \"matrix-js-sdk/src/matrix\";\n\nimport { useSettingValue } from \"../../../../../hooks/useSettings\";\nimport { IS_MAC, Key } from \"../../../../../Keyboard\";\nimport type Autocomplete from \"../../Autocomplete\";\nimport { handleClipboardEvent, handleEventWithAutocomplete, isEventToHandleAsClipboardEvent } from \"./utils\";\nimport { useSuggestion } from \"./useSuggestion\";\nimport { isNotNull, isNotUndefined } from \"../../../../../Typeguards\";\nimport { useMatrixClientContext } from \"../../../../../contexts/MatrixClientContext\";\nimport { useScopedRoomContext } from \"../../../../../contexts/ScopedRoomContext.tsx\";\n\nfunction isDivElement(target: EventTarget): target is HTMLDivElement {\n return target instanceof HTMLDivElement;\n}\n\n/**\n * React hook which generates all of the listeners and the ref to be attached to the editor.\n *\n * Also returns pieces of state and utility functions that are required for use in other hooks\n * and by the autocomplete component.\n *\n * @param initialContent - the content of the editor when it is first mounted\n * @param onChange - called whenever there is change in the editor content\n * @param onSend - called whenever the user sends the message\n * @param eventRelation - used to send the event to the correct place eg timeline vs thread\n * @param isAutoReplaceEmojiEnabled - whether plain text emoticons should be auto replaced with emojis\n * @returns\n * - `ref`: a ref object which the caller must attach to the HTML `div` node for the editor\n * * `autocompleteRef`: a ref object which the caller must attach to the autocomplete component\n * - `content`: state representing the editor's current text content\n * - `setContent`: the setter function for `content`\n * - `onInput`, `onPaste`, `onKeyDown`: handlers for input, paste and keyDown events\n * - the output from the {@link useSuggestion} hook\n */\nexport function usePlainTextListeners(\n initialContent?: string,\n onChange?: (content: string) => void,\n onSend?: () => void,\n eventRelation?: IEventRelation,\n isAutoReplaceEmojiEnabled?: boolean,\n): {\n ref: RefObject<HTMLDivElement | null>;\n autocompleteRef: RefObject<Autocomplete | null>;\n content?: string;\n onBeforeInput(event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>): void;\n onInput(event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>): void;\n onPaste(event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>): void;\n onKeyDown(event: KeyboardEvent<HTMLDivElement>): void;\n setContent(text?: string): void;\n handleMention: (link: string, text: string, attributes: AllowedMentionAttributes) => void;\n handleAtRoomMention: (attributes: AllowedMentionAttributes) => void;\n handleCommand: (text: string) => void;\n handleEmoji: (emoji: string) => void;\n onSelect: (event: SyntheticEvent<HTMLDivElement>) => void;\n suggestion: MappedSuggestion | null;\n} {\n const roomContext = useScopedRoomContext(\"room\", \"timelineRenderingType\", \"replyToEvent\");\n const mxClient = useMatrixClientContext();\n\n const ref = useRef<HTMLDivElement>(null);\n const autocompleteRef = useRef<Autocomplete>(null);\n const [content, setContent] = useState<string | undefined>(initialContent);\n\n const send = useCallback(() => {\n if (ref.current) {\n ref.current.innerHTML = \"\";\n }\n onSend?.();\n }, [ref, onSend]);\n\n const setText = useCallback(\n (text?: string) => {\n if (isNotUndefined(text)) {\n setContent(text);\n onChange?.(text);\n } else if (isNotNull(ref) && isNotNull(ref.current)) {\n // if called with no argument, read the current innerHTML from the ref and amend it as per `onInput`\n const currentRefContent = ref.current.innerHTML;\n setContent(currentRefContent);\n onChange?.(currentRefContent);\n }\n },\n [onChange, ref],\n );\n\n // For separation of concerns, the suggestion handling is kept in a separate hook but is\n // nested here because we do need to be able to update the `content` state in this hook\n // when a user selects a suggestion from the autocomplete menu\n const {\n suggestion,\n onSelect,\n handleCommand,\n handleMention,\n handleAtRoomMention,\n handleEmojiSuggestion,\n handleEmojiReplacement,\n } = useSuggestion(ref, setText, isAutoReplaceEmojiEnabled);\n\n const onInput = useCallback(\n (event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>) => {\n if (isDivElement(event.target)) {\n setText(event.target.innerHTML);\n }\n },\n [setText],\n );\n\n const onPaste = useCallback(\n (event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>) => {\n const { nativeEvent } = event;\n let imagePasteWasHandled = false;\n\n if (isEventToHandleAsClipboardEvent(nativeEvent)) {\n const data =\n nativeEvent instanceof ClipboardEvent ? nativeEvent.clipboardData : nativeEvent.dataTransfer;\n imagePasteWasHandled = handleClipboardEvent(nativeEvent, data, roomContext, mxClient, eventRelation);\n }\n\n // prevent default behaviour and skip call to onInput if the image paste event was handled\n if (imagePasteWasHandled) {\n event.preventDefault();\n } else {\n onInput(event);\n }\n },\n [eventRelation, mxClient, onInput, roomContext],\n );\n\n const enterShouldSend = !useSettingValue(\"MessageComposerInput.ctrlEnterToSend\");\n const onKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n // we need autocomplete to take priority when it is open for using enter to select\n const isHandledByAutocomplete = handleEventWithAutocomplete(autocompleteRef, event);\n if (isHandledByAutocomplete) {\n return;\n }\n // handle accepting of plain text emojicon to emoji replacement\n if (event.key == Key.ENTER || event.key == Key.SPACE) {\n handleEmojiReplacement();\n }\n\n // resume regular flow\n if (event.key === Key.ENTER) {\n // TODO use getKeyBindingsManager().getMessageComposerAction(event) like in useInputEventProcessor\n const sendModifierIsPressed = IS_MAC ? event.metaKey : event.ctrlKey;\n\n // if enter should send, send if the user is not pushing shift\n if (enterShouldSend && !event.shiftKey) {\n event.preventDefault();\n event.stopPropagation();\n send();\n }\n\n // if enter should not send, send only if the user is pushing ctrl/cmd\n if (!enterShouldSend && sendModifierIsPressed) {\n event.preventDefault();\n event.stopPropagation();\n send();\n }\n }\n },\n [autocompleteRef, enterShouldSend, send, handleEmojiReplacement],\n );\n\n return {\n ref,\n autocompleteRef,\n onBeforeInput: onPaste,\n onInput,\n onPaste,\n onKeyDown,\n content,\n setContent: setText,\n suggestion,\n onSelect,\n handleCommand,\n handleMention,\n handleAtRoomMention,\n handleEmoji: handleEmojiSuggestion,\n };\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classNames from \"classnames\";\nimport { type IEventRelation } from \"matrix-js-sdk/src/matrix\";\nimport React, { type JSX, type RefObject, type ReactNode } from \"react\";\n\nimport { useComposerFunctions } from \"../hooks/useComposerFunctions\";\nimport { useIsFocused } from \"../hooks/useIsFocused\";\nimport { usePlainTextInitialization } from \"../hooks/usePlainTextInitialization\";\nimport { usePlainTextListeners } from \"../hooks/usePlainTextListeners\";\nimport { useSetCursorPosition } from \"../hooks/useSetCursorPosition\";\nimport { type ComposerFunctions } from \"../types\";\nimport { Editor } from \"./Editor\";\nimport { WysiwygAutocomplete } from \"./WysiwygAutocomplete\";\nimport { useSettingValue } from \"../../../../../hooks/useSettings\";\n\ninterface PlainTextComposerProps {\n disabled?: boolean;\n onChange?: (content: string) => void;\n onSend?: () => void;\n placeholder?: string;\n initialContent?: string;\n className?: string;\n leftComponent?: ReactNode;\n rightComponent?: ReactNode;\n children?: (ref: RefObject<HTMLDivElement | null>, composerFunctions: ComposerFunctions) => ReactNode;\n eventRelation?: IEventRelation;\n}\n\nexport function PlainTextComposer({\n className,\n disabled = false,\n onSend,\n onChange,\n children,\n placeholder,\n initialContent,\n leftComponent,\n rightComponent,\n eventRelation,\n}: PlainTextComposerProps): JSX.Element {\n const isAutoReplaceEmojiEnabled = useSettingValue(\"MessageComposerInput.autoReplaceEmoji\");\n const {\n ref: editorRef,\n autocompleteRef,\n onBeforeInput,\n onInput,\n onPaste,\n onKeyDown,\n content,\n setContent,\n suggestion,\n onSelect,\n handleCommand,\n handleMention,\n handleAtRoomMention,\n handleEmoji,\n } = usePlainTextListeners(initialContent, onChange, onSend, eventRelation, isAutoReplaceEmojiEnabled);\n const composerFunctions = useComposerFunctions(editorRef, setContent);\n usePlainTextInitialization(initialContent, editorRef);\n useSetCursorPosition(disabled, editorRef);\n const { isFocused, onFocus } = useIsFocused();\n const computedPlaceholder = (!content && placeholder) || undefined;\n return (\n <div\n data-testid=\"PlainTextComposer\"\n className={classNames(className, { [`${className}-focused`]: isFocused })}\n onFocus={onFocus}\n onBlur={onFocus}\n onBeforeInput={onBeforeInput}\n onInput={onInput}\n onPaste={onPaste}\n onKeyDown={onKeyDown}\n onSelect={onSelect}\n >\n <WysiwygAutocomplete\n ref={autocompleteRef}\n suggestion={suggestion}\n handleMention={handleMention}\n handleCommand={handleCommand}\n handleAtRoomMention={handleAtRoomMention}\n handleEmoji={handleEmoji}\n />\n <Editor\n ref={editorRef}\n disabled={disabled}\n leftComponent={leftComponent}\n rightComponent={rightComponent}\n placeholder={computedPlaceholder}\n />\n {children?.(editorRef, composerFunctions)}\n </div>\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type RefObject, useMemo } from \"react\";\n\nimport { setSelection } from \"../utils/selection\";\n\nexport function useComposerFunctions(\n ref: RefObject<HTMLDivElement | null>,\n setContent: (content: string) => void,\n): {\n clear(): void;\n insertText(text: string): void;\n} {\n return useMemo(\n () => ({\n clear: () => {\n if (ref.current) {\n // eslint-disable-next-line react-compiler/react-compiler\n ref.current.innerHTML = \"\";\n }\n },\n insertText: (text: string) => {\n const selection = document.getSelection();\n\n if (ref.current && selection) {\n const content = ref.current.innerHTML;\n const { anchorOffset, focusOffset } = selection;\n ref.current.innerHTML = `${content.slice(0, anchorOffset)}${text}${content.slice(focusOffset)}`;\n setSelection({\n anchorNode: ref.current.firstChild,\n anchorOffset: anchorOffset + text.length,\n focusNode: ref.current.firstChild,\n focusOffset: focusOffset + text.length,\n isForward: true,\n });\n setContent(ref.current.innerHTML);\n }\n },\n }),\n [ref, setContent],\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type RefObject, useEffect } from \"react\";\n\nexport function usePlainTextInitialization(initialContent = \"\", ref: RefObject<HTMLElement | null>): void {\n useEffect(() => {\n // always read and write the ref.current using .innerHTML for consistency in linebreak and HTML entity handling\n if (ref.current) {\n // eslint-disable-next-line react-compiler/react-compiler\n ref.current.innerHTML = initialContent;\n }\n }, [ref, initialContent]);\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type JSX } from \"react\";\n\nimport { type MenuProps } from \"../../../../structures/ContextMenu\";\nimport { EmojiButton } from \"../../EmojiButton\";\nimport dis from \"../../../../../dispatcher/dispatcher\";\nimport { type ComposerInsertPayload } from \"../../../../../dispatcher/payloads/ComposerInsertPayload\";\nimport { Action } from \"../../../../../dispatcher/actions\";\nimport { useScopedRoomContext } from \"../../../../../contexts/ScopedRoomContext.tsx\";\n\ninterface EmojiProps {\n menuPosition: MenuProps;\n}\n\nexport function Emoji({ menuPosition }: EmojiProps): JSX.Element {\n const roomContext = useScopedRoomContext(\"timelineRenderingType\");\n\n return (\n <EmojiButton\n menuPosition={menuPosition}\n addEmoji={(emoji) => {\n dis.dispatch<ComposerInsertPayload>({\n action: Action.ComposerInsert,\n text: emoji,\n timelineRenderingType: roomContext.timelineRenderingType,\n });\n return true;\n }}\n />\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type JSX, type RefObject, useMemo, type ReactNode } from \"react\";\nimport { type IEventRelation } from \"matrix-js-sdk/src/matrix\";\nimport LockOffIcon from \"@vector-im/compound-design-tokens/assets/web/icons/lock-off\";\n\nimport { useWysiwygSendActionHandler } from \"./hooks/useWysiwygSendActionHandler\";\nimport { WysiwygComposer } from \"./components/WysiwygComposer\";\nimport { PlainTextComposer } from \"./components/PlainTextComposer\";\nimport { type ComposerFunctions } from \"./types\";\nimport { E2EStatus } from \"../../../../utils/ShieldUtils\";\nimport E2EIcon from \"../E2EIcon\";\nimport { type MenuProps } from \"../../../structures/ContextMenu\";\nimport { Emoji } from \"./components/Emoji\";\nimport { ComposerContext, getDefaultContextValue } from \"./ComposerContext\";\n\ninterface ContentProps {\n disabled?: boolean;\n composerFunctions: ComposerFunctions;\n ref?: RefObject<HTMLElement | null>;\n}\n\nconst Content = function Content({ disabled = false, composerFunctions, ref }: ContentProps): ReactNode {\n useWysiwygSendActionHandler(disabled, ref, composerFunctions);\n return null;\n};\n\nexport interface SendWysiwygComposerProps {\n initialContent?: string;\n isRichTextEnabled: boolean;\n placeholder?: string;\n disabled?: boolean;\n e2eStatus?: E2EStatus;\n onChange: (content: string) => void;\n onSend: () => void;\n menuPosition: MenuProps;\n eventRelation?: IEventRelation;\n}\n\n// Default needed for React.lazy\nexport default function SendWysiwygComposer({\n isRichTextEnabled,\n e2eStatus,\n menuPosition,\n ...props\n}: SendWysiwygComposerProps): JSX.Element {\n const Composer = isRichTextEnabled ? WysiwygComposer : PlainTextComposer;\n const defaultContextValue = useMemo(\n () => getDefaultContextValue({ eventRelation: props.eventRelation }),\n [props.eventRelation],\n );\n\n let leftIcon: false | JSX.Element = false;\n if (!e2eStatus) {\n leftIcon = (\n <LockOffIcon\n data-testid=\"e2e-icon\"\n width={12}\n height={12}\n color=\"var(--cpd-color-icon-info-primary)\"\n className=\"mx_E2EIcon\"\n />\n );\n } else if (e2eStatus !== E2EStatus.Normal) {\n leftIcon = <E2EIcon status={e2eStatus} size={12} />;\n }\n return (\n <ComposerContext.Provider value={defaultContextValue}>\n <Composer\n className=\"mx_SendWysiwygComposer\"\n leftComponent={leftIcon}\n rightComponent={<Emoji menuPosition={menuPosition} />}\n {...props}\n >\n {(ref, composerFunctions) => (\n <Content disabled={props.disabled} ref={ref} composerFunctions={composerFunctions} />\n )}\n </Composer>\n </ComposerContext.Provider>\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type RefObject, useCallback, useRef } from \"react\";\n\nimport defaultDispatcher from \"../../../../../dispatcher/dispatcher\";\nimport { Action } from \"../../../../../dispatcher/actions\";\nimport { type ActionPayload } from \"../../../../../dispatcher/payloads\";\nimport { TimelineRenderingType } from \"../../../../../contexts/RoomContext\";\nimport { useDispatcher } from \"../../../../../hooks/useDispatcher\";\nimport { focusComposer } from \"./utils\";\nimport { type ComposerFunctions } from \"../types\";\nimport { ComposerType } from \"../../../../../dispatcher/payloads/ComposerInsertPayload\";\nimport { useComposerContext } from \"../ComposerContext\";\nimport { setSelection } from \"../utils/selection\";\nimport { useScopedRoomContext } from \"../../../../../contexts/ScopedRoomContext.tsx\";\n\nexport function useWysiwygSendActionHandler(\n disabled: boolean,\n composerElement: RefObject<HTMLElement | null> | undefined,\n composerFunctions: ComposerFunctions,\n): void {\n const roomContext = useScopedRoomContext(\"timelineRenderingType\");\n const composerContext = useComposerContext();\n const timeoutId = useRef<number | null>(null);\n\n const handler = useCallback(\n (payload: ActionPayload) => {\n // don't let the user into the composer if it is disabled - all of these branches lead\n // to the cursor being in the composer\n if (disabled || !composerElement?.current) return;\n\n const context = payload.context ?? TimelineRenderingType.Room;\n\n switch (payload.action) {\n case \"reply_to_event\":\n case Action.FocusAComposer:\n case Action.FocusSendMessageComposer:\n focusComposer(composerElement, context, roomContext, timeoutId);\n break;\n case Action.ClearAndFocusSendMessageComposer:\n // When a thread is opened, prevent the main composer to steal the thread composer focus\n if (payload.timelineRenderingType !== roomContext.timelineRenderingType) break;\n\n composerFunctions.clear();\n focusComposer(composerElement, context, roomContext, timeoutId);\n break;\n case Action.ComposerInsert:\n if (payload.timelineRenderingType !== roomContext.timelineRenderingType) break;\n if (payload.composerType !== ComposerType.Send) break;\n\n if (payload.userId) {\n // TODO insert mention - see SendMessageComposer\n } else if (payload.event) {\n // TODO insert quote message - see SendMessageComposer\n } else if (payload.text) {\n setSelection(composerContext.selection).then(() => composerFunctions.insertText(payload.text));\n }\n break;\n }\n },\n [disabled, composerElement, roomContext, composerFunctions, composerContext],\n );\n\n useDispatcher(defaultDispatcher, handler);\n}\n","import { forwardRef } from \"react\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nfunction LockOffIcon(props, ref) {\n return /*#__PURE__*/_jsx(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"1em\",\n height: \"1em\",\n fill: \"currentColor\",\n viewBox: \"0 0 24 24\",\n ref: ref,\n ...props,\n children: /*#__PURE__*/_jsx(\"path\", {\n d: \"M6 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 4 20V10q0-.825.588-1.412a2 2 0 0 1 .702-.463L1.333 4.167a1 1 0 0 1 1.414-1.414L7 7.006v-.012l13 13v.012l1.247 1.247a1 1 0 1 1-1.414 1.414l-.896-.896A1.94 1.94 0 0 1 18 22zm14-4.834V10q0-.825-.587-1.412A1.93 1.93 0 0 0 18 8h-1V6q0-2.075-1.463-3.537Q14.075 1 12 1T8.463 2.463a4.9 4.9 0 0 0-1.22 1.946L9 6.166V6q0-1.25.875-2.125A2.9 2.9 0 0 1 12 3q1.25 0 2.125.875T15 6v2h-4.166z\"\n })\n });\n}\n;\nLockOffIcon.displayName = \"LockOffIcon\";\nexport default forwardRef(LockOffIcon);","import { forwardRef } from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nfunction MicOnIcon(props, ref) {\n return /*#__PURE__*/_jsxs(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"1em\",\n height: \"1em\",\n fill: \"currentColor\",\n viewBox: \"0 0 24 24\",\n ref: ref,\n ...props,\n children: [/*#__PURE__*/_jsx(\"path\", {\n d: \"M6 12a1 1 0 1 0-2 0 8 8 0 0 0 7 7.938V21a1 1 0 1 0 2 0v-1.062A8 8 0 0 0 20 12a1 1 0 1 0-2 0 6 6 0 0 1-12 0\"\n }), /*#__PURE__*/_jsx(\"path\", {\n fillRule: \"evenodd\",\n d: \"M14 12V6a2 2 0 1 0-4 0v6a2 2 0 1 0 4 0M12 2a4 4 0 0 0-4 4v6a4 4 0 0 0 8 0V6a4 4 0 0 0-4-4\",\n clipRule: \"evenodd\"\n })]\n });\n}\n;\nMicOnIcon.displayName = \"MicOnIcon\";\nexport default forwardRef(MicOnIcon);","import { forwardRef } from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nfunction ReactionIcon(props, ref) {\n return /*#__PURE__*/_jsxs(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"1em\",\n height: \"1em\",\n fill: \"currentColor\",\n viewBox: \"0 0 24 24\",\n ref: ref,\n ...props,\n children: [/*#__PURE__*/_jsx(\"path\", {\n d: \"M15.536 15.536a1 1 0 0 0-1.415-1.415 3 3 0 0 1-2.12.879 3 3 0 0 1-2.122-.879 1 1 0 1 0-1.414 1.415A5 5 0 0 0 12 17c1.38 0 2.632-.56 3.536-1.464M10 10.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m5.5 1.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3\"\n }), /*#__PURE__*/_jsx(\"path\", {\n d: \"M22 12c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2s10 4.477 10 10m-2 0a8 8 0 1 0-16 0 8 8 0 0 0 16 0\"\n })]\n });\n}\n;\nReactionIcon.displayName = \"ReactionIcon\";\nexport default forwardRef(ReactionIcon);","import { forwardRef } from \"react\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nfunction StickerIcon(props, ref) {\n return /*#__PURE__*/_jsx(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"1em\",\n height: \"1em\",\n fill: \"currentColor\",\n viewBox: \"0 0 24 24\",\n ref: ref,\n ...props,\n children: /*#__PURE__*/_jsx(\"path\", {\n fillRule: \"evenodd\",\n d: \"M17 2a5 5 0 0 1 5 4.999v5.335a5 5 0 0 1-1.58 3.647l-4.978 4.667A5 5 0 0 1 12.023 22H7l-.258-.007A5 5 0 0 1 2 17V7a5 5 0 0 1 5-5zM7 4a3 3 0 0 0-3 3v10a3 3 0 0 0 2.999 3H12v-4a4 4 0 0 1 4-4h4V6.999A3 3 0 0 0 17 4zm9 10a2 2 0 0 0-2 2v3.251l.074-.062 4.978-4.666q.252-.238.441-.523z\",\n clipRule: \"evenodd\"\n })\n });\n}\n;\nStickerIcon.displayName = \"StickerIcon\";\nexport default forwardRef(StickerIcon);","import { forwardRef } from \"react\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nfunction TextFormattingIcon(props, ref) {\n return /*#__PURE__*/_jsx(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"1em\",\n height: \"1em\",\n fill: \"currentColor\",\n viewBox: \"0 0 24 24\",\n ref: ref,\n ...props,\n children: /*#__PURE__*/_jsx(\"path\", {\n d: \"M6 19a.97.97 0 0 1-.713-.288A.97.97 0 0 1 5 18q0-.424.287-.712A.97.97 0 0 1 6 17h12q.424 0 .712.288.288.287.288.712 0 .424-.288.712A.97.97 0 0 1 18 19zm1.35-5.2 3.425-9.2a.9.9 0 0 1 .338-.437A.93.93 0 0 1 11.65 4h.7q.3 0 .537.162.238.163.338.438l3.425 9.225q.15.425-.1.8a.8.8 0 0 1-.7.375.9.9 0 0 1-.512-.162A.9.9 0 0 1 15 14.4l-.75-2.2H9.8L9 14.425a.84.84 0 0 1-.325.425q-.225.15-.5.15a.84.84 0 0 1-.738-.387.82.82 0 0 1-.087-.813m3-3.2h3.3l-1.6-4.55h-.1z\"\n })\n });\n}\n;\nTextFormattingIcon.displayName = \"TextFormattingIcon\";\nexport default forwardRef(TextFormattingIcon);"],"names":["CollapsibleButton","_ref","title","children","className","inputRef","props","_objectWithoutProperties","_excluded","useContext","OverflowMenuContext","React","IconizedContextMenuOption","_extends","icon","label","AccessibleButton","ref","EmojiButton","addEmoji","menuPosition","overflowMenuCloser","menuDisplayed","button","openMenu","closeMenu","useContextMenu","contextMenu","current","position","aboveLeftOf","getBoundingClientRect","onFinished","ContextMenu","managed","focusLock","EmojiPicker","onChoose","computedClassName","classNames","mx_EmojiButton_highlight","onClick","_t","ReactionIcon","createContext","emojiButton","key","uploadButton","UploadButton","UploadButtonContext","UploadButtonContextProvider","roomId","relation","cli","MatrixClientContext","roomContext","useScopedRoomContext","uploadInput","useRef","onUploadClick","_uploadInput$current","isGuest","dis","dispatch","action","click","useDispatcher","payload","timelineRenderingType","context","Provider","value","type","style","display","multiple","chromeFileInputFix","onChange","ev","_ev$target$files","target","files","length","ContentMessages","sharedInstance","sendContentListToRoom","Array","from","replyToEvent","uploadButtonFn","AttachmentIcon","showStickersButton","id","setStickerPickerOpen","isStickerPickerOpen","StickerIcon","voiceRecordingButton","narrow","onRecordStartEndClick","MicOnIcon","pollButton","room","PollButton","constructor","args","_defineProperty","_this$context","this","call","currentState","maySendEvent","M_POLL_START","name","MatrixClientPeg","safeGet","getSafeUserId","_this$props$relation","threadId","rel_type","THREAD_RELATION_TYPE","event_id","undefined","Modal","createDialog","PollCreateDialog","ErrorDialog","description","render","_this$props$relation2","onCreateClick","PollsIcon","showLocationButton","matrixClient","sender","getMember","LocationButton","ComposerModeButton","isRichTextEnabled","TextFormattingIcon","isWysiwygLabEnabled","useSettingValue","haveRecording","mainButtons","moreButtons","onComposerModeClick","showPollsButton","filterBoolean","moreOptionsClasses","mx_MessageComposer_button","mx_MessageComposer_buttonMenu","mx_MessageComposer_closeButtonMenu","isMenuOpen","toggleButtonMenu","OverflowHorizontalIcon","IconizedContextMenu","wrapperClassName","compact","IconizedContextMenuOptionList","useSuggestion","editorRef","setText","isAutoReplaceEmojiEnabled","_suggestionData$mappe","suggestionData","setSuggestionData0","useState","setSuggestionData","logger","log","Function","mappedSuggestion","keyChar","text","suggestion","handleCommand","replacementText","_document$getSelectio2","node","newContent","textContent","document","getSelection","setBaseAndExtent","processCommand","handleMention","href","displayName","attributes","processMention","handleAtRoomMention","handleEmojiSuggestion","emoji","processTextReplacement","handleEmojiReplacement","_suggestionData$mappe2","processEmojiReplacement","onSelect","_selection$anchorNode","selection","isCollapsed","anchorNode","nodeName","currentNode","anchorOffset","currentOffset","firstTextNode","createNodeIterator","NodeFilter","SHOW_TEXT","nextNode","isFirstTextNode","foundSuggestion","offset","startSliceIndex","endSliceIndex","shouldDecrementStartIndex","shouldIncrementEndIndex","wordAtCursor","slice","EMOTICON_TO_EMOJI","get","unicode","firstChar","charAt","restOfString","getMappedSuggestion","startOffset","endOffset","findSuggestionInText","processSelectionChange","_node$textContent","_node$textContent$sli","_node$textContent2","_document$getSelectio","linkElement","createElement","linkTextNode","createTextNode","setAttribute","attr","entries","appendChild","leadingTextNode","trailingTextNode","parentNode","isNotNull","insertBefore","removeChild","_document$getSelectio3","existingContent","index","test","usePlainTextListeners","initialContent","onSend","eventRelation","mxClient","useMatrixClientContext","autocompleteRef","content","setContent","send","useCallback","innerHTML","isNotUndefined","currentRefContent","onInput","event","HTMLDivElement","onPaste","nativeEvent","imagePasteWasHandled","isEventToHandleAsClipboardEvent","data","ClipboardEvent","clipboardData","dataTransfer","handleClipboardEvent","preventDefault","enterShouldSend","onKeyDown","handleEventWithAutocomplete","Key","ENTER","SPACE","sendModifierIsPressed","IS_MAC","metaKey","ctrlKey","shiftKey","stopPropagation","onBeforeInput","handleEmoji","PlainTextComposer","disabled","placeholder","leftComponent","rightComponent","composerFunctions","useMemo","clear","insertText","focusOffset","setSelection","firstChild","focusNode","isForward","useComposerFunctions","useEffect","usePlainTextInitialization","useSetCursorPosition","isFocused","onFocus","useIsFocused","computedPlaceholder","onBlur","WysiwygAutocomplete","Editor","Emoji","Action","ComposerInsert","Content","composerElement","composerContext","useComposerContext","timeoutId","handler","_payload$context","TimelineRenderingType","Room","FocusAComposer","FocusSendMessageComposer","focusComposer","ClearAndFocusSendMessageComposer","composerType","ComposerType","Send","userId","then","defaultDispatcher","useWysiwygSendActionHandler","SendWysiwygComposer","e2eStatus","Composer","WysiwygComposer","defaultContextValue","getDefaultContextValue","leftIcon","E2EStatus","Normal","E2EIcon","status","size","LockOffIcon","width","height","color","ComposerContext","xmlns","fill","viewBox","d","forwardRef","fillRule","clipRule"],"sourceRoot":""}