From d24895387c984af5470b8dffa4a6bfcb30f98d73 Mon Sep 17 00:00:00 2001 From: Meinrad Recheis Date: Thu, 6 Jul 2023 13:03:21 +0200 Subject: [PATCH] Docs: Fix copy-to-clipboard function for certain snippets (#7161) --- .../Components/SectionContent.razor | 2 +- .../Components/SectionContent.razor.cs | 13 +++++-- .../Extensions/DocsViewExtension.cs | 1 + src/MudBlazor.Docs/Models/Snippets.cs | 2 +- src/MudBlazor.Docs/Services/DocsJsApi.cs | 38 +++++++++++++++++++ src/MudBlazor.Docs/wwwroot/JS/docs.js | 21 ++++++++-- .../Generated/ApiDocsTests.cs | 3 +- .../Generated/ExampleDocsTests.cs | 3 +- .../Mocks/MockDocsJsApiService.cs | 12 ++++++ ...ckJsApiServices.cs => MockJsApiService.cs} | 6 +-- src/MudBlazor/TScripts/mudWindow.js | 1 + 11 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 src/MudBlazor.Docs/Services/DocsJsApi.cs create mode 100644 src/MudBlazor.UnitTests/Mocks/MockDocsJsApiService.cs rename src/MudBlazor.UnitTests/Mocks/{MockJsApiServices.cs => MockJsApiService.cs} (73%) diff --git a/src/MudBlazor.Docs/Components/SectionContent.razor b/src/MudBlazor.Docs/Components/SectionContent.razor index 00d8b6b7ed64..d590a4204f46 100644 --- a/src/MudBlazor.Docs/Components/SectionContent.razor +++ b/src/MudBlazor.Docs/Components/SectionContent.razor @@ -45,7 +45,7 @@ @if (_hasCode) {
-
+
@CodeComponent(_activeCode)
diff --git a/src/MudBlazor.Docs/Components/SectionContent.razor.cs b/src/MudBlazor.Docs/Components/SectionContent.razor.cs index 99e3838f7527..64a403d5603f 100644 --- a/src/MudBlazor.Docs/Components/SectionContent.razor.cs +++ b/src/MudBlazor.Docs/Components/SectionContent.razor.cs @@ -12,12 +12,14 @@ using Microsoft.AspNetCore.Components; using MudBlazor.Docs.Extensions; using MudBlazor.Docs.Models; +using MudBlazor.Docs.Services; namespace MudBlazor.Docs.Components; public partial class SectionContent { [Inject] protected IJsApiService JsApiService { get; set; } + [Inject] protected IDocsJsApiService DocsJsApiService { get; set; } protected string Classname => new CssBuilder("docs-section-content") @@ -47,6 +49,8 @@ public partial class SectionContent .AddClass("show-code", _hasCode && ShowCode) .Build(); + private string _snippetId = "_" + Guid.NewGuid().ToString()[..8]; + [Parameter] public string Class { get; set; } [Parameter] public bool DarkenBackground { get; set; } [Parameter] public bool Outlined { get; set; } = true; @@ -66,9 +70,9 @@ protected override void OnParametersSet() if(Codes != null) { _hasCode = true; - _activeCode = Codes.FirstOrDefault().code; + _activeCode = Codes.FirstOrDefault()?.code; } - else if(!String.IsNullOrWhiteSpace(Code)) + else if(!string.IsNullOrWhiteSpace(Code)) { _hasCode = true; _activeCode = Code; @@ -99,7 +103,10 @@ private string GetActiveCode(string value) private async Task CopyTextToClipboard() { - await JsApiService.CopyToClipboardAsync(Snippets.GetCode(Code)); + var code = Snippets.GetCode(Code); + if (code == null) + code=await DocsJsApiService.GetInnerTextByIdAsync(_snippetId); + await JsApiService.CopyToClipboardAsync(code ?? $"Snippet '{Code}' not found!"); } RenderFragment CodeComponent(string code) => builder => diff --git a/src/MudBlazor.Docs/Extensions/DocsViewExtension.cs b/src/MudBlazor.Docs/Extensions/DocsViewExtension.cs index cfb57481e9c2..be921608f297 100644 --- a/src/MudBlazor.Docs/Extensions/DocsViewExtension.cs +++ b/src/MudBlazor.Docs/Extensions/DocsViewExtension.cs @@ -32,6 +32,7 @@ public static void TryAddDocsViewServices(this IServiceCollection services) #pragma warning restore 0618 }); + services.AddScoped(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/MudBlazor.Docs/Models/Snippets.cs b/src/MudBlazor.Docs/Models/Snippets.cs index f59643d3af16..daf82df3251e 100644 --- a/src/MudBlazor.Docs/Models/Snippets.cs +++ b/src/MudBlazor.Docs/Models/Snippets.cs @@ -11,7 +11,7 @@ public static string GetCode(string component) var field = typeof(Snippets).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField) .FirstOrDefault(f => f.Name == component); if (field == null) - return $"Snippet for component '{component}' not found!"; + return null; return (string)field.GetValue(null); } diff --git a/src/MudBlazor.Docs/Services/DocsJsApi.cs b/src/MudBlazor.Docs/Services/DocsJsApi.cs new file mode 100644 index 000000000000..09c10ea098ec --- /dev/null +++ b/src/MudBlazor.Docs/Services/DocsJsApi.cs @@ -0,0 +1,38 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.JSInterop; + +namespace MudBlazor.Docs.Services +{ + + public interface IDocsJsApiService + { + /// + /// Return the inner text of the HTML element referenced by given id + /// + ValueTask GetInnerTextByIdAsync(string id); + } + + public class DocsJsApiService : IDocsJsApiService + { + private readonly IJSRuntime _jsRuntime; + + public DocsJsApiService(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + /// + public ValueTask GetInnerTextByIdAsync(string id) + { + return _jsRuntime.InvokeAsync($"mudBlazorDocs.getInnerTextById", id); + } + } +} diff --git a/src/MudBlazor.Docs/wwwroot/JS/docs.js b/src/MudBlazor.Docs/wwwroot/JS/docs.js index fc9c29211d5c..a9c65c431122 100644 --- a/src/MudBlazor.Docs/wwwroot/JS/docs.js +++ b/src/MudBlazor.Docs/wwwroot/JS/docs.js @@ -1,13 +1,26 @@ -//General functions for Docs page -var mudBlazorDocs = { +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//General functions for Docs page +class MudBlazorDocs { + + // return the inner text of the element referenced by given element id + getInnerTextById(id) { + let element = document.getElementById(id) + if (!element) + return null; + return element.innerText; + } //scrolls to the active nav link in the NavMenu - scrollToActiveNavLink: function () { + scrollToActiveNavLink() { let element = document.querySelector('.mud-nav-link.active'); if (!element) return; element.scrollIntoView({ block: 'center', behavior: 'smooth' }) } -} +}; +window.mudBlazorDocs = new MudBlazorDocs(); // Workaround for #5482 if(typeof window.GoogleAnalyticsInterop === 'undefined') { diff --git a/src/MudBlazor.UnitTests/Generated/ApiDocsTests.cs b/src/MudBlazor.UnitTests/Generated/ApiDocsTests.cs index ba81be6ab25f..f7b1b0ab25e0 100644 --- a/src/MudBlazor.UnitTests/Generated/ApiDocsTests.cs +++ b/src/MudBlazor.UnitTests/Generated/ApiDocsTests.cs @@ -33,7 +33,8 @@ public void Setup() ctx.Services.AddSingleton(new MockBrowserViewportService()); ctx.Services.AddTransient(); ctx.Services.AddTransient(); - ctx.Services.AddTransient(); + ctx.Services.AddTransient(); + ctx.Services.AddTransient(); ctx.Services.AddTransient(); ctx.Services.AddTransient(); ctx.Services.AddTransient(); diff --git a/src/MudBlazor.UnitTests/Generated/ExampleDocsTests.cs b/src/MudBlazor.UnitTests/Generated/ExampleDocsTests.cs index 925cec2b16a4..d94cf2697c38 100644 --- a/src/MudBlazor.UnitTests/Generated/ExampleDocsTests.cs +++ b/src/MudBlazor.UnitTests/Generated/ExampleDocsTests.cs @@ -33,7 +33,8 @@ public void Setup() ctx.Services.AddSingleton(new MockBrowserViewportService()); ctx.Services.AddTransient(); ctx.Services.AddTransient(); - ctx.Services.AddTransient(); + ctx.Services.AddTransient(); + ctx.Services.AddTransient(); ctx.Services.AddTransient(); ctx.Services.AddTransient(); ctx.Services.AddTransient(); diff --git a/src/MudBlazor.UnitTests/Mocks/MockDocsJsApiService.cs b/src/MudBlazor.UnitTests/Mocks/MockDocsJsApiService.cs new file mode 100644 index 000000000000..fc4b559af1f1 --- /dev/null +++ b/src/MudBlazor.UnitTests/Mocks/MockDocsJsApiService.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using MudBlazor.Docs.Services; + +namespace MudBlazor.UnitTests.Mocks +{ + public class MockDocsJsApiService : IDocsJsApiService + { + + public ValueTask GetInnerTextByIdAsync(string id) => ValueTask.FromResult("inner text"); + + } +} diff --git a/src/MudBlazor.UnitTests/Mocks/MockJsApiServices.cs b/src/MudBlazor.UnitTests/Mocks/MockJsApiService.cs similarity index 73% rename from src/MudBlazor.UnitTests/Mocks/MockJsApiServices.cs rename to src/MudBlazor.UnitTests/Mocks/MockJsApiService.cs index 0742eb05aedc..59409d771a61 100644 --- a/src/MudBlazor.UnitTests/Mocks/MockJsApiServices.cs +++ b/src/MudBlazor.UnitTests/Mocks/MockJsApiService.cs @@ -2,10 +2,8 @@ namespace MudBlazor.UnitTests.Mocks { - /// - /// Mock for scroll listener - /// - public class MockJsApiServices : IJsApiService + + public class MockJsApiService : IJsApiService { public ValueTask CopyToClipboardAsync(string text) => ValueTask.CompletedTask; diff --git a/src/MudBlazor/TScripts/mudWindow.js b/src/MudBlazor/TScripts/mudWindow.js index f9db489f00d9..6dd6e6cc7040 100644 --- a/src/MudBlazor/TScripts/mudWindow.js +++ b/src/MudBlazor/TScripts/mudWindow.js @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. class MudWindow { + copyToClipboard (text) { navigator.clipboard.writeText(text); }