diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor index 47df0248..c588274f 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditor.razor +++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor @@ -117,8 +117,9 @@ { if (firstRender) { - await RichTextEditorInterop.CreateEditor( - JsRuntime, + var interop = new RichTextEditorInterop(JsRuntime); + + await interop.CreateEditor( _editorElement, _toolBar, ReadOnly, @@ -126,14 +127,10 @@ Theme, DebugLevel); - await RichTextEditorInterop.LoadEditorContent( - JsRuntime, - _editorElement, Content); + await interop.LoadEditorContent(_editorElement, Content); // preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor ) - _original = await RichTextEditorInterop.GetHtml( - JsRuntime, - _editorElement); + _original = await interop.GetHtml(_editorElement); } } @@ -146,25 +143,22 @@ public async Task RefreshRichText() { - await RichTextEditorInterop.LoadEditorContent( - JsRuntime, - _editorElement, _content); + var interop = new RichTextEditorInterop(JsRuntime); + await interop.LoadEditorContent(_editorElement, _content); } public async Task RefreshRawHtml() { - _content = await RichTextEditorInterop.GetHtml( - JsRuntime, - _editorElement); + var interop = new RichTextEditorInterop(JsRuntime); + _content = await interop.GetHtml(_editorElement); StateHasChanged(); } public async Task GetHtml() { // get rich text content - string content = await RichTextEditorInterop.GetHtml( - JsRuntime, - _editorElement); + var interop = new RichTextEditorInterop(JsRuntime); + string content = await interop.GetHtml(_editorElement); if (_original != content) { @@ -185,9 +179,8 @@ var fileid = _fileManager.GetFileId(); if (fileid != -1) { - await RichTextEditorInterop.InsertImage( - JsRuntime, - _editorElement, ContentUrl(fileid)); + var interop = new RichTextEditorInterop(JsRuntime); + await interop.InsertImage(_editorElement, ContentUrl(fileid)); _filemanagervisible = false; _message = string.Empty; } @@ -207,22 +200,19 @@ // other rich text editor methods which can be used by developers public async Task GetText() { - return await RichTextEditorInterop.GetText( - JsRuntime, - _editorElement); + var interop = new RichTextEditorInterop(JsRuntime); + return await interop.GetText(_editorElement); } public async Task GetContent() { - return await RichTextEditorInterop.GetContent( - JsRuntime, - _editorElement); + var interop = new RichTextEditorInterop(JsRuntime); + return await interop.GetContent(_editorElement); } public async Task EnableEditor(bool mode) { - await RichTextEditorInterop.EnableEditor( - JsRuntime, - _editorElement, mode); + var interop = new RichTextEditorInterop(JsRuntime); + await interop.EnableEditor(_editorElement, mode); } } diff --git a/Oqtane.Client/Modules/Controls/RichTextEditorInterop.cs b/Oqtane.Client/Modules/Controls/RichTextEditorInterop.cs index 1f590f8a..c9b442d4 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditorInterop.cs +++ b/Oqtane.Client/Modules/Controls/RichTextEditorInterop.cs @@ -4,10 +4,16 @@ using System.Threading.Tasks; namespace Oqtane.Modules.Controls { - public static class RichTextEditorInterop + public class RichTextEditorInterop { - internal static ValueTask CreateEditor( - IJSRuntime jsRuntime, + private readonly IJSRuntime _jsRuntime; + + public RichTextEditorInterop(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + public Task CreateEditor( ElementReference quillElement, ElementReference toolbar, bool readOnly, @@ -15,66 +21,104 @@ namespace Oqtane.Modules.Controls string theme, string debugLevel) { - return jsRuntime.InvokeAsync( - "interop.createQuill", - quillElement, toolbar, readOnly, - placeholder, theme, debugLevel); + try + { + _jsRuntime.InvokeAsync( + "interop.createQuill", + quillElement, toolbar, readOnly, + placeholder, theme, debugLevel); + return Task.CompletedTask; + } + catch + { + return Task.CompletedTask; + } } - internal static ValueTask GetText( - IJSRuntime jsRuntime, - ElementReference quillElement) + public ValueTask GetText(ElementReference quillElement) { - return jsRuntime.InvokeAsync( - "interop.getQuillText", - quillElement); + try + { + return _jsRuntime.InvokeAsync( + "interop.getQuillText", + quillElement); + } + catch + { + return new ValueTask(Task.FromResult(string.Empty)); + } } - internal static ValueTask GetHtml( - IJSRuntime jsRuntime, - ElementReference quillElement) + public ValueTask GetHtml(ElementReference quillElement) { - return jsRuntime.InvokeAsync( - "interop.getQuillHTML", - quillElement); + try + { + return _jsRuntime.InvokeAsync( + "interop.getQuillHTML", + quillElement); + } + catch + { + return new ValueTask(Task.FromResult(string.Empty)); + } } - internal static ValueTask GetContent( - IJSRuntime jsRuntime, - ElementReference quillElement) + public ValueTask GetContent(ElementReference quillElement) { - return jsRuntime.InvokeAsync( - "interop.getQuillContent", - quillElement); + try + { + return _jsRuntime.InvokeAsync( + "interop.getQuillContent", + quillElement); + } + catch + { + return new ValueTask(Task.FromResult(string.Empty)); + } } - internal static ValueTask LoadEditorContent( - IJSRuntime jsRuntime, - ElementReference quillElement, - string content) + public Task LoadEditorContent(ElementReference quillElement, string content) { - return jsRuntime.InvokeAsync( - "interop.loadQuillContent", - quillElement, content); + try + { + _jsRuntime.InvokeAsync( + "interop.loadQuillContent", + quillElement, content); + return Task.CompletedTask; + } + catch + { + return Task.CompletedTask; + } } - internal static ValueTask EnableEditor( - IJSRuntime jsRuntime, - ElementReference quillElement, - bool mode) + public Task EnableEditor(ElementReference quillElement, bool mode) { - return jsRuntime.InvokeAsync( - "interop.enableQuillEditor", quillElement, mode); + try + { + _jsRuntime.InvokeAsync( + "interop.enableQuillEditor", quillElement, mode); + return Task.CompletedTask; + } + catch + { + return Task.CompletedTask; + } } - internal static ValueTask InsertImage( - IJSRuntime jsRuntime, - ElementReference quillElement, - string imageUrl) + public Task InsertImage(ElementReference quillElement, string imageUrl) { - return jsRuntime.InvokeAsync( - "interop.insertQuillImage", - quillElement, imageUrl); + try + { + _jsRuntime.InvokeAsync( + "interop.insertQuillImage", + quillElement, imageUrl); + return Task.CompletedTask; + } + catch + { + return Task.CompletedTask; + } } } } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 0ae86ac5..5c95ade6 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using System; +using Microsoft.JSInterop; using System.Threading.Tasks; namespace Oqtane.UI @@ -18,7 +16,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.setCookie", name, value, days); return Task.CompletedTask; @@ -47,7 +45,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.updateTitle", title); return Task.CompletedTask; @@ -62,7 +60,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.includeMeta", id, attribute, name, content); return Task.CompletedTask; @@ -77,7 +75,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.includeLink", id, rel, url, type, integrity, crossorigin); return Task.CompletedTask; @@ -92,7 +90,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.includeScript", id, src, content, location, integrity, crossorigin); return Task.CompletedTask; @@ -107,7 +105,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.includeLink", id, "stylesheet", url, "text/css"); return Task.CompletedTask; @@ -122,7 +120,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.removeElementsById", prefix, first, last); return Task.CompletedTask; @@ -152,7 +150,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.submitForm", path, fields); return Task.CompletedTask; @@ -181,7 +179,7 @@ namespace Oqtane.UI { try { - _jsRuntime.InvokeAsync( + _jsRuntime.InvokeAsync( "interop.uploadFiles", posturl, folder, id); return Task.CompletedTask; diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/Module.css b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/Module.css new file mode 100644 index 00000000..0856a263 --- /dev/null +++ b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/Module.css @@ -0,0 +1 @@ +/* Module Custom Styles */ \ No newline at end of file diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/Module.js b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/Module.js new file mode 100644 index 00000000..1b415a08 --- /dev/null +++ b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/Module.js @@ -0,0 +1 @@ +/* Module Script */ \ No newline at end of file diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/resources.txt b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/resources.txt new file mode 100644 index 00000000..903815cf --- /dev/null +++ b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]s/resources.txt @@ -0,0 +1 @@ +This is the location where static resources such as images, style sheets, or scripts for this module will be located. Static assets can be organized in subfolders. When the module package is deployed the assets will be extracted under the web root in a folder that matches the module namespace. \ No newline at end of file