Skip to content

Add new RichTextEditor component (#12505)#12531

Merged
msynk merged 43 commits into
bitfoundation:developfrom
msynk:12505-blazorui-new-richtexteditor
Jul 3, 2026
Merged

Add new RichTextEditor component (#12505)#12531
msynk merged 43 commits into
bitfoundation:developfrom
msynk:12505-blazorui-new-richtexteditor

Conversation

@msynk

@msynk msynk commented Jun 27, 2026

Copy link
Copy Markdown
Member

closes #12505

Summary by CodeRabbit

  • New Features
    • Added a new HTML-first RichTextEditor with debounced two-way binding, configurable height/placeholder/read-only, optional max-length with character count, source view, fullscreen toggle, and text direction.
    • Added toolbar controls with configurable group ordering/custom items, plus link/image/media/table/rule insertion, emoji picker, slash menu, find/replace, and keyboard shortcuts.
    • Added sanitization policy support and EditForm validation integration.
  • Bug Fixes
    • Improved URL/HTML validation and editor state synchronization/error reporting.
  • Breaking Changes
    • Replaced the prior Quill-based API and removed bundled Quill typings and theme assets.
  • Documentation / Tests
    • Updated the RichTextEditor demo and refreshed unit tests.

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e4ee277d-e5c6-4fe7-94d2-a564abb5a8b0

📥 Commits

Reviewing files that changed from the base of the PR and between 4288250 and ff4c70b.

📒 Files selected for processing (3)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts

Walkthrough

The PR replaces the RichTextEditor’s Quill-based typings, scripts, and styles with a native Blazor editor backed by an element-based JS bridge. It adds new public models and parameters for toolbar, sanitization, selection, upload, and view behaviors, rewrites the component rendering and interop flow, and updates the demo and tests.

Changes

Native RichTextEditor replacement

Layer / File(s) Summary
Quill declarations removed
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/..., src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.*.css
Legacy Quill, Parchment, editor, module, theme, toolbar, selection, and utility declaration files, plus bundled Quill Snow and Bubble stylesheets, are deleted from the RichTextEditor package.
New contracts and support models
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs, BitRichTextEditorContentFacts.cs, BitRichTextEditorSelectionState.cs, BitRichTextEditorImageUpload.cs, BitRichTextEditorSanitizationPolicy.cs, BitRichTextEditorToolbar.cs, BitRichTextEditorToolbarConfig.cs, BitRichTextEditorToolbarItem.cs, IBitRichTextEditorLocalizer.cs, BitRichTextEditorClassStyles.cs, BitRichTextEditorSetupOptions.cs, BitRichTextEditorTheme.cs, BitRichTextEditorModule.cs, QuillModule.cs
Adds the new editor contracts, toolbar and sanitization types, localizer interface, style extensions, and setup options, while removing obsolete Quill-era public models.
Component core and JS bridge
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs, BitRichTextEditor.View.cs, BitRichTextEditorJsRuntimeExtensions.cs, BitRichTextEditor.ts
The Blazor component core rewrites value binding, initialization, callbacks, localization, and disposal around the editor element reference, and the TypeScript engine switches to element-based HTML editing, sanitization, command dispatch, find/replace, tables, media, keyboard shortcuts, and selection-state reporting.
Feature partial classes
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs, BitRichTextEditor.Emoji.cs, BitRichTextEditor.Find.cs, BitRichTextEditor.Forms.cs, BitRichTextEditor.Links.cs, BitRichTextEditor.Media.cs, BitRichTextEditor.Sanitization.cs, BitRichTextEditor.Shortcuts.cs, BitRichTextEditor.Slash.cs, BitRichTextEditor.SourceView.cs, BitRichTextEditor.Structured.cs, BitRichTextEditor.Tables.cs
Partial classes implement count, emoji, find, forms, links, media, sanitization, shortcuts, slash commands, source view, structured insertion, and table behavior.
Razor template and SCSS
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor, BitRichTextEditor.scss, BitRichTextEditorClassStyles.cs
The component now renders its toolbar, inline panels, source view, slash menu, and counters directly, with matching Bit-scoped styling and updated CSS hook properties.
Demo page and test suite
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor, BitRichTextEditorDemo.razor.cs, BitRichTextEditorDemo.razor.scss, src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
The demo documents and exercises the new API and features, and the tests are updated for the new bridge and component behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Poem

🐇 No more Quill, no more old tracks,
The rabbit hops on native stacks.
Buttons, emoji, source view too,
Sanitized HTML shining through ✨
A toolbar blooms, the editor sings—
Hoppy trails to better things!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a new RichTextEditor component.
Linked Issues check ✅ Passed The PR adds a native Blazor RichTextEditor and removes the old JS-library wrapper, matching #12505.
Out of Scope Changes check ✅ Passed The changes are broadly tied to the editor replacement, including API, tests, demo, styles, and typings, with no clear unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 17

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (5)
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs-333-336 (1)

333-336: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

[Required] should treat visually empty HTML as empty
At BitRichTextEditorDemo.razor.cs lines 333-336 and 431-435, the editor sends raw innerHTML back to .NET, so markup like <p><br></p> still satisfies [Required]. Use a validator that checks rendered text/content facts or normalize empty HTML before binding.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs`
around lines 333 - 336, The FormModel.Body field is being validated with
[Required] on raw innerHTML, so visually empty editor content like <p><br></p>
still passes. Update the binding path in BitRichTextEditorDemo and the FormModel
validation flow to normalize the editor value before it reaches Body, or replace
[Required] with a custom validator that checks for meaningful rendered
text/content instead of HTML markup.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss-243-243 (1)

243-243: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the quoted font-family names to satisfy Stylelint.

These two declarations currently violate font-family-name-quotes and will keep the stylesheet linting red.

Suggested change
-    font-family: "SFMono-Regular", Consolas, monospace;
+    font-family: SFMono-Regular, Consolas, monospace;
...
-        font-family: "SFMono-Regular", Consolas, monospace;
+        font-family: SFMono-Regular, Consolas, monospace;

Also applies to: 312-312

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss`
at line 243, Update the font-family declarations in RichTextEditor.scss to
satisfy Stylelint’s font-family-name-quotes rule by removing quotes from the
font names in the affected RichTextEditor styles. Make the same adjustment at
both occurrences of the monospace stack in the SCSS so the stylesheet passes
linting consistently.

Source: Linters/SAST tools

src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs-19-20 (1)

19-20: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Default Block to "p" instead of an empty string.

The block-format dropdown binds straight to _state.Block, and the current options do not include "". That leaves the toolbar blank until JS sends a selection state, even though the editor's default block is effectively a paragraph.

Suggested change
-    public string Block { get; set; } = "";
+    public string Block { get; set; } = "p";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs`
around lines 19 - 20, The RichTextEditor selection state is initializing Block
to an empty string, which leaves the block-format dropdown without a matching
option until JavaScript updates it. Update the default value in
BitRichTextEditorSelectionState.Block so it starts as "p", matching the editor’s
default paragraph block and the options bound from _state.Block.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs-24-31 (1)

24-31: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Block slash actions in read-only mode.

This path can still open the slash menu and mutate content after the component becomes read-only. The other insertion flows already guard ReadOnly, so slash commands are the remaining write bypass.

Proposed fix
     [JSInvokable("OnSlashTrigger")]
     public void _OnSlashTrigger()
     {
+        if (ReadOnly) return;
         _slashFilter = "";
         _showSlash = true;
         StateHasChanged();
     }
@@
     private async Task ApplySlashAsync(string command)
     {
+        if (ReadOnly)
+        {
+            CloseSlash();
+            return;
+        }
         _showSlash = false;
         _slashFilter = "";
         await _js.BitRichTextEditorApplySlashCommand(_editorRef, command);
     }

Also applies to: 46-50

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs`
around lines 24 - 31, The slash trigger handler in BitRichTextEditor.Slash
(_OnSlashTrigger) still opens the menu even when the editor is read-only,
creating a write bypass. Add the same ReadOnly guard used by the other insertion
paths before changing _slashFilter, _showSlash, or calling StateHasChanged, and
apply the same protection to the related slash-action flow referenced in the
comment so slash commands are fully blocked in read-only mode.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs-19-23 (1)

19-23: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Merge case-insensitive attribute keys before ToDictionary().

Lowercasing the key here means a policy that contains both "A" and "a" will throw during setup instead of producing a deterministic allowlist. Since this is a public configuration surface, normalize with a case-insensitive comparer or merge duplicates before building the payload.

Proposed fix
             allowedAttributes = SanitizationPolicy.AllowedAttributes
-                .ToDictionary(
-                    kv => kv.Key.ToLowerInvariant(),
-                    kv => kv.Value.Select(a => a.ToLowerInvariant()).ToArray()),
+                .GroupBy(kv => kv.Key, StringComparer.OrdinalIgnoreCase)
+                .ToDictionary(
+                    g => g.Key.ToLowerInvariant(),
+                    g => g.SelectMany(kv => kv.Value)
+                          .Select(a => a.ToLowerInvariant())
+                          .Distinct()
+                          .ToArray()),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`
around lines 19 - 23, The allowedAttributes mapping in BitRichTextEditor
sanitization currently lowercases keys before ToDictionary, which can throw if
SanitizationPolicy.AllowedAttributes contains duplicate keys that differ only by
case. Update the normalization step in the sanitization setup to use a
case-insensitive merge/comparer or otherwise coalesce duplicate attribute names
before building the allowlist, so the payload is deterministic and does not fail
during initialization.
🧹 Nitpick comments (1)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs (1)

12-20: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add coverage for the sanitization interop path.

This rewrite moved XSS filtering behind the new bridge, but the suite never exercises BitBlazorUI.RichTextEditor.sanitizeHtml or a non-null SanitizationPolicy. A broken JS identifier or allowlist payload would still pass here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`
around lines 12 - 20, The RichTextEditor tests only cover the existing JS
interop calls and miss the sanitization bridge path. Update
BitRichTextEditorTests to exercise BitBlazorUI.RichTextEditor.sanitizeHtml by
configuring a non-null SanitizationPolicy and asserting the sanitization interop
is invoked as part of the editor flow. Use the existing JSInterop setup in the
test class to add coverage for the bridge identifier and verify the
allowlist/payload is passed through correctly so a broken identifier or
malformed policy can’t slip through.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs`:
- Around line 20-25: The cached FieldIdentifier in EnsureField() is only
initialized once, so it can become stale when ValueExpression changes. Update
RichTextEditor’s field-tracking logic in EnsureField() to detect binding changes
and recompute _fieldIdentifier whenever the current ValueExpression differs from
the one previously cached, so NotifyFieldChanged() always uses the active bound
field.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs`:
- Around line 61-69: Reject protocol-relative URLs in IsAcceptableLinkUrl by
narrowing the current slash check so only true site-relative paths are allowed;
the existing StartsWith('/') branch also accepts //example.com, which should be
treated as external. Update the link allowlist in BitRichTextEditor.Links.cs to
distinguish a single leading slash from a double-slash URL, while keeping the
explicit http(s), mailto, tel, and hash cases intact.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs`:
- Around line 41-52: Apply the same ReadOnly protection used by ExecAsync and
the other formatting handlers to ApplyImageUrlAsync in BitRichTextEditor.Media,
so image insertion is blocked when the editor is read-only. Before calling
_js.BitRichTextEditorInsertImageUrl, check ReadOnly and return early (optionally
raising the same no-edit error pattern used elsewhere), and keep the dialog
state reset only when insertion is actually allowed.
- Around line 80-83: The upload failure handler in RichTextEditor.Media is
leaking raw exception details into the UI via RaiseErrorAsync in the
OnImageUpload catch block. Update the catch path in the image upload flow to
send a generic user-facing message for upload-failed instead of ex.Message, and
keep the full exception details only in logging/telemetry so
BitRichTextEditorError and RaiseErrorAsync do not expose infrastructure or auth
information.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`:
- Around line 206-334: The toolbar button class/style hook is only applied in
HistoryGroup, leaving the other button groups inconsistent. Update the button
markup in the RichTextEditor toolbar fragments (such as InlineGroup, ColorGroup,
ListsGroup, AlignmentGroup, and the other group render fragments) to use
`@Classes`?.Button and `@Styles`?.Button on each bit-rte-btn so the public styling
contract is applied uniformly across all toolbar buttons.
- Around line 21-125: The new form controls in BitRichTextEditor.razor rely on
placeholders only, so they are missing accessible names. Add explicit labels or
aria-label/aria-labelledby for the URL inputs, find/replace fields, emoji
search, slash filter, and the source-view textarea so screen readers can
identify them. Update the inputs in the _showLinkInput, _showImageInput,
_showMediaInput, _showFind, _showEmoji, _showSlash, and _inSourceView sections
without changing their current behavior.
- Around line 13-18: The rich text editor toolbar still hard-codes English
labels and tooltips instead of using the new localizer, so route all user-facing
toolbar strings in BitRichTextEditor.razor through IBitRichTextEditorLocalizer.
Update the toolbar container label and the text/tooltip values used by
RenderGroup, OrderedToolbarIds, and the button/menu rendering paths so items
like Undo, Paragraph format, Heading 1, and Full screen come from the localizer
rather than literals. Verify the main toolbar surface and all related
label/tooltip helpers in the BitRichTextEditor component use the localizer
consistently.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs`:
- Around line 246-249: The toolbar roving setup in BitRichTextEditor is only
performed on the first-render path, so when ShowToolbar changes from false to
true later it never gets initialized. Update the component logic around the
toolbar initialization flow in BitRichTextEditor.razor.cs so that
BitRichTextEditorEnableToolbarRoving is also invoked when ShowToolbar
transitions to true after render, using the existing _toolbarRef and the
relevant lifecycle/update method in BitRichTextEditor.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs`:
- Around line 25-30: The keyboard bridge is ignoring the handled/unhandled
result from BitRichTextEditor._OnShortcut, so shortcuts beyond b/i/u still fall
through to the browser default. Update the JS side in BitRichTextEditor.ts to
await the OnShortcut JSInvokable call and, when it returns true, call
preventDefault() (and stop further processing) for all mapped combos including
ctrl+z, ctrl+y, and any custom shortcut keys.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs`:
- Around line 38-39: The source-view save path in RichTextEditor currently
updates the value and fires OnChange but skips EditContext notification, so it
won’t behave like the normal edit flow. Update the source-view handler that
calls AssignValue and OnChange to also invoke NotifyEditContextChanged after the
bound value is assigned, matching the existing edit path behavior so EditForm
tracking and validation run correctly.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs`:
- Around line 47-50: The YouTube embed path in BuildMediaEmbed/TryGetYouTubeId
is inserting an unescaped video id into iframe HTML, creating an XSS risk.
Validate the id extracted from GetQueryValue/TryGetYouTubeId against the
expected YouTube id format before using it, and HTML-escape or otherwise safely
encode it when building the iframe in BuildMediaEmbed. Apply the same fix to the
other embed branch referenced by the comment so no user-controlled value is
concatenated into HTML attributes unsafely.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 156-176: The URI allowlist from
BitRichTextEditorSanitizationPolicy is not being applied in the link/image
flows, so custom allowedUriSchemes and allowDataImageUris have no effect. Update
the URL handling in BitRichTextEditor’s createLink, updateLink, and
insertImageUrl paths to validate against the active sanitization policy before
writing href/src or dispatching createLink/insertImage, and reuse the existing
URI sanitization helper(s) so only allowed schemes/data URIs are accepted.
- Around line 724-731: The MaxLength enforcement in BitRichTextEditor’s
insert/edit path currently treats every change as additive, so replacing an
existing selection is blocked or over-truncated at the limit. Update the logic
around the max check in the editor insertion flow to account for the currently
selected range size (and any content being replaced) before deciding whether to
return or slice the input, so in-place edits at max length are allowed when the
net length does not increase. Apply the same adjustment in the other affected
insert path referenced by the review so both branches use the selection-aware
length calculation consistently.
- Around line 261-301: The RichTextEditor.find/clearFind flow is inserting
transient <mark class="bit-rte-find"> nodes into the live editable DOM, which
can leak into editor.innerHTML and Value. Update the RichTextEditor search
highlighting so it is only temporary: before any content snapshot or persistence
path (especially afterChange and any toolbar command that reads innerHTML),
ensure clearFind(editor) runs, and keep the find state isolated so the editable
content itself is restored before saving. Use the existing clearFind, find, and
afterChange hooks to contain the search markup.
- Around line 108-126: Sanitize inbound HTML before it reaches the DOM in
BitRichTextEditor.setHtml. The current editor assignment path writes the
provided Value/html directly to innerHTML, so update the RichTextEditor flow to
apply BitRichTextEditorSanitizeHtml (or an equivalent safe default) before any
innerHTML or insertHTML call, especially when SanitizationPolicy is null. Make
sure the fix is applied in the setHtml method and the BitRichTextEditor.razor.cs
ValueChanged/default policy path so all entry points use the same secure HTML
handling.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs`:
- Around line 23-52: The shared Default policy in
BitRichTextEditorSanitizationPolicy is mutable, so any consumer modifying its
sets or dictionaries can unintentionally change sanitization for all later
editors. Update the Default property to return a fresh policy instance or switch
the allowlists in BitRichTextEditorSanitizationPolicy to immutable/read-only
collections so callers cannot mutate the process-wide default.
- Around line 48-50: Remove "data" from the generic AllowedUriSchemes set in
BitRichTextEditorSanitizationPolicy so the default href/src scheme allowlist
only covers non-data schemes. Keep data URI handling behind the existing
AllowDataImageUris image-specific switch, and update the policy initialization
so data: URLs are only permitted where image sanitization explicitly allows
them.

---

Minor comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`:
- Around line 19-23: The allowedAttributes mapping in BitRichTextEditor
sanitization currently lowercases keys before ToDictionary, which can throw if
SanitizationPolicy.AllowedAttributes contains duplicate keys that differ only by
case. Update the normalization step in the sanitization setup to use a
case-insensitive merge/comparer or otherwise coalesce duplicate attribute names
before building the allowlist, so the payload is deterministic and does not fail
during initialization.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss`:
- Line 243: Update the font-family declarations in RichTextEditor.scss to
satisfy Stylelint’s font-family-name-quotes rule by removing quotes from the
font names in the affected RichTextEditor styles. Make the same adjustment at
both occurrences of the monospace stack in the SCSS so the stylesheet passes
linting consistently.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs`:
- Around line 24-31: The slash trigger handler in BitRichTextEditor.Slash
(_OnSlashTrigger) still opens the menu even when the editor is read-only,
creating a write bypass. Add the same ReadOnly guard used by the other insertion
paths before changing _slashFilter, _showSlash, or calling StateHasChanged, and
apply the same protection to the related slash-action flow referenced in the
comment so slash commands are fully blocked in read-only mode.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs`:
- Around line 19-20: The RichTextEditor selection state is initializing Block to
an empty string, which leaves the block-format dropdown without a matching
option until JavaScript updates it. Update the default value in
BitRichTextEditorSelectionState.Block so it starts as "p", matching the editor’s
default paragraph block and the options bound from _state.Block.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs`:
- Around line 333-336: The FormModel.Body field is being validated with
[Required] on raw innerHTML, so visually empty editor content like <p><br></p>
still passes. Update the binding path in BitRichTextEditorDemo and the FormModel
validation flow to normalize the editor value before it reaches Body, or replace
[Required] with a custom validator that checks for meaningful rendered
text/content instead of HTML markup.

---

Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`:
- Around line 12-20: The RichTextEditor tests only cover the existing JS interop
calls and miss the sanitization bridge path. Update BitRichTextEditorTests to
exercise BitBlazorUI.RichTextEditor.sanitizeHtml by configuring a non-null
SanitizationPolicy and asserting the sanitization interop is invoked as part of
the editor flow. Use the existing JSInterop setup in the test class to add
coverage for the bridge identifier and verify the allowlist/payload is passed
through correctly so a broken identifier or malformed policy can’t slip through.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: afc9b637-5a12-4633-9a3f-974f7c3974e5

📥 Commits

Reviewing files that changed from the base of the PR and between f990c5a and 7cf0f84.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts

@msynk

msynk commented Jun 27, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

@msynk I'll re-review the latest changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 123-125: The URI checks in RichTextEditor.isAllowedUri and the
sanitization flow in RichTextEditor.sanitize are too permissive for obfuscated
schemes and do not consistently protect pasted/source/setHtml HTML. Normalize
the candidate URI before scheme validation so whitespace/control-obfuscated
values like java\nscript: are treated as unsafe, and reuse the same validator
inside sanitize() so all inbound HTML paths (including paste, source import, and
setHtml) are enforced by the active policy rather than only the command
handlers. Ensure the shared logic is applied consistently across the affected
RichTextEditor methods.
- Around line 798-804: The shortcut handling in BitRichTextEditor is still
awaiting OnShortcut before deciding to cancel, which lets browser defaults win
for custom combos. Update the key handling around the
editor._dotNetRef.invokeMethodAsync flow so owned shortcuts are identified and
prevented synchronously in JS before any await, using the existing key handling
logic in BitRichTextEditor and the shortcut path that currently checks ['b',
'i', 'u', 'z', 'y']. Keep the .NET callback for custom handling, but do not rely
on its returned handled flag to stop native behavior for overlapping shortcuts.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor`:
- Around line 77-78: The demo is rendering editor-controlled content through
MarkupString, which bypasses Blazor’s HTML encoding. Update
BitRichTextEditorDemo and the rendered output block to show the bound HTML as
plain text instead of injecting it into the DOM, or only render it after it has
passed through the trusted sanitization path used by the editor workflow. Keep
the bindingHtml display intact, but remove the direct MarkupString-based
rendering so the sample code does not encourage unsafe usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b80d2455-482a-46ef-a7d3-535245069a24

📥 Commits

Reviewing files that changed from the base of the PR and between 7cf0f84 and 35f43bc.

📒 Files selected for processing (16)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts Outdated
@msynk

msynk commented Jun 27, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs (1)

17-36: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Don’t cache FieldIdentifier only by ValueExpression reference.

FieldIdentifier.Create(...) captures the current model behind the expression. Line 32 only invalidates the cache when the Expression object changes, so a parent that reuses the same ValueExpression instance while swapping the EditForm model can still notify the old field. That leaves validation attached to the wrong model. The safest fix is to rebuild the FieldIdentifier each time EnsureField() runs, or include the current EditContext/model identity in the cache key.

Minimal fix
     private FieldIdentifier _fieldIdentifier;
     private bool _hasField;
-    private Expression<Func<string?>>? _cachedValueExpression;
 
     private void EnsureField()
     {
         if (ValueExpression is null)
         {
             _hasField = false;
-            _cachedValueExpression = null;
             return;
         }
 
-        // Recompute whenever the bound expression changes so a rebinding never leaves us
-        // notifying a stale field.
-        if (_hasField is false || _cachedValueExpression != ValueExpression)
-        {
-            _fieldIdentifier = FieldIdentifier.Create(ValueExpression);
-            _cachedValueExpression = ValueExpression;
-            _hasField = true;
-        }
+        _fieldIdentifier = FieldIdentifier.Create(ValueExpression);
+        _hasField = true;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs`
around lines 17 - 36, The caching in EnsureField() is too narrow because
FieldIdentifier.Create(ValueExpression) can still point to an old model even
when the same ValueExpression instance is reused. Update BitRichTextEditor.Forms
so EnsureField() rebuilds the FieldIdentifier every time it runs, or expand the
cache invalidation in EnsureField() to also consider the current
EditContext/model identity instead of only _cachedValueExpression.
🧹 Nitpick comments (2)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs (1)

11-38: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Localize the emoji catalog instead of hard-coding English search terms.

The picker’s labels and searchable keywords are fixed English strings, so localized hosts still surface and search this menu in English only. Consider separating invariant emoji ids from localized display/search text, or make the catalog injectable through the same localization path as the rest of the editor.

Also applies to: 46-53

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs`
around lines 11 - 38, The Emoji catalog in BitRichTextEditor.Emoji is hard-coded
with English labels and keywords, so localized editors still show English-only
labels and search terms. Update the static EmojiEntry list to use localized
display/search text or route it through the same localization/injection
mechanism used by the rest of the editor, keeping the invariant emoji
identifiers separate from user-facing strings.
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs (1)

83-95: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tighten the toolbar filtering assertion.

This test should fail if Toolbar=Inline renders extra groups. Assert the exact inline button count instead of >= 4.

Proposed fix
-        Assert.IsTrue(component.FindAll(".bit-rte-tlb .bit-rte-btn").Count >= 4);
+        Assert.AreEqual(4, component.FindAll(".bit-rte-tlb .bit-rte-btn").Count);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`
around lines 83 - 95, The BitRichTextEditorShouldRenderToolbarGroups test is too
permissive because it uses a minimum count check, so extra toolbar groups could
still pass. In BitRichTextEditorShouldRenderToolbarGroups, tighten the assertion
on component.FindAll(".bit-rte-tlb .bit-rte-btn") to verify the exact Inline
toolbar button count for BitRichTextEditorToolbar.Inline, so the test fails if
BitRichTextEditor renders any additional groups.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs`:
- Around line 24-45: ApplyLinkAsync in BitRichTextEditor.Links should respect
the editor’s ReadOnly state before mutating the document. Add the same ReadOnly
guard used by the other command helpers and RemoveLinkAsync, so the method exits
early without calling BitRichTextEditorUpdateLink or BitRichTextEditorCreateLink
when the editor is read-only. Keep the existing validation flow intact, but
block the JS link update/create path and only close/reset the dialog when the
write is allowed.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`:
- Around line 119-124: The editable surface in BitRichTextEditor is missing an
accessible textbox name and role; update the contenteditable div in the editor
markup to expose it as a textbox with multiline semantics and a clear accessible
name. Add role="textbox" and aria-multiline="true", and provide either
aria-label or aria-labelledby on the same element so assistive technologies can
identify the editor properly while keeping the existing ReadOnly and
_inSourceView behavior unchanged.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs`:
- Around line 233-251: The first-render flow in
BitRichTextEditor.OnAfterRenderAsync is writing the initial Value directly into
the editor before sanitization is applied, so unsafe HTML can bypass
SanitizationPolicy. Update the first-render path (including the later update
path referenced in the comment) to sanitize _currentHtml/Value using the same
policy logic used by OnValueSet before calling BitRichTextEditorSetHtml, and
keep the behavior consistent with _initialized so the editor never receives
unsanitized initial content.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs`:
- Around line 43-47: BuildOwnedShortcutCombos() is advertising custom shortcut
keys that _OnShortcut() and IsKnownCommand() may later reject as unknown, so
only include shortcuts whose command can actually be executed. Update the
shortcut-building logic in BitRichTextEditor.Shortcuts to filter custom key
entries against the known command set (the same check used in _OnShortcut), so
the JS bridge only suppresses browser defaults for combos the editor truly
handles.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs`:
- Around line 43-49: LooksLikeValidHtml in BitRichTextEditor.SourceView is only
counting angle brackets, so malformed or misnested markup can still pass and be
committed. Replace that heuristic with a real HTML parse/validation step in the
source-view exit path, using the bridge logic that decides whether to leave
source view, so invalid HTML is rejected before committing user input.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs`:
- Around line 53-57: The YouTube and Vimeo host validation in the RichTextEditor
embed parsing is too permissive because substring matching can accept spoofed
hosts like youtube.com.evil.test. Update the host checks in the embed-handling
logic (the YouTube/Vimeo branches in BitRichTextEditor.Structured) to use exact
host comparison or a proper subdomain-suffix match against the parsed Uri.Host,
so only legitimate youtube.com, youtu.be, and vimeo.com hosts are accepted
before generating iframe embeds.
- Around line 18-39: ApplyMediaAsync in BitRichTextEditor.Structured should
respect the editor’s ReadOnly state before mutating content. Add the same
read-only guard used by other insert/update paths near the start of
ApplyMediaAsync, before building or inserting the embed, and return early
without calling _js.BitRichTextEditorInsertMedia when the editor is read-only.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs`:
- Around line 89-98: The InvokeCustomItemAsync catch block is surfacing the raw
exception message through RaiseErrorAsync, which can leak host callback
internals to the UI. Update the BitRichTextEditorToolbarItem activation error
handling to pass a generic user-facing BitRichTextEditorError message instead of
ex.Message, and keep the caught exception only for logging/telemetry outside the
inline UI path.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 220-223: The insertMedia method in RichTextEditor is inserting the
provided HTML directly via insertHTML without sanitization. Update insertMedia
to route media content through the existing safe media-building path or apply a
media-specific allowlist/sanitizer before dispatching the insertMedia action, so
only approved markup reaches RichTextEditor.dispatch and afterChange.
- Around line 967-1001: The sanitize method in BitRichTextEditor currently only
removes a small denylist when editor._policy is absent, so it does not enforce
the documented secure default allowlist. Update sanitize to start from an
explicit built-in allowlist of permitted tags, attributes, and URI schemes, then
merge or override with the custom policy from editor._policy; ensure non-URI
attributes like form/action-related fields are blocked unless explicitly
allowed, while keeping the existing isAllowedUri checks and attribute filtering
behavior in place.
- Around line 606-617: The mergeSelectedCells method currently merges all
intersecting cells into the first cell by only increasing colspan, which breaks
multi-row selections and can create malformed tables. Update the logic in
mergeSelectedCells to compute the selected rectangle across rows and columns,
then set both rowspan and colspan on the top-left cell and remove or normalize
the other cells in the merged area. Use the existing table/cell selection
handling in BitRichTextEditor.ts to locate the fix and keep the merge behavior
correct for 2×2 and larger selections.
- Around line 703-710: The image handling in RichTextEditor.handleImageFiles
should fail per file instead of letting readAsDataUrl or ResolveImageUrl
rejections escape the whole paste/drop flow. Wrap the per-file upload/read logic
in a try/catch around the existing dataUrl,
editor._dotNetRef.invokeMethodAsync('ResolveImageUrl'), and insertImage path,
then route any failure through OnClientError (via the existing RichTextEditor
error dispatch pattern) and continue to the next file. Keep the fix localized to
handleImageFiles and its use of readAsDataUrl/ResolveImageUrl so one bad file
does not abort the entire batch.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs`:
- Around line 11-16: The ToggleFullScreen flow in BitRichTextEditor.View
currently updates _fullScreen before calling BitRichTextEditorSetFullScreen,
which can leave the component visually out of sync if the JS interop fails. Move
the _fullScreen state change to after the await on
_js.BitRichTextEditorSetFullScreen(_editorRef, _fullScreen) succeeds, and keep
ClassBuilder.Reset and StateHasChanged aligned with the confirmed state so the
fullscreen UI only updates when the browser action succeeds.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs`:
- Around line 23-55: The secure default in
BitRichTextEditorSanitizationPolicy.Default still allows arbitrary iframe embeds
via the "iframe" tag and its src-related attributes, which should not be part of
the baseline formatting allowlist. Remove iframe from the default AllowedTags
and drop the iframe entry from AllowedAttributes in Default, leaving iframe
support to be opt-in via custom policies while keeping the rest of the editor
sanitization defaults intact.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs`:
- Around line 17-36: The caching in EnsureField() is too narrow because
FieldIdentifier.Create(ValueExpression) can still point to an old model even
when the same ValueExpression instance is reused. Update BitRichTextEditor.Forms
so EnsureField() rebuilds the FieldIdentifier every time it runs, or expand the
cache invalidation in EnsureField() to also consider the current
EditContext/model identity instead of only _cachedValueExpression.

---

Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs`:
- Around line 11-38: The Emoji catalog in BitRichTextEditor.Emoji is hard-coded
with English labels and keywords, so localized editors still show English-only
labels and search terms. Update the static EmojiEntry list to use localized
display/search text or route it through the same localization/injection
mechanism used by the rest of the editor, keeping the invariant emoji
identifiers separate from user-facing strings.

In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`:
- Around line 83-95: The BitRichTextEditorShouldRenderToolbarGroups test is too
permissive because it uses a minimum count check, so extra toolbar groups could
still pass. In BitRichTextEditorShouldRenderToolbarGroups, tighten the assertion
on component.FindAll(".bit-rte-tlb .bit-rte-btn") to verify the exact Inline
toolbar button count for BitRichTextEditorToolbar.Inline, so the test fails if
BitRichTextEditor renders any additional groups.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b09ac936-2f59-49b9-b400-f4a7070c8758

📥 Commits

Reviewing files that changed from the base of the PR and between f990c5a and e0ef3df.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts Outdated
@msynk

msynk commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

♻️ Duplicate comments (2)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs (1)

236-250: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Sanitize the initial Value before the first SetHtml.

OnValueSet() sanitizes external HTML, but the first-render path writes Value straight into the editor. That bypasses SanitizationPolicy for the initial load.

Patch idea
             await _js.BitRichTextEditorSetup(_editorRef, _dotnetObj, new()
             {
                 Debounce = DebounceMs,
                 Policy = BuildPolicyPayload(),
                 HasUpload = OnImageUpload is not null,
                 PlainTextPaste = PasteAsPlainText,
                 MaxLength = MaxLength,
                 ShortcutKeys = BuildOwnedShortcutCombos()
             });
 
+            if (SanitizationPolicy is not null && string.IsNullOrEmpty(_currentHtml) is false)
+            {
+                _currentHtml = await _js.BitRichTextEditorSanitizeHtml(_editorRef, _currentHtml);
+            }
+
             if (string.IsNullOrEmpty(_currentHtml) is false)
             {
                 await _js.BitRichTextEditorSetHtml(_editorRef, _currentHtml);
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs`
around lines 236 - 250, The initial editor load in BitRichTextEditor bypasses
SanitizationPolicy because _currentHtml is assigned directly from Value before
the first BitRichTextEditorSetHtml call. Update the BitRichTextEditor.razor.cs
initialization path so the same sanitization used by OnValueSet is applied to
the initial Value before setting _currentHtml and passing it to
_js.BitRichTextEditorSetHtml, keeping the setup flow in sync with the existing
policy handling in BitRichTextEditorSetup.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts (1)

478-489: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return the fullscreen promise before flipping C# state.

requestFullscreen().catch(...) is not returned, so the interop call resolves before the browser accepts/rejects fullscreen. ToggleFullScreen() can still set _fullScreen = true after a denied request.

🐛 Proposed fix direction
 public static setFullScreen(editor: any, on: boolean) {
@@
             if (on) {
                 if (root.requestFullscreen) {
-                    root.requestFullscreen().catch(() => {
+                    return root.requestFullscreen().catch(() => {
                         if (editor._dotNetRef) editor._dotNetRef.invokeMethodAsync('OnClientError', 'fullscreen-denied', 'Full-screen mode was blocked by the browser.');
+                        throw new Error('fullscreen-denied');
                     });
                 }
             } else if (document.fullscreenElement) {
-                document.exitFullscreen?.();
+                return document.exitFullscreen?.();
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`
around lines 478 - 489, The setFullScreen flow in BitRichTextEditor currently
fires requestFullscreen().catch(...) without returning it, so the interop
completes before fullscreen is actually accepted or denied. Update the
setFullScreen method to return the fullscreen promise from the
root.requestFullscreen path, and ensure the caller path in ToggleFullScreen
waits on that promise before updating C# state like _fullScreen. Preserve the
existing OnClientError handling in the catch branch so denial is still reported
correctly.
🧹 Nitpick comments (3)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs (1)

145-163: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make this assertion prove the call came from the Value update.

VerifyInvoke("BitBlazorUI.RichTextEditor.sanitizeHtml") still passes if the bridge is only hit during the initial render. Capture the pre-update invocation count (or clear prior invocations) before SetParametersAndRender, then assert the count increases after the Value change so the test covers the behavior its name describes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`
around lines 145 - 163, The test for BitRichTextEditor sanitization is too weak
because `VerifyInvoke("BitBlazorUI.RichTextEditor.sanitizeHtml")` can pass from
an earlier render. In
`BitRichTextEditorShouldInvokeSanitizeBridgeWhenPolicyIsSet`, capture the
JSInterop invocation count or clear invocations after the initial
`RenderComponent<BitRichTextEditor>` setup and before `SetParametersAndRender`,
then assert the sanitize bridge is invoked again only after the `Value`
parameter change so the test specifically proves the update path.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts (1)

1146-1148: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Merge wildcard attributes with tag-specific attributes.

policy.allowedAttributes[tag] || policy.allowedAttributes['*'] means global attributes like class, style, and dir are dropped from tags that define their own attributes, such as a and img.

♻️ Proposed fix
                     if (policy && policy.allowedAttributes) {
-                        const allowed = policy.allowedAttributes[tag] || policy.allowedAttributes['*'] || [];
+                        const allowed = [
+                            ...(policy.allowedAttributes['*'] || []),
+                            ...(policy.allowedAttributes[tag] || [])
+                        ];
                         if (!allowed.includes(name)) el.removeAttribute(attr.name);
                     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`
around lines 1146 - 1148, The attribute allowlist logic in BitRichTextEditor is
incorrectly choosing either tag-specific attributes or wildcard attributes,
which drops global attributes for tags like a and img. Update the sanitization
path around the allowedAttributes check to merge policy.allowedAttributes[tag]
with policy.allowedAttributes['*'] in the attribute filtering logic, so both
sets are honored before removing el.removeAttribute(attr.name).
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs (1)

8-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider exposing built-in toolbar ids as constants.

Order is intentionally stringly typed and unknown ids are skipped, so a typo in "blockformat" or "fullscreen" silently changes the rendered toolbar. Publishing the built-in ids from code would make this API much harder to misuse.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs`
around lines 8 - 18, Expose the built-in toolbar entry ids as named constants or
a shared readonly list alongside BitRichTextEditorToolbarConfig so callers can
reference them instead of hardcoding strings in Order; update the config surface
to publish the existing built-in ids (history, blockformat, font, inline, color,
script, lists, indent, blocks, link, media, image, table, rule, alignment,
direction, emoji, find, source, fullscreen, clear) and keep Order accepting
those symbols to reduce typo-prone string usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs`:
- Around line 47-58: Apply the same 1000-character validation used by
RunFindAsync to the replace paths in BitRichTextEditor.Find.cs. Update
ReplaceCurrentAsync and ReplaceAllAsync so they reject oversized _findTerm
values before calling _js.BitRichTextEditorReplaceCurrent or
_js.BitRichTextEditorReplaceAll, using the same guard behavior as the find flow.
Keep the fix localized to the replace methods so all search/replace entry points
enforce the same term-length limit.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`:
- Around line 100-110: Move the slash filter textbox out of the element with
role="listbox" in BitRichTextEditor.razor so the listbox contains only the slash
command options rendered by FilteredSlash() and the bit-rte-slash-item buttons.
Keep the filtering input separate from the options container, while preserving
its current bindings and Escape handling in the _showSlash block. This will keep
the accessibility tree valid and avoid nesting non-option content inside the
listbox.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs`:
- Around line 238-246: The first-render setup in BitRichTextEditor.razor.cs
freezes bridge options by passing Debounce, Policy, HasUpload, PlainTextPaste,
MaxLength, and ShortcutKeys only through BitRichTextEditorSetup, so later
parameter changes never reach the JS bridge. Update the RichTextEditor
initialization flow (around the BitRichTextEditorSetup call and related
setup/state methods) so these options are refreshed whenever their corresponding
component parameters change, not only on first render. Use the existing symbols
BuildPolicyPayload, BuildOwnedShortcutCombos, and BitRichTextEditorSetup to
locate the setup path and ensure the JS config stays aligned with the current C#
state.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`:
- Around line 20-27: The sanitization payload builder is dropping wildcard
attributes because `BitRichTextEditor.Sanitization.cs` only emits per-tag
entries from `SanitizationPolicy.AllowedAttributes`, so the JS sanitizer’s
`allowedAttributes[tag] || allowedAttributes['*']` fallback never gets the
shared `"*"` values when a specific tag exists. Update the payload construction
in the sanitization mapping logic to preserve and merge the `"*"` attributes
into each tag-specific entry (or otherwise emit `"*"` separately without being
shadowed), using the existing `SanitizationPolicy.AllowedAttributes` and the
builder that produces the `allowedAttributes` dictionary.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss`:
- Around line 212-237: The editor surfaces in BitRichTextEditor.scss suppress
focus outlines on .bit-rte-src and .bit-rte-edt without providing an accessible
replacement. Update these selectors to restore a visible keyboard focus state,
preferably using :focus-visible on both the source textarea and the editable
surface, and keep the styling consistent with the existing editor theme.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs`:
- Around line 34-39: The shortcut lookup in BitRichTextEditor.Shortcuts uses the
raw combo string from BuildComboKey, but custom shortcuts are normalized to
lowercase in BuildOwnedShortcutCombos, so case-variant keys can be advertised
yet never match. Update the lookup in the shortcut handling path to normalize
the generated combo the same way before probing KeyboardShortcuts and
DefaultShortcuts, keeping the matching behavior consistent with
BuildOwnedShortcutCombos and the related shortcut methods in BitRichTextEditor.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs`:
- Around line 12-22: The slash menu item labels in BitRichTextEditor.Slash.cs
are hardcoded and bypass the existing localization path used by the component.
Update the SlashCommands definitions so each display label is passed through the
same Label(...) localization mechanism used in BitRichTextEditor.razor, and keep
the command values unchanged; use the SlashCommands array as the main place to
align these menu entries with the localized placeholder and empty state.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 847-854: The image insertion flow in RichTextEditor currently
skips URI policy checks for both the raw data URL and the URL returned by
ResolveImageUrl. Update the upload/paste/drop path around the
dataUrl/ResolveImageUrl handling to validate the final URL with the existing
isAllowedUri logic before calling dispatch with insertImage, and reject or skip
insertion when the policy disallows data URIs or the resolved scheme. Keep the
fix localized to the RichTextEditor upload insertion code so the existing
allowlist behavior is enforced consistently.
- Around line 293-318: The media insertion flow in RichTextEditor is bypassing
the active sanitization policy because insertMedia() and sanitizeMedia() allow
iframe embeds even when DEFAULT_POLICY would reject them. Update
insertMedia()/sanitizeMedia() to first honor the current editor policy before
allowing media tags, so iframe/embed markup is only permitted when the active
policy allows it and won’t be stripped later by setHtml(). Keep the fix
localized to the RichTextEditor media sanitization path and reuse the existing
policy checks used elsewhere in the component.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs`:
- Around line 19-20: The default value for BitRichTextEditorSelectionState.Block
is incorrect because it represents an active paragraph format instead of an
inactive/unknown state. Update the Block property in
BitRichTextEditorSelectionState so omitted JS data deserializes as no active
block, and keep the summary aligned with the inactive-by-default behavior.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss`:
- Around line 6-7: The wrapping layout in the RichTextEditor demo styles is
being negated by the container’s max-width setting. Update the styling in
BitRichTextEditorDemo.razor.scss for the flex container that uses flex-flow so
it can shrink on narrow viewports by removing max-width: max-content or
replacing it with a width-constrained value, allowing the wrapped buttons to
flow instead of overflowing.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs`:
- Around line 236-250: The initial editor load in BitRichTextEditor bypasses
SanitizationPolicy because _currentHtml is assigned directly from Value before
the first BitRichTextEditorSetHtml call. Update the BitRichTextEditor.razor.cs
initialization path so the same sanitization used by OnValueSet is applied to
the initial Value before setting _currentHtml and passing it to
_js.BitRichTextEditorSetHtml, keeping the setup flow in sync with the existing
policy handling in BitRichTextEditorSetup.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 478-489: The setFullScreen flow in BitRichTextEditor currently
fires requestFullscreen().catch(...) without returning it, so the interop
completes before fullscreen is actually accepted or denied. Update the
setFullScreen method to return the fullscreen promise from the
root.requestFullscreen path, and ensure the caller path in ToggleFullScreen
waits on that promise before updating C# state like _fullScreen. Preserve the
existing OnClientError handling in the catch branch so denial is still reported
correctly.

---

Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 1146-1148: The attribute allowlist logic in BitRichTextEditor is
incorrectly choosing either tag-specific attributes or wildcard attributes,
which drops global attributes for tags like a and img. Update the sanitization
path around the allowedAttributes check to merge policy.allowedAttributes[tag]
with policy.allowedAttributes['*'] in the attribute filtering logic, so both
sets are honored before removing el.removeAttribute(attr.name).

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs`:
- Around line 8-18: Expose the built-in toolbar entry ids as named constants or
a shared readonly list alongside BitRichTextEditorToolbarConfig so callers can
reference them instead of hardcoding strings in Order; update the config surface
to publish the existing built-in ids (history, blockformat, font, inline, color,
script, lists, indent, blocks, link, media, image, table, rule, alignment,
direction, emoji, find, source, fullscreen, clear) and keep Order accepting
those symbols to reduce typo-prone string usage.

In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`:
- Around line 145-163: The test for BitRichTextEditor sanitization is too weak
because `VerifyInvoke("BitBlazorUI.RichTextEditor.sanitizeHtml")` can pass from
an earlier render. In
`BitRichTextEditorShouldInvokeSanitizeBridgeWhenPolicyIsSet`, capture the
JSInterop invocation count or clear invocations after the initial
`RenderComponent<BitRichTextEditor>` setup and before `SetParametersAndRender`,
then assert the sanitize bridge is invoked again only after the `Value`
parameter change so the test specifically proves the update path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1deeb3ae-2957-4eef-8c84-8575ab376c2b

📥 Commits

Reviewing files that changed from the base of the PR and between f990c5a and ebc3ddf.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts Outdated
@msynk

msynk commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

♻️ Duplicate comments (3)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs (1)

90-100: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep owned shortcuts aligned with custom overrides.

KeyboardShortcuts wins in _OnShortcut, but BuildOwnedShortcutCombos() always seeds built-ins. If a consumer overrides ctrl+b with an unknown command, ctrl+b remains advertised as owned while _OnShortcut rejects it, so the bridge can suppress a shortcut the editor does not handle. This is a remaining edge case of the previously flagged shortcut-advertising issue.

Proposed fix
 private string[] BuildOwnedShortcutCombos()
 {
-    var combos = new HashSet<string>(DefaultShortcuts.Keys, StringComparer.OrdinalIgnoreCase);
+    var combos = new Dictionary<string, string>(DefaultShortcuts, StringComparer.OrdinalIgnoreCase);
     if (KeyboardShortcuts is not null)
     {
         // Only advertise custom combos whose command can actually be executed; otherwise the
         // JS bridge would suppress the browser default for a combo _OnShortcut later rejects.
         foreach (var (key, command) in KeyboardShortcuts)
-            if (IsKnownCommand(command))
-                combos.Add(key);
+        {
+            if (IsKnownCommand(command))
+                combos[key] = command;
+            else
+                combos.Remove(key);
+        }
     }
-    return combos.Select(c => c.ToLowerInvariant()).ToArray();
+    return combos.Keys.Select(c => c.ToLowerInvariant()).ToArray();
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs`
around lines 90 - 100, `BuildOwnedShortcutCombos()` still seeds
`DefaultShortcuts`, which leaves built-in combos advertised as owned even when
`KeyboardShortcuts` overrides them with an unknown command. Update
`BitRichTextEditor.Shortcuts` so owned shortcuts are computed from the effective
shortcut map used by `_OnShortcut`, not from the defaults alone; when a custom
override exists for a key, only advertise it if `IsKnownCommand(command)`
returns true, otherwise omit the combo so the bridge does not suppress an
unhandled browser shortcut.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor (1)

107-116: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep non-option content out of the listbox.

The filter input was moved out, but the “No matching command” div is still inside role="listbox". Render the empty state outside the listbox or only render the listbox when options exist.

Proposed fix
-            <div class="bit-rte-slash-list" role="listbox" aria-label="`@Label`("filter-commands", "Filter commands")">
-                `@foreach` (var c in FilteredSlash())
-                {
-                    <button type="button" class="bit-rte-slash-item" role="option"
-                            `@onmousedown`:preventDefault="true" `@onclick`="() => ApplySlashAsync(c.Command)">`@Label`(c.Key, c.Label)</button>
-                }
-                `@if` (FilteredSlash().Any() is false)
-                {
-                    <div class="bit-rte-emoji-empty">`@Label`("no-command", "No matching command")</div>
-                }
-            </div>
+            `@if` (FilteredSlash().Any())
+            {
+                <div class="bit-rte-slash-list" role="listbox" aria-label="`@Label`("commands", "Commands")">
+                    `@foreach` (var c in FilteredSlash())
+                    {
+                        <button type="button" class="bit-rte-slash-item" role="option"
+                                `@onmousedown`:preventDefault="true" `@onclick`="() => ApplySlashAsync(c.Command)">`@Label`(c.Key, c.Label)</button>
+                    }
+                </div>
+            }
+            else
+            {
+                <div class="bit-rte-emoji-empty" role="status">`@Label`("no-command", "No matching command")</div>
+            }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`
around lines 107 - 116, The empty-state “No matching command” content is still
being rendered inside the element with role="listbox" in
BitRichTextEditor.razor, which leaves non-option content in the listbox; update
the slash-command UI so only option items are inside the listbox, either by
moving the empty state outside the listbox or by rendering the listbox only when
FilteredSlash().Any() is true. Use the existing BitRichTextEditor and
FilteredSlash() section to keep the listbox restricted to the button options.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs (1)

20-27: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Merge wildcard attributes into tag-specific entries.

The builder still leaves "*" attributes separate, so tag-specific entries can shadow shared attributes in the JS sanitizer path. This is the same wildcard-preservation issue previously flagged.

Proposed fix
 private object? BuildPolicyPayload()
 {
     if (SanitizationPolicy is null) return null;
+
+    var wildcardAttributes = SanitizationPolicy.AllowedAttributes
+        .Where(kv => string.Equals(kv.Key, "*", StringComparison.OrdinalIgnoreCase))
+        .SelectMany(kv => kv.Value)
+        .Select(a => a.ToLowerInvariant())
+        .Distinct()
+        .ToArray();
+
     return new
     {
         allowedTags = SanitizationPolicy.AllowedTags.Select(t => t.ToLowerInvariant()).ToArray(),
         allowedAttributes = SanitizationPolicy.AllowedAttributes
             .GroupBy(kv => kv.Key.ToLowerInvariant())
             .ToDictionary(
                 g => g.Key,
                 g => g.SelectMany(kv => kv.Value)
                       .Select(a => a.ToLowerInvariant())
+                      .Concat(g.Key == "*" ? Array.Empty<string>() : wildcardAttributes)
                       .Distinct()
                       .ToArray()),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`
around lines 20 - 27, The AllowedAttributes normalization in RichTextEditor
sanitization still keeps the "*" entry separate, so update the builder around
SanitizationPolicy.AllowedAttributes to merge wildcard attributes into every
tag-specific entry instead of leaving them isolated. Preserve the shared
attributes when building the dictionary in BitRichTextEditor.Sanitization,
ensuring each tag entry includes both its own attributes and the wildcard set
before the JS sanitizer consumes it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs`:
- Around line 10-11: The RichTextEditor `MaxLength` parameter currently accepts
negative values, so update the `BitRichTextEditor.Count`/`MaxLength` handling to
reject them before they reach the footer or bridge enforcement. Add validation
in the `MaxLength` property path (or the component’s parameter-setting logic if
that’s where other bounds are enforced) so only null or non-negative values are
allowed, and ensure invalid negatives are handled consistently with the rest of
the component’s parameter validation.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs`:
- Around line 12-21: The ToggleFind method currently discards the ClearFindAsync
call when closing the panel, which can leave stale highlight nodes and hide JS
interop failures. Update ToggleFind so the clear operation is awaited as part of
the close path, and preserve any exception handling needed around ClearFindAsync
to keep failures visible while resetting _showFind, _findTerm, _replaceTerm, and
_findCount.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs`:
- Around line 58-71: `IsAcceptableImageUrl` currently allows any `data:` URL and
`_ResolveImageUrl` embeds the raw client `contentType`, which can permit
non-image payloads. Update the `BitRichTextEditor.Media` logic to only
accept/emit `data:` URLs when `SanitizationPolicy.AllowDataImageUris` is enabled
and the MIME type is a known image type, and validate the fallback in
`_ResolveImageUrl` before constructing the inline data URL.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`:
- Around line 94-98: The inline error display is currently nested under the
ShowToolbar block in BitRichTextEditor, so it is hidden when the toolbar is
disabled. Move the _inlineError alert rendering in BitRichTextEditor.razor
outside the toolbar-only section while keeping the same bit-rte-err alert markup
and role="alert" behavior, so errors still render for toolbar-less editor
configurations.
- Around line 132-137: The source-view textarea in BitRichTextEditor still
allows edits when ReadOnly is enabled, unlike the main contenteditable surface.
Update the _inSourceView rendering in BitRichTextEditor.razor so the source
<textarea> also respects ReadOnly, likely by binding the readonly/disabled state
alongside value="`@_sourceText`" and `@oninput`="OnSourceTextChanged". Make sure the
same ReadOnly state used by the editor surface is applied consistently in the
source editing path.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs`:
- Around line 25-27: The source-view validation path in
BitRichTextEditor.SourceView currently hardcodes the inline error text, which
bypasses localization. Update the invalid HTML branch in the
BitRichTextEditor.SourceView logic to use the existing Label(...) fallback path
for the error message before calling RaiseErrorAsync, so localized editors
display the translated text instead of the English literal.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs`:
- Around line 9-11: The invalid-table validation in BitRichTextEditor.Tables
still uses a hardcoded English string instead of the localizer. Update the error
creation in the table row/column bounds check to use the existing localizer path
used elsewhere in BitRichTextEditor, so the "invalid-table" message is
translated consistently. Keep the same error key and wire the localized text
through RaiseErrorAsync and BitRichTextEditorError.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 271-275: Restore the saved editor range before running
selection-dependent actions in `updateLink`, `tableOp`, and `setBlockDirection`,
since they currently read `document.getSelection()` first and may act on the
toolbar/dialog selection instead of the editor. Use the existing `editor._range`
restoration logic in `BitRichTextEditor` before calling
`RichTextEditor.linkAtSelection`, `RichTextEditor.dispatch`, or any
direction/table commands so the editor selection is active when these commands
run.
- Around line 28-37: The default sanitizer in BitRichTextEditor currently allows
the global style attribute, which lets arbitrary inline CSS through pasted or
source HTML. Update the sanitizer allowlist in the BitRichTextEditor
configuration to remove style from the global allowedAttributes, or restrict it
to only the safe editor-generated properties/values if it must remain. Make the
same change in the other sanitizer configuration block referenced by the comment
so both paths use the same safe policy.
- Around line 359-362: The imperative insertion path in
RichTextEditor.insertText bypasses the same _maxLength enforcement used by
onBeforeInput and paste, so programmatic inserts can exceed the configured
limit. Update insertText (and any related insertion helpers in the
RichTextEditor flow) to check the current content length against _maxLength
before dispatching the insert, truncating or skipping the insertion as needed.
Reuse the existing length-counting logic already used for user input so
emoji/custom toolbar inserts are handled consistently. Also review the related
insertion path referenced by insertText to ensure all programmatic text entry
honors the same limit.
- Around line 17-37: The RichTextEditor sanitizer policy currently allows no
<font> tags, so font formatting created by fontName/fontSize is lost after
sanitization; update the generated markup in BitRichTextEditor to emit allowed
<span style="..."> wrappers instead of <font> elements. Make the change in the
editor’s font formatting handling paths (the places referenced by the comment,
including the font-related generation logic) so the output survives
DEFAULT_POLICY roundtrips without unwrapping or dropping styles.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs`:
- Around line 11-20: The full-screen state in ToggleFullScreen is only updated
after the JS call, but external exits are not reflected back into the component,
so _fullScreen can stay stale. Add a JS-to-.NET callback for fullscreenchange in
the rich text editor bridge, and use it to clear _fullScreen and refresh the
class/state when the browser exits full screen via Escape or UI controls. Update
the relevant RichTextEditor view/interop symbols
(_js.BitRichTextEditorSetFullScreen, ToggleFullScreen, and the editor fullscreen
handling) so the component stays in sync with the actual browser state.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`:
- Around line 107-116: The empty-state “No matching command” content is still
being rendered inside the element with role="listbox" in
BitRichTextEditor.razor, which leaves non-option content in the listbox; update
the slash-command UI so only option items are inside the listbox, either by
moving the empty state outside the listbox or by rendering the listbox only when
FilteredSlash().Any() is true. Use the existing BitRichTextEditor and
FilteredSlash() section to keep the listbox restricted to the button options.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`:
- Around line 20-27: The AllowedAttributes normalization in RichTextEditor
sanitization still keeps the "*" entry separate, so update the builder around
SanitizationPolicy.AllowedAttributes to merge wildcard attributes into every
tag-specific entry instead of leaving them isolated. Preserve the shared
attributes when building the dictionary in BitRichTextEditor.Sanitization,
ensuring each tag entry includes both its own attributes and the wildcard set
before the JS sanitizer consumes it.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs`:
- Around line 90-100: `BuildOwnedShortcutCombos()` still seeds
`DefaultShortcuts`, which leaves built-in combos advertised as owned even when
`KeyboardShortcuts` overrides them with an unknown command. Update
`BitRichTextEditor.Shortcuts` so owned shortcuts are computed from the effective
shortcut map used by `_OnShortcut`, not from the defaults alone; when a custom
override exists for a key, only advertise it if `IsKnownCommand(command)`
returns true, otherwise omit the combo so the bridge does not suppress an
unhandled browser shortcut.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7f4d9627-7c75-44c6-8be4-c0cc22162d26

📥 Commits

Reviewing files that changed from the base of the PR and between f990c5a and 4e95933.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts

@msynk

msynk commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs (1)

8-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Expose the built-in toolbar ids as code, not only XML docs.

Order is a public stringly-typed contract, and the downstream ordering code silently drops unknown ids. That makes typos or future renames fail as “missing buttons” with no signal. Please publish stable constants (or a typed wrapper) for the built-in ids instead of requiring consumers to copy doc strings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs`
around lines 8 - 18, The public Order contract in BitRichTextEditorToolbarConfig
is stringly typed and only documents the built-in toolbar ids in XML comments,
so consumers have no safe way to reference them. Add stable public constants or
a typed wrapper for the built-in ids on BitRichTextEditorToolbarConfig (or a
related shared type) and expose them as the source of truth for ordering, so
callers can use the same identifiers instead of copying names from the docs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs`:
- Around line 229-250: OnValue-driven rerenders in BitRichTextEditor are causing
unnecessary BitRichTextEditorUpdateOptions JS calls even when bridge-backed
settings are unchanged. Update OnParametersSetAsync and BuildSetupOptions to
cache the last setup payload (or its relevant fields) and only invoke
_js.BitRichTextEditorUpdateOptions when DebounceMs, BuildPolicyPayload,
PasteAsPlainText, MaxLength, OnImageUpload, or BuildOwnedShortcutCombos actually
differ from the previous snapshot. Keep the existing _initialized gate and use
the BitRichTextEditorSetupOptions shape to compare and skip redundant updates.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss`:
- Around line 120-127: The auxiliary editor bars are locked to a single flex
row, causing the link/media/find controls to overflow on narrow widths or high
zoom. Update the .bit-rte-bar styles (and the other matching auxiliary bar rules
referenced by the same comment) so they can wrap instead of forcing one line,
while keeping spacing/alignment intact and preserving the existing bar structure
in BitRichTextEditor.scss.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs`:
- Around line 32-41: The exit path in BitRichTextEditor.SourceView currently
always writes back and raises notifications even when the sanitized source text
matches the existing HTML. In the source-view close flow, compare the sanitized
result against the pre-existing _currentHtml before calling
BitRichTextEditorSetHtml, AssignValue, NotifyEditContextChanged, and OnChange.
If there is no effective content change, skip the save/notify path and only exit
source view state. Keep the check localized around the existing
_inSourceView/_currentHtml update logic.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs`:
- Around line 79-84: The custom toolbar button rendering in
BitRichTextEditor.Toolbar should not rely on item.AriaLabel alone for
accessibility. Update the attribute values in the button-building logic to use a
fallback chain like item.AriaLabel ?? item.Label ?? item.Id so icon-only items
still get a usable name, and keep the same fallback consistent across the title
and aria-label attributes in the toolbar item rendering path.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 546-551: The fullscreen request path in BitRichTextEditor’s
ToggleFullScreen/requestFullscreen handling is swallowing failures by resolving
the promise after catch, which makes the C# interop think fullscreen succeeded;
update the promise flow so a denied request still rejects or otherwise signals
failure to the caller, while keeping OnClientError reporting in place, and make
the change in the requestFullscreen branch tied to editor._dotNetRef and
ToggleFullScreen.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs`:
- Around line 6-19: Add fail-fast validation for blank Id and AriaLabel instead
of relying on required on BitRichTextEditorToolbarItem. Update the normalization
path in ToolbarConfig.CustomItems to reject null/empty/whitespace values for
these fields before items are used for ordering, lookup, title, or aria-label,
and make the guard explicit where custom toolbar items are prepared.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs`:
- Around line 386-390: The FormModel validation currently applies MinLength to
the raw HTML from BitRichTextEditor, so markup can satisfy the rule without
enough visible text. Update FormModel.Body validation to check the plain-text
content instead of the HTML payload by stripping tags before enforcing length,
or remove the minimum-length constraint from this demo. Use the FormModel and
Body property to locate the change.

In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs`:
- Around line 157-168: The RichTextEditor test assumes the sanitize bridge entry
already exists, which can fail on initial renders with empty values. Update the
test in BitRichTextEditorTests to read the pre-update invocation count for
BitBlazorUI.RichTextEditor.sanitizeHtml using a safe lookup instead of indexing
directly, then keep the SetParametersAndRender update-path assertion by
comparing the count before and after the Value change.

---

Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs`:
- Around line 8-18: The public Order contract in BitRichTextEditorToolbarConfig
is stringly typed and only documents the built-in toolbar ids in XML comments,
so consumers have no safe way to reference them. Add stable public constants or
a typed wrapper for the built-in ids on BitRichTextEditorToolbarConfig (or a
related shared type) and expose them as the source of truth for ordering, so
callers can use the same identifiers instead of copying names from the docs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ac4e7152-a4e6-4524-8313-77ffca0349b6

📥 Commits

Reviewing files that changed from the base of the PR and between f990c5a and 2627692.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts

@msynk

msynk commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@msynk

msynk commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@msynk

msynk commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs (1)

14-31: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Wildcard ("*") attributes are shadowed by tag-specific entries.

Since the JS sanitizer does allowedAttributes[tag] || allowedAttributes['*'], any tag with its own entry here never sees the "*" attributes. This breaks the documented "*" = "allowed on any tag" contract for tags like links, images, or table cells that also have their own entries.

🛡️ Proposed fix to merge wildcard attributes into tag-specific entries
     private object? BuildPolicyPayload()
     {
         if (SanitizationPolicy is null) return null;
+
+        var wildcardAttributes = SanitizationPolicy.AllowedAttributes.TryGetValue("*", out var attrs)
+            ? attrs.Select(a => a.ToLowerInvariant()).ToArray()
+            : Array.Empty<string>();
+
         return new
         {
             allowedTags = SanitizationPolicy.AllowedTags.Select(t => t.ToLowerInvariant()).ToArray(),
             allowedAttributes = SanitizationPolicy.AllowedAttributes
                 .GroupBy(kv => kv.Key.ToLowerInvariant())
                 .ToDictionary(
                     g => g.Key,
                     g => g.SelectMany(kv => kv.Value)
                           .Select(a => a.ToLowerInvariant())
+                          .Concat(g.Key == "*" ? Array.Empty<string>() : wildcardAttributes)
                           .Distinct()
                           .ToArray()),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`
around lines 14 - 31, The BuildPolicyPayload method in BitRichTextEditor
sanitization is emitting tag-specific allowedAttributes entries without merging
in the wildcard "*" attributes, so tags with their own rules never inherit
shared attributes. Update the allowedAttributes construction to combine the "*"
attribute list into every tag-specific entry while preserving deduplication and
lowercase normalization, and keep "*" present as the fallback entry for the JS
sanitizer contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs`:
- Around line 40-44: The ToggleEmoji method in BitRichTextEditor.Emoji currently
only flips _showEmoji and clears _emojiSearch, leaving any previous _inlineError
visible. Update ToggleEmoji so it also resets _inlineError when opening or
closing the emoji picker, matching the behavior of the other inline tool toggles
and clearing stale validation state.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs`:
- Around line 41-44: The validation path in BitRichTextEditor.Find.cs leaves a
stale result count visible when the search term is too long. Update the
find-term validation branches in the RichTextEditor find flow (including the
find-too-long checks in the relevant find methods) to reset _findCount before
raising the error so the UI does not keep showing the previous count for an
invalid term.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor`:
- Around line 104-113: The slash-menu key handler in BitRichTextEditor’s input
currently processes ArrowUp, ArrowDown, Enter, and Escape but still allows
browser defaults to run. Update the keydown handling around OnSlashKeyDownAsync
so those handled keys suppress native behavior only when pressed, using a
conditional preventDefault approach or a small JS bridge tied to the slash input
element. Keep normal typing unaffected and avoid a blanket
`@onkeydown`:preventDefault on the filter input.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 364-375: Gate the RichTextEditor color/font commands on the active
allowlist so they only run when the current policy permits the resulting markup.
Update `applyColor` and `applyFont` (and the related dispatch/normalization path
they use) to check the editor’s allowlist before applying `backColor`,
`foreColor`, `fontSize`, or `fontName`, and skip or no-op when `span`/`style`
would be stripped by `snapshot()`. Make sure the fix covers the same behavior in
the other formatting helpers referenced by the comment so displayed formatting
matches what persists in `Value`.
- Around line 223-295: Update BitRichTextEditor.validateHtml to accept HTML
comments alongside normal tags, since it currently rejects any <...> that does
not start with a letter. Add a comment-handling branch in the validateHtml scan
so sequences like <!-- ... --> are treated as valid and skipped without
affecting the tag stack, while preserving the existing validation for real tags,
voidTags, and optionalClose behavior.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor`:
- Around line 150-153: The Links demo is passing a literal string to
BitRichTextEditor instead of binding the current HTML value. Update the
BitRichTextEditor usage in BitRichTextEditorDemo.razor to bind the Value from
linkHtml the same way the example in example11RazorCode does, while keeping
ValueChanged wired to HandleLinkHtmlChanged and the existing
toolbar/error/placeholder settings intact.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`:
- Around line 14-31: The BuildPolicyPayload method in BitRichTextEditor
sanitization is emitting tag-specific allowedAttributes entries without merging
in the wildcard "*" attributes, so tags with their own rules never inherit
shared attributes. Update the allowedAttributes construction to combine the "*"
attribute list into every tag-specific entry while preserving deduplication and
lowercase normalization, and keep "*" present as the fallback entry for the JS
sanitizer contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e51cf7d8-7b72-4de0-9220-bbc522f6ccd3

📥 Commits

Reviewing files that changed from the base of the PR and between 9c34dfb and 2e41c92.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts

@msynk

msynk commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (4)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs (1)

45-48: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Drop style from the secure default wildcard attributes.

This is still unresolved: allowing arbitrary inline CSS in untrusted editor HTML enables UI spoofing/overlay content. Remove style here and mirror the same change in BitRichTextEditor.ts’s DEFAULT_POLICY.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs`
around lines 45 - 48, Remove the insecure default inline style allowance from
the rich text editor sanitization policy by updating
BitRichTextEditorSanitizationPolicy’s wildcard AllowedAttributes entry to
exclude style, and make the same matching change in BitRichTextEditor.ts within
DEFAULT_POLICY so both policies stay aligned; keep class and dir allowed if
still needed, and ensure any other policy references to wildcard attributes no
longer permit style.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts (2)

1715-1718: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Normalize custom URI schemes before comparison.

The C# policy uses case-insensitive sets, but the JS bridge uses includes, so a custom policy containing HTTPS rejects valid https: URLs after serialization. Compare lowercased scheme values.

Proposed fix
             if (policy && Array.isArray(policy.allowedUriSchemes)) {
-                return policy.allowedUriSchemes.includes(scheme);
+                return policy.allowedUriSchemes
+                    .some((s: string) => (s || '').toLowerCase() === scheme);
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`
around lines 1715 - 1718, Normalize the URI scheme before checking it in the
RichTextEditor URI validation path, since the C# policy is case-insensitive but
the JS bridge currently uses a direct includes check. Update the scheme
comparison in the RichTextEditor logic so the value being tested and the entries
in policy.allowedUriSchemes are compared in lowercase (including the default
http/https/mailto/tel fallback), and keep the fix localized around the scheme
validation branch in BitRichTextEditor.

323-370: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Gate link/image commands on required attributes too.

These paths check the tag and URI, but a custom policy can allow a/img while omitting href/src. The live editor then shows a link/image that snapshot() strips later. Require the attribute before dispatching.

Proposed fix
-            if (!RichTextEditor.isTagAllowed(editor, 'a')) {
+            if (!RichTextEditor.isTagAllowed(editor, 'a') || !RichTextEditor.isAttrAllowed(editor, 'a', 'href')) {
                 RichTextEditor.reportClientError(editor, 'invalid-url', 'Links are not allowed by the current policy.');
                 return;
             }
@@
-            if (!RichTextEditor.isTagAllowed(editor, 'a')) {
+            if (!RichTextEditor.isTagAllowed(editor, 'a') || !RichTextEditor.isAttrAllowed(editor, 'a', 'href')) {
                 RichTextEditor.reportClientError(editor, 'invalid-url', 'Links are not allowed by the current policy.');
                 return;
             }
@@
-            if (!RichTextEditor.isTagAllowed(editor, 'img')) {
+            if (!RichTextEditor.isTagAllowed(editor, 'img') || !RichTextEditor.isAttrAllowed(editor, 'img', 'src')) {
                 RichTextEditor.reportClientError(editor, 'invalid-url', 'Images are not allowed by the current policy.');
                 return;
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`
around lines 323 - 370, The link/image command paths in RichTextEditor still
allow dispatching when the tag is permitted but the required attribute is not,
which can create content later removed by snapshot(). Update createLink,
updateLink, and insertImageUrl to also verify that the active policy allows the
needed attribute (href for links, src for images) before calling dispatch or
setAttribute, using the existing RichTextEditor.isTagAllowed and related
policy-check helpers in this class.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs (1)

388-393: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

formSubmitted is never reset after a later edit invalidates the form.

HandleValidSubmit only sets formSubmitted = true; nothing clears it when the bound content changes again, so the "submitted successfully" state can persist even after subsequent edits make the content invalid.

♻️ Proposed fix
     private readonly FormModel formModel = new();
     private bool formSubmitted;
     private void HandleValidSubmit()
     {
         formSubmitted = true;
     }
+    private void HandleBodyChanged(string? value)
+    {
+        formModel.Body = value;
+        formSubmitted = false;
+    }

And bind the editor via @bind-Value="formModel.Body" plus reset on change, or simply clear formSubmitted in an OnChange/ValueChanged handler wired to the EditForm example.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs`
around lines 388 - 393, The success flag in `BitRichTextEditorDemo` is only set
in `HandleValidSubmit` and never cleared when the editor content changes, so the
submitted state can linger after edits. Update the `EditForm`/rich text editor
wiring around `formModel.Body` so changes reset `formSubmitted` (for example via
`OnChange` or `ValueChanged`), or switch to `@bind-Value="formModel.Body"` and
clear the flag whenever the bound value changes. Keep the fix centered on
`HandleValidSubmit`, `formSubmitted`, and the `formModel` binding.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs`:
- Around line 66-77: Update IsAcceptableLinkUrl in BitRichTextEditor.Links so it
rejects backslash-based protocol-relative inputs before the existing
site-relative StartsWith('/') check. Treat values like /\evil.com, \/evil.com,
and \\evil.com as unsafe by either blocking any leading backslash patterns or
normalizing the URL and revalidating, while keeping the existing http/https,
mailto, tel, and fragment handling intact.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs`:
- Around line 113-127: FocusSlashIfPendingAsync currently only handles
JSDisconnectedException, so JS interop failures from _slashInputRef.FocusAsync
or _js.BitRichTextEditorBindSlashKeys(_slashInputRef) can escape the render
lifecycle. Update this method in BitRichTextEditor.Slash.cs to also catch
JSException, matching the defensive pattern already used by ToggleFullScreen in
BitRichTextEditor.View.cs, and keep the failure silently ignored when the
interop call cannot complete.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs`:
- Around line 110-119: Handle malformed percent-encoding in GetQueryValue by
catching decode failures from Uri.UnescapeDataString and returning null instead
of letting the exception escape. Update the query-value parsing in
BitRichTextEditor.Structured.cs so invalid encoded values are treated as
missing, allowing ApplyMediaAsync to surface the existing validation error. Use
the GetQueryValue helper as the fix point and keep the current key-matching
logic unchanged.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor`:
- Around line 214-222: The “Media & rules” demo in BitRichTextEditorDemo
currently describes YouTube/Vimeo iframe embeds even though the default
sanitization policy does not allow iframes. Update the example around the
BitRichTextEditor media sample to either use an iframe-capable policy explicitly
for this demo or change the copy to mention only direct audio/video URLs, so the
text matches the behavior of mediaHtml and the Media toolbar example.
- Line 10: The RichTextEditor description is overstating that all logic lives in
C# and should be updated to match the actual split of responsibilities. In
BitRichTextEditorDemo.razor, revise the Description text so it says the
component state/API lives in C# while browser editing operations are handled in
the JS/TypeScript bridge, and make sure the copy no longer claims the bridge is
only for minor browser concerns.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 1715-1718: Normalize the URI scheme before checking it in the
RichTextEditor URI validation path, since the C# policy is case-insensitive but
the JS bridge currently uses a direct includes check. Update the scheme
comparison in the RichTextEditor logic so the value being tested and the entries
in policy.allowedUriSchemes are compared in lowercase (including the default
http/https/mailto/tel fallback), and keep the fix localized around the scheme
validation branch in BitRichTextEditor.
- Around line 323-370: The link/image command paths in RichTextEditor still
allow dispatching when the tag is permitted but the required attribute is not,
which can create content later removed by snapshot(). Update createLink,
updateLink, and insertImageUrl to also verify that the active policy allows the
needed attribute (href for links, src for images) before calling dispatch or
setAttribute, using the existing RichTextEditor.isTagAllowed and related
policy-check helpers in this class.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs`:
- Around line 45-48: Remove the insecure default inline style allowance from the
rich text editor sanitization policy by updating
BitRichTextEditorSanitizationPolicy’s wildcard AllowedAttributes entry to
exclude style, and make the same matching change in BitRichTextEditor.ts within
DEFAULT_POLICY so both policies stay aligned; keep class and dir allowed if
still needed, and ensure any other policy references to wildcard attributes no
longer permit style.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs`:
- Around line 388-393: The success flag in `BitRichTextEditorDemo` is only set
in `HandleValidSubmit` and never cleared when the editor content changes, so the
submitted state can linger after edits. Update the `EditForm`/rich text editor
wiring around `formModel.Body` so changes reset `formSubmitted` (for example via
`OnChange` or `ValueChanged`), or switch to `@bind-Value="formModel.Body"` and
clear the flag whenever the bound value changes. Keep the fix centered on
`HandleValidSubmit`, `formSubmitted`, and the `formModel` binding.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cbe41513-93ab-4733-9765-a0fc8a8e91fd

📥 Commits

Reviewing files that changed from the base of the PR and between 9c34dfb and 58a55ca.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts

@msynk

msynk commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@msynk

msynk commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor (1)

335-347: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

EditForm description still doesn't match the sample code.

Text says
"Bind a model property with @@bind-Value"
but the example below uses explicit Value/ValueChanged (line 343), not @bind-Value. This was flagged before and marked addressed, but the mismatch is still present.

✏️ Proposed fix
-                    The editor participates in <b>EditForm</b> like any input. Bind a model property with <b>@@bind-Value</b> and
-                    the component picks up the EditContext, so DataAnnotationsValidator and ValidationMessage work as expected.
+                    The editor participates in <b>EditForm</b> like any input. Bind a model property with
+                    <b>Value</b>/<b>ValueChanged</b> (or <b>@@bind-Value</b>) and the component picks up the EditContext, so
+                    DataAnnotationsValidator and ValidationMessage work as expected.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor`
around lines 335 - 347, The EditForm demo text still mismatches the sample: the
description in BitRichTextEditorDemo.razor says to use `@bind-Value`, but the
BitRichTextEditor example below uses explicit Value and ValueChanged wiring.
Update the explanatory text in the EditForm validation example to match the
actual binding pattern shown by the BitRichTextEditor and formModel usage, so
the description and sample code are consistent.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs (1)

14-31: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Wildcard ("*") attributes are still not merged into tag-specific entries.

BuildPolicyPayload() groups AllowedAttributes per-tag but never folds "*" entries into other tags. Since the JS sanitizer uses allowedAttributes[tag] || allowedAttributes['*'] (fallback, not merge), any tag with its own entry (e.g. a, img, table) will completely lose wildcard-only attributes like class/style/dir, breaking the documented "* = allowed on any tag" contract.

♻️ Proposed fix
     private object? BuildPolicyPayload()
     {
         if (SanitizationPolicy is null) return null;
+
+        var wildcardAttributes = SanitizationPolicy.AllowedAttributes.TryGetValue("*", out var attrs)
+            ? attrs.Select(a => a.ToLowerInvariant()).ToArray()
+            : Array.Empty<string>();
+
         return new
         {
             allowedTags = SanitizationPolicy.AllowedTags.Select(t => t.ToLowerInvariant()).ToArray(),
             allowedAttributes = SanitizationPolicy.AllowedAttributes
                 .GroupBy(kv => kv.Key.ToLowerInvariant())
                 .ToDictionary(
                     g => g.Key,
                     g => g.SelectMany(kv => kv.Value)
                           .Select(a => a.ToLowerInvariant())
+                          .Concat(g.Key == "*" ? Array.Empty<string>() : wildcardAttributes)
                           .Distinct()
                           .ToArray()),
             allowedUriSchemes = SanitizationPolicy.AllowedUriSchemes.Select(s => s.ToLowerInvariant()).ToArray(),
             allowDataImageUris = SanitizationPolicy.AllowDataImageUris
         };
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`
around lines 14 - 31, BuildPolicyPayload currently serializes AllowedAttributes
by tag only, so wildcard "*" attributes are not carried into tag-specific
entries and the JS sanitizer’s fallback behavior will drop shared attrs like
class/style/dir. Update BitRichTextEditor.Sanitization.cs in BuildPolicyPayload
to merge any "*" attributes into each concrete tag’s attribute list before
building the payload, while still preserving per-tag attributes and
de-duplicating/lowercasing values. Keep the payload shape compatible with the
sanitizer by ensuring allowedAttributes for tags such as a, img, and table
includes both their own attrs and the wildcard ones.
🧹 Nitpick comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs (1)

6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a concrete type for Policy.

object? bypasses compile-time checks for callers constructing this options object. If it's always a BitRichTextEditorSanitizationPolicy (or a serializable projection of it), typing it explicitly would improve safety without behavior change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs`
at line 6, The Policy property is too loosely typed as object?, which removes
compile-time safety for callers creating BitRichTextEditorSetupOptions. Update
BitRichTextEditorSetupOptions.Policy to use the concrete
BitRichTextEditorSanitizationPolicy type (or a clearly defined serializable DTO
if that is the intended payload), and adjust any related serialization or
initialization code so the API remains behaviorally unchanged while becoming
strongly typed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 1318-1322: The onDrop path in BitRichTextEditor is computing
imageFiles correctly but then calling handleImageFiles with all dropped files,
which causes non-image files to be processed and emit invalid-file errors.
Update the drop handler to pass the filtered imageFiles array to
handleImageFiles, matching the onPaste flow and keeping the gate/processing
logic consistent in RichTextEditor.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`:
- Around line 14-31: BuildPolicyPayload currently serializes AllowedAttributes
by tag only, so wildcard "*" attributes are not carried into tag-specific
entries and the JS sanitizer’s fallback behavior will drop shared attrs like
class/style/dir. Update BitRichTextEditor.Sanitization.cs in BuildPolicyPayload
to merge any "*" attributes into each concrete tag’s attribute list before
building the payload, while still preserving per-tag attributes and
de-duplicating/lowercasing values. Keep the payload shape compatible with the
sanitizer by ensuring allowedAttributes for tags such as a, img, and table
includes both their own attrs and the wildcard ones.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor`:
- Around line 335-347: The EditForm demo text still mismatches the sample: the
description in BitRichTextEditorDemo.razor says to use `@bind-Value`, but the
BitRichTextEditor example below uses explicit Value and ValueChanged wiring.
Update the explanatory text in the EditForm validation example to match the
actual binding pattern shown by the BitRichTextEditor and formModel usage, so
the description and sample code are consistent.

---

Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs`:
- Line 6: The Policy property is too loosely typed as object?, which removes
compile-time safety for callers creating BitRichTextEditorSetupOptions. Update
BitRichTextEditorSetupOptions.Policy to use the concrete
BitRichTextEditorSanitizationPolicy type (or a clearly defined serializable DTO
if that is the intended payload), and adjust any related serialization or
initialization code so the API remains behaviorally unchanged while becoming
strongly typed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 901d60e4-6746-41fd-bf37-5a1170df773f

📥 Commits

Reviewing files that changed from the base of the PR and between 9c34dfb and 4288250.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts Outdated
@msynk

msynk commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (3)
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs (1)

180-190: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Trace.TraceError won't reach the host app's actual logging pipeline.

This survives Release builds (fixing the Debug.WriteLine issue), but System.Diagnostics.Trace output only reaches registered TraceListeners — ASP.NET Core does not wire Trace calls into the app's configured ILogger providers (Console/Application Insights/Serilog/etc.) by default. Most hosts consuming this library will still see no record of upload failures in their actual logs/telemetry, which was the original intent of the past review comment. Prefer an injected ILogger<BitRichTextEditor> as originally suggested.

♻️ Suggested fix using an injected logger
-using System.Diagnostics;
-
 namespace Bit.BlazorUI;

 // Image insertion (URL, drag-drop, paste, upload callback), color, and font.
 public partial class BitRichTextEditor
 {
+    [Inject] private ILogger<BitRichTextEditor>? _logger { get; set; }
+
@@
         catch (Exception ex)
         {
-            // Keep infrastructure details out of the user-facing error; log them instead. Use
-            // Trace (not Debug) so the failure is still recorded in Release builds, matching the
-            // other always-on logging paths in this component (e.g. _OnCommandError).
-            Trace.TraceError($"BitRichTextEditor image upload failed for \"{fileName}\": {ex}");
+            // Keep infrastructure details out of the user-facing error; log them via the app's
+            // configured logging pipeline instead of an unconfigured Trace listener.
+            _logger?.LogError(ex, "BitRichTextEditor image upload failed for {FileName}", fileName);
             await RaiseErrorAsync(new BitRichTextEditorError("upload-failed",
                 string.Format(Label("image-upload-failed", "Upload of \"{0}\" failed. Please try again."), fileName)));
             return null;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs`
around lines 180 - 190, The upload failure handling in BitRichTextEditor.Media
currently uses Trace.TraceError, which won’t flow into the host app’s configured
logging pipeline. Update the error path in the image upload catch block to use
an injected ILogger<BitRichTextEditor> instead, and log the exception there with
the same context (including fileName) so failures are captured by standard
ASP.NET Core logging/telemetry in Release builds.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs (1)

20-26: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Find highlights still not cleared before source-view snapshot.

Entering source view still calls GetHtmlAsync() directly without first clearing active find/highlight state. If a search is active, temporary highlight nodes injected into the DOM by the find feature get captured into _sourceText and can be persisted back as real content on exit.

This was flagged previously and does not appear to have been addressed in this revision.

♻️ Suggested fix
         if (_inSourceView is false)
         {
+            if (_showFind)
+            {
+                await ClearFindAsync();
+                _showFind = false;
+                _findTerm = "";
+                _replaceTerm = "";
+                _findCount = "";
+            }
+
             _sourceText = await GetHtmlAsync();
             _inSourceView = true;
             StateHasChanged();
             return;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs`
around lines 20 - 26, Entering source view in BitRichTextEditor.SourceView still
snapshots the editor DOM before clearing active find/highlight state. Update the
_inSourceView branch so it clears any active search/highlight markers before
calling GetHtmlAsync(), then store the cleaned HTML in _sourceText and proceed
with the existing state change flow. Use the existing source-view toggle path
and the find/highlight handling in BitRichTextEditor to locate the right
pre-snapshot cleanup point.
src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs (1)

18-31: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Wildcard attribute merging still missing — issue not addressed.

The JS bridge does allowedAttributes[tag] || allowedAttributes['*'], so any tag with its own entry silently loses the "*" attributes. This was flagged previously but the payload builder is unchanged and still doesn't merge wildcard attributes into tag-specific entries.

♻️ Suggested fix
     private object? BuildPolicyPayload()
     {
         if (SanitizationPolicy is null) return null;
+
+        var wildcardAttributes = SanitizationPolicy.AllowedAttributes.TryGetValue("*", out var attrs)
+            ? attrs.Select(a => a.ToLowerInvariant()).ToArray()
+            : Array.Empty<string>();
+
         return new
         {
             allowedTags = SanitizationPolicy.AllowedTags.Select(t => t.ToLowerInvariant()).ToArray(),
             allowedAttributes = SanitizationPolicy.AllowedAttributes
                 .GroupBy(kv => kv.Key.ToLowerInvariant())
                 .ToDictionary(
                     g => g.Key,
                     g => g.SelectMany(kv => kv.Value)
                           .Select(a => a.ToLowerInvariant())
+                          .Concat(g.Key == "*" ? Array.Empty<string>() : wildcardAttributes)
                           .Distinct()
                           .ToArray()),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`
around lines 18 - 31, The sanitization payload builder in
BitRichTextEditor.Sanitization still drops wildcard attributes because
tag-specific entries overwrite the "*" entry used by the JS bridge. Update the
allowedAttributes construction to merge SanitizationPolicy.AllowedAttributes for
each tag with the wildcard ("*") attributes instead of keeping them separate,
and ensure the final dictionary produced by the sanitization method includes
both sets for every tag-specific key.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs`:
- Around line 27-40: _OnSlashTrigger in BitRichTextEditor.Slash currently opens
the slash menu when only ReadOnly is checked, which allows a dead menu in
source-view mode. Update the guard to use ControlsDisabled (matching
ApplySlashAsync) so the slash UI is never shown when controls are disabled, and
keep the existing reset/focus logic only inside the enabled path.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts`:
- Around line 28-37: The default rich text policy is missing support for
editor-generated color/font formatting, so applyColor() and applyFont() fail
under the demo configuration. Update BitRichTextEditor’s
DEFAULT_POLICY.allowedAttributes to either safely allow the span/style
combination with proper sanitization for editor-created styles, or hide/gate the
color and font toolbar groups when that policy is not enabled. Make the change
in the policy definition and the toolbar logic that enables these commands so
the default setup does not trigger format-not-allowed.
- Around line 1700-1704: The relative-URL check in BitRichTextEditor should also
reject the "/\\" network-path form, not just "//" and "\\". Update the URL
validation logic around the scheme detection branch so the candidate is treated
as unsafe whenever it starts with "/\\" as well, using the same rejection path
as the existing protocol-relative and backslash cases.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs`:
- Around line 180-190: The upload failure handling in BitRichTextEditor.Media
currently uses Trace.TraceError, which won’t flow into the host app’s configured
logging pipeline. Update the error path in the image upload catch block to use
an injected ILogger<BitRichTextEditor> instead, and log the exception there with
the same context (including fileName) so failures are captured by standard
ASP.NET Core logging/telemetry in Release builds.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs`:
- Around line 18-31: The sanitization payload builder in
BitRichTextEditor.Sanitization still drops wildcard attributes because
tag-specific entries overwrite the "*" entry used by the JS bridge. Update the
allowedAttributes construction to merge SanitizationPolicy.AllowedAttributes for
each tag with the wildcard ("*") attributes instead of keeping them separate,
and ensure the final dictionary produced by the sanitization method includes
both sets for every tag-specific key.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs`:
- Around line 20-26: Entering source view in BitRichTextEditor.SourceView still
snapshots the editor DOM before clearing active find/highlight state. Update the
_inSourceView branch so it clears any active search/highlight markers before
calling GetHtmlAsync(), then store the cleaned HTML in _sourceText and proceed
with the existing state change flow. Use the existing source-view toggle path
and the find/highlight handling in BitRichTextEditor to locate the right
pre-snapshot cleanup point.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e051b58d-72f9-4480-8109-a0f6c07c38f4

📥 Commits

Reviewing files that changed from the base of the PR and between 9c34dfb and b2b0469.

📒 Files selected for processing (103)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Count.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Emoji.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Find.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Forms.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Links.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Media.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Sanitization.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Shortcuts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Slash.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.SourceView.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Structured.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Tables.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.Toolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.View.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorContentFacts.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorError.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorImageUpload.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSanitizationPolicy.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSelectionState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorSetupOptions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbar.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarConfig.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorToolbarItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/IBitRichTextEditorLocalizer.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill-2.0.3.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/RichTextEditor/BitRichTextEditorDemo.razor.scss
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/RichTextEditor/BitRichTextEditorTests.cs
💤 Files with no reviewable changes (68)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/bold.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/header.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/color.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/size.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.bubble-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/container.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/createRegistryWithFormats.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/video.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/snow.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/tooltip.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/blockquote.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/strike.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/bubble.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/formula.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/break.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/text.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/tableEmbed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/indent.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/selection.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icons.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/emitter.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/syntax.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/script.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/underline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/direction.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/themes/base.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/link.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/background.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/toolbar.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/image.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/italic.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/align.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/quill.snow-2.0.3.css
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/icon-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uploader.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/AttributeMap.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditorTheme.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/code.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/EventEmitter3/EventEmitter3.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/editor.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/logger.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/ui/color-picker.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/uiNode.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/parchment/parchment.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/composition.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/input.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/keyboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/font.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Op.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/QuillModule.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/OpIterator.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/block.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/module.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/utils/scrollRectIntoView.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/delta/Delta.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/embed.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/list.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/quill.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/inline.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/scroll.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/formats/table.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/history.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/modules/clipboard.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/theme.d.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/@types/blots/cursor.d.ts

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/RichTextEditor/BitRichTextEditor.ts Outdated
@msynk

msynk commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@msynk

msynk commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

@msynk I'll run a full re-review of the PR now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@msynk msynk merged commit a21ef89 into bitfoundation:develop Jul 3, 2026
3 checks passed
@msynk msynk deleted the 12505-blazorui-new-richtexteditor branch July 3, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The new Blazor native RichTextEditor component

1 participant