Google Summer of Code 2025 for Rocket.Chat
Hello, this is Ishan! I created this repository as a dedicated hub for my final work product submission, which illustrates and highlights my contributions to Rocket.Chat during Google Summer of Code - 2025.
The Message Composer refers to Rocket.Chat's textbox component inside the chatroom. It includes the textbox where users can type messages, use the formatter buttons, and attach files.
The project implements real-time rendering of the user's text message, including bold, italics, and strikethrough, as well as converting emoji text shortcodes such as :rocket: to 🚀.
This quality-of-life feature is much needed, as it allows users to quickly preview the outcome of their message before sending, rather than looking at raw Markdown plaintext, such as _this_.
- Develop a new
RichTextComposercomponent with rich-text support - Create a Storybook component to ensure the integrity of the design is maintained
- Implement backward-compatible APIs for the
RichTextComposercomponent to maintain integrity with the oldComposer - Support keyboard interactions for formatting shortcuts and message navigation
- Verify consistent behavior across Chromium-based and Firefox-based browsers
- Render bold, italics, strikethrough, and inline code as the user types
- Render username mentions,
@all,@here - Convert emoji shortcodes to Unicode emojis1
- Render custom server emojis to images1, 2
- Ensure user can undo or redo edits3
- Render unordered lists, ordered lists, quote blocks, multiline code, KaTeX, tables
- Handle rendering on drag-and-drop, copy-paste, cut-paste4
1 Cursor jumps to the start of the message when a shorthand converts to an emoji in the parent Composer. This affects the RichTextComposer.
2 Limited support. Rendition logic needs refinement, as non-text assets (e.g., GIFs) don’t preserve the original shorthand.
3 Unsupported. Rich text rendition logic destroys edit history. Requires implementation of the edit history stack. Keyboard shortcuts don't work.
4 Limited support. Cut-paste and Copy-paste events work. Drag-and-drop causes glitches.
The following table lists key commits from the pull request. It highlights only the most important changes made during the development of the RichTextComposer.
| Commit | Short description |
|---|---|
| 4bad5c1 | Replace textarea with contenteditable inside ComposerMessageInput |
| 7f97121 | Implement getSelectionRange / setSelectionRange as replacements for textarea selection APIs |
| b999a60 | Implement cursor tracking so formatter button clicks work correctly |
| 43d567b | Add a placeholder inside the RichTextComposer component |
| 3f77840 | Update getSelectionRange / setSelectionRange to traverse DOM tree structures |
| 21d4e8b | @MartinSchoeler: Wrapping RichTextComposer inside FeaturePreview |
| 1f4562e | Update contenteditable from div to span for better cross-browser inline support |
| 949e19f | Add composer state handlers to track text/cursor on edit events in render pipeline |
| 322744b | Integrate Gazzodown parseMessage helper function to parse AST in the render pipeline |
| 39c2b5d | Implement messageParser to convert AST to HTML in the rich text rendering pipeline |
| 8103d3f | Implement shortcode to native Unicode character or custom emoji image |
| e730794 | Final commit during the Coding Period of Google Summer of Code 2025 |
The deliverables have been largely implemented, though there is still room for improvement. Additional commits will be pushed to the PR after the conclusion of GSoC.
This project was developed in tandem with the AI Enhanced Message Composer Component, which builds upon the new RichTextComposer component.
hero-video-e.mp4
- Different browsers handle text input inside
contenteditablein very different ways, often leading to unexpected inconsistencies. - A script that runs smoothly on Chromium often breaks on Firefox unless carefully accounted for.
- Using
execCommandwithin aninputevent caused highly unpredictable behavior, making it clear this approach should be avoided. - While the core pipeline design was straightforward, the overall scale and complexity of the monorepo significantly increased the implementation effort.
- Bugfixes in both the original
ComposerandRichTextComposer - Add support for more advanced Markdown layouts, such as code blocks with syntax highlighting
- Work on the React Native client to bring this feature to Android and iOS smartphones
I am very grateful to my mentors, who encouraged me to work with a strong sense of teamwork and discipline. Since I was working closely with another GSoC contributor, this guidance became even more valuable. Their technical advice and focus on making small, meaningful commits helped me improve both my collaboration skills and my work approach.
I wish to thank two other mentors and my fellow GSoC contributor. Their extended support is extremely appreciated.