diff --git a/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.cs b/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.cs
index 58aadcc..073c90d 100644
--- a/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.cs
+++ b/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.cs
@@ -5,6 +5,8 @@ namespace Tizzani.MudBlazor.HtmlEditor;
public sealed partial class MudHtmlEditor : IAsyncDisposable
{
+ private readonly MudHtmlEditorOptions _options = new();
+
private DotNetObjectReference? _dotNetRef;
private IJSObjectReference? _quill;
private ElementReference _toolbar;
@@ -23,7 +25,7 @@ public sealed partial class MudHtmlEditor : IAsyncDisposable
public bool Outlined { get; set; } = true;
///
- /// The placeholder text to display when the editor has not content.
+ /// The placeholder text to display when the editor has no content.
///
[Parameter]
public string Placeholder { get; set; } = "Tell your story...";
@@ -52,6 +54,18 @@ public sealed partial class MudHtmlEditor : IAsyncDisposable
[Parameter]
public EventCallback TextChanged { get; set; }
+ ///
+ /// When true, ol elements containing li elements with data-list="bullet" will be replaced with ul elements.
+ /// Default value is true. Set to false to revert to previous behavior.
+ ///
+ [Obsolete("This parameter was added to preserve backwards compatibility, but will be removed in a future version.")]
+ [Parameter]
+ public bool ReplaceOrderedWithUnorderedListTag
+ {
+ get => _options.SanitizeHtml;
+ set => _options.SanitizeHtml = value;
+ }
+
///
/// Whether or not the user can resize the editor. Default value is .
///
@@ -114,7 +128,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
_dotNetRef = DotNetObjectReference.Create(this);
await using var module = await JS.InvokeAsync("import", "./_content/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.js");
- _quill = await module.InvokeAsync("createQuillInterop", _dotNetRef, _editor, _toolbar, Placeholder);
+ _quill = await module.InvokeAsync("createQuillInterop", _dotNetRef, _editor, _toolbar, Placeholder, _options);
await SetHtml(Html);
@@ -152,4 +166,9 @@ async ValueTask IAsyncDisposable.DisposeAsync()
_dotNetRef?.Dispose();
_dotNetRef = null;
}
+}
+
+public sealed class MudHtmlEditorOptions
+{
+ public bool SanitizeHtml { get; set; } = true;
}
\ No newline at end of file
diff --git a/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.js b/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.js
index 974d5b6..34bb154 100644
--- a/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.js
+++ b/src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.js
@@ -16,7 +16,7 @@ try {
Quill.register('modules/blotFormatter', QuillBlotFormatter.default);
} catch { }
-export function createQuillInterop(dotNetRef, editorRef, toolbarRef, placeholder) {
+export function createQuillInterop(dotNetRef, editorRef, toolbarRef, placeholder, options) {
var quill = new Quill(editorRef, {
modules: {
toolbar: {
@@ -27,22 +27,19 @@ export function createQuillInterop(dotNetRef, editorRef, toolbarRef, placeholder
placeholder: placeholder,
theme: 'snow'
});
- return new MudQuillInterop(dotNetRef, quill, editorRef, toolbarRef);
+ return new MudQuillInterop(dotNetRef, quill, editorRef, toolbarRef, options);
}
export class MudQuillInterop {
- /**
- * @param {Quill} quill
- * @param {Element} editorRef
- * @param {Element} toolbarRef
- */
- constructor(dotNetRef, quill, editorRef, toolbarRef) {
+
+ constructor(dotNetRef, quill, editorRef, toolbarRef, options) {
quill.getModule('toolbar').addHandler('hr', this.insertDividerHandler);
quill.on('text-change', this.textChangedHandler);
this.dotNetRef = dotNetRef;
this.quill = quill;
this.editorRef = editorRef;
this.toolbarRef = toolbarRef;
+ this.options = options;
}
getText = () => {
@@ -50,12 +47,69 @@ export class MudQuillInterop {
};
getHtml = () => {
- return this.quill.root.innerHTML;
+ const html = this.quill.root.innerHTML;
+ return this.options.sanitizeHtml ? this.getSanitizedHtml(html) : html;
};
+
+ getSanitizedHtml = (html) => {
- setHtml = (html) => {
- this.quill.root.innerHTML = html;
- }
+ // Parse the HTML into a DOM
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(html, 'text/html');
+
+ // Find all elements
+ doc.querySelectorAll('ol').forEach(ol => {
+
+ const hasBullets = Array.from(ol.querySelectorAll('li')).some(
+ li => li.getAttribute('data-list') === 'bullet'
+ );
+
+ if (hasBullets) {
+ // Create a new element
+ const ul = doc.createElement('ul');
+
+ // Move children from to
+ while (ol.firstChild) {
+ ul.appendChild(ol.firstChild);
+ }
+
+ // Replace with
+ ol.replaceWith(ul);
+ }
+ });
+
+ return doc.body.innerHTML;
+ };
+
+ getQuillHtml = (html) => {
+
+ // Parse the HTML into a DOM
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(html, 'text/html');
+
+ // Find all elements
+ doc.querySelectorAll('ul').forEach(ul => {
+
+ const hasBullets = Array.from(ul.querySelectorAll('li')).some(
+ li => li.getAttribute('data-list') === 'bullet'
+ );
+
+ if (hasBullets) {
+ // Create a new element
+ const ol = doc.createElement('ol');
+
+ // Move children from to
+ while (ul.firstChild) {
+ ol.appendChild(ul.firstChild);
+ }
+
+ // Replace with
+ ul.replaceWith(ol);
+ }
+ });
+
+ return doc.body.innerHTML;
+ };
insertDividerHandler = () => {
const range = this.quill.getSelection();
@@ -65,14 +119,12 @@ export class MudQuillInterop {
}
};
- /**
- *
- * @param {Delta} delta
- * @param {Delta} oldDelta
- * @param {any} source
- */
+ setHtml = (html) => {
+ this.quill.root.innerHTML = this.options.sanitizeHtml ? this.getQuillHtml(html) : html;
+ }
+
textChangedHandler = (delta, oldDelta, source) => {
this.dotNetRef.invokeMethodAsync('HandleHtmlContentChanged', this.getHtml());
this.dotNetRef.invokeMethodAsync('HandleTextContentChanged', this.getText());
};
-}
\ No newline at end of file
+}
diff --git a/src/Tizzani.MudBlazor.HtmlEditor/Tizzani.MudBlazor.HtmlEditor.csproj b/src/Tizzani.MudBlazor.HtmlEditor/Tizzani.MudBlazor.HtmlEditor.csproj
index f462726..ea380c6 100644
--- a/src/Tizzani.MudBlazor.HtmlEditor/Tizzani.MudBlazor.HtmlEditor.csproj
+++ b/src/Tizzani.MudBlazor.HtmlEditor/Tizzani.MudBlazor.HtmlEditor.csproj
@@ -9,7 +9,7 @@
https://github.com/erinnmclaughlin/MudBlazor.HtmlEditor
LICENSE
README.md
- 2.3.0
+ 2.3.1
A customizable HTML editor component for MudBlazor, powered by QuillJS.
2024 Erin McLaughlin
https://github.com/erinnmclaughlin/MudBlazor.HtmlEditor