diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor
new file mode 100644
index 00000000..2a06a5a8
--- /dev/null
+++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor
@@ -0,0 +1,84 @@
+@namespace Oqtane.Modules.Controls
+@inherits ModuleBase
+@inject IJSRuntime JSRuntime
+
+
+ @ToolbarContent
+
+
+
+
+@code {
+ [Parameter]
+ public RenderFragment ToolbarContent { get; set; }
+
+ [Parameter]
+ public bool ReadOnly { get; set; }
+ = false;
+
+ [Parameter]
+ public string Placeholder { get; set; }
+ = "Compose an epic...";
+
+ [Parameter]
+ public string Theme { get; set; }
+ = "snow";
+
+ [Parameter]
+ public string DebugLevel { get; set; }
+ = "info";
+
+ private ElementReference EditorElement;
+ private ElementReference ToolBar;
+
+ protected override async Task
+ OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ await RichTextEditorInterop.CreateEditor(
+ JSRuntime,
+ EditorElement,
+ ToolBar,
+ ReadOnly,
+ Placeholder,
+ Theme,
+ DebugLevel);
+ }
+ }
+
+ public async Task GetText()
+ {
+ return await RichTextEditorInterop.GetText(
+ JSRuntime,
+ EditorElement);
+ }
+
+ public async Task GetHTML()
+ {
+ return await RichTextEditorInterop.GetHTML(
+ JSRuntime,
+ EditorElement);
+ }
+
+ public async Task GetContent()
+ {
+ return await RichTextEditorInterop.GetContent(
+ JSRuntime,
+ EditorElement);
+ }
+
+ public async Task LoadContent(string Content)
+ {
+ await RichTextEditorInterop.LoadEditorContent(
+ JSRuntime,
+ EditorElement, Content);
+ }
+
+ public async Task EnableEditor(bool mode)
+ {
+ await RichTextEditorInterop.EnableEditor(
+ JSRuntime,
+ EditorElement, mode);
+ }
+}
\ No newline at end of file
diff --git a/Oqtane.Client/Modules/HtmlText/Edit.razor b/Oqtane.Client/Modules/HtmlText/Edit.razor
index f9d891d4..4618aa09 100644
--- a/Oqtane.Client/Modules/HtmlText/Edit.razor
+++ b/Oqtane.Client/Modules/HtmlText/Edit.razor
@@ -1,5 +1,6 @@
@using Oqtane.Modules.HtmlText.Services
@using Oqtane.Modules.HtmlText.Models
+@using Oqtane.Modules.Controls
@namespace Oqtane.Modules.HtmlText
@inherits ModuleBase
@inject NavigationManager NavigationManager
@@ -12,10 +13,53 @@
-
+ @if (!RichTextEditorMode)
+ {
+
+ }
+ else
+ {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
|
+@if (!RichTextEditorMode)
+{
+
+}
+else
+{
+
+}
Cancel
@@ -26,36 +70,70 @@
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Edit; } }
public override string Title { get { return "Edit Html/Text"; } }
+ RichTextEditor RichTextEditorHtml;
+ bool RichTextEditorMode = true;
string content;
string createdby;
DateTime createdon;
string modifiedby;
DateTime modifiedon;
- protected override async Task OnInitializedAsync()
+ protected override async Task
+ OnAfterRenderAsync(bool firstRender)
{
- try
+ if (firstRender)
{
- HtmlTextService htmltextservice = new HtmlTextService(http, sitestate, NavigationManager);
- HtmlTextInfo htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
- if (htmltext != null)
+ try
{
- content = htmltext.Content;
- createdby = htmltext.CreatedBy;
- createdon = htmltext.CreatedOn;
- modifiedby = htmltext.ModifiedBy;
- modifiedon = htmltext.ModifiedOn;
+ await LoadText();
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "An Error Occurred Loading Html/Text Content. " + ex.Message);
+ AddModuleMessage(ex.Message, MessageType.Error);
}
}
- catch (Exception ex)
+ }
+
+ private async Task LoadText()
+ {
+ HtmlTextService htmltextservice = new HtmlTextService(http, sitestate, NavigationManager);
+ HtmlTextInfo htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
+ if (htmltext != null)
{
- await logger.LogError(ex, "An Error Occurred Loading Html/Text Content. " + ex.Message);
- AddModuleMessage(ex.Message, MessageType.Error);
+ content = htmltext.Content;
+ createdby = htmltext.CreatedBy;
+ createdon = htmltext.CreatedOn;
+ modifiedby = htmltext.ModifiedBy;
+ modifiedon = htmltext.ModifiedOn;
+
+ if (RichTextEditorMode)
+ {
+ await RichTextEditorHtml.LoadContent(content);
+ StateHasChanged();
+ }
}
}
+ private async Task RichTextEditor()
+ {
+ RichTextEditorMode = true;
+ await LoadText();
+ }
+
+ private async Task RawHTMLEditor()
+ {
+ RichTextEditorMode = false;
+ await LoadText();
+ }
+
private async Task SaveContent()
{
+ if (RichTextEditorMode)
+ {
+ content = await this.RichTextEditorHtml.GetHTML();
+ }
+
try
{
HtmlTextService htmltextservice = new HtmlTextService(http, sitestate, NavigationManager);
diff --git a/Oqtane.Client/Shared/Interop.cs b/Oqtane.Client/Shared/Interop.cs
index d9cf1780..f5bc53cc 100644
--- a/Oqtane.Client/Shared/Interop.cs
+++ b/Oqtane.Client/Shared/Interop.cs
@@ -1,4 +1,5 @@
-using Microsoft.JSInterop;
+using Microsoft.AspNetCore.Components;
+using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;
diff --git a/Oqtane.Client/Shared/RichTextEditorInterop.cs b/Oqtane.Client/Shared/RichTextEditorInterop.cs
new file mode 100644
index 00000000..87088fb7
--- /dev/null
+++ b/Oqtane.Client/Shared/RichTextEditorInterop.cs
@@ -0,0 +1,70 @@
+using Microsoft.AspNetCore.Components;
+using Microsoft.JSInterop;
+using System.Threading.Tasks;
+
+namespace Oqtane.Modules.Controls
+{
+ public static class RichTextEditorInterop
+ {
+ internal static ValueTask