Skip to content

Commit 9061954

Browse files
committed
Added MarkerService
1 parent 1fa4356 commit 9061954

File tree

7 files changed

+81
-3
lines changed

7 files changed

+81
-3
lines changed

src/LinkDotNet.Blog.Web/Pages/_Layout.cshtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<script async src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/languages/csharp.min.js" integrity="sha512-v7mtZg9ySysViDE/8FxpWzLPe4Qzj+xQ//OqdMkl0UapomXAjp79QNiziv6PLmG5GSXjTcfCOzEBv5B/Rp6COg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
4949
<script async src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js" integrity="sha512-Tn2m0TIpgVyTzzvmxLNuqbSJH3JP8jm+Cy3hvHrW7ndTDcJ1w5mBiksqDBb8GpE2ksktFvDB/ykZ0mDpsZj20w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
5050
<script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha256-cMPWkL3FzjuaFSfEYESYmjF25hCIL6mfRSPnW8OVvM4=" crossorigin="anonymous"></script>
51+
<script async src="components/selection.js" ></script>
5152
<script async src="components/slideshow.js" ></script>
5253
</body>
5354
</html>

src/LinkDotNet.Blog.Web/ServiceExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ public static void RegisterServices(this IServiceCollection services)
1616
services.AddScoped<ISitemapService, SitemapService>();
1717
services.AddScoped<IXmlFileWriter, XmlFileWriter>();
1818
services.AddScoped<IFileProcessor, FileProcessor>();
19+
services.AddScoped<IMarkerService, MarkerService>();
1920
}
2021
}

src/LinkDotNet.Blog.Web/Shared/Admin/CreateNewBlogPost.razor

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@using LinkDotNet.Blog.Domain
2+
@using LinkDotNet.Blog.Web.Shared.Services
23
@inherits MarkdownComponentBase
4+
@inject IMarkerService markerService
35

46
<h3>@Title</h3>
57

@@ -15,13 +17,14 @@
1517
</div>
1618
<div class="mb-3">
1719
<label for="short">Short Description</label>
18-
<textarea class="form-control" id="short" rows="4"
20+
<textarea class="form-control" id="short" rows="4" @onkeyup="MarkShortDescription"
1921
@oninput="args => model.ShortDescription = args.Value.ToString()">@model.ShortDescription</textarea>
2022
<small for="short" class="form-text text-muted">You can use markdown to style your component.</small>
2123
</div>
2224
<div class="mb-3">
2325
<label for="content">Content</label>
24-
<textarea class="form-control" id="content" @oninput="args => model.Content = args.Value.ToString()" rows="10">@model.Content</textarea>
26+
<textarea class="form-control" id="content" @oninput="args => model.Content = args.Value.ToString()" rows="10"
27+
@onkeyup="MarkContent">@model.Content</textarea>
2528
<small for="content" class="form-text text-muted">You can use markdown to style your component. Additional features are listed <a @onclick="@(() => FeatureDialog.Open())">here</a></small>
2629
<UploadFile OnFileUploaded="SetContentFromFile" id="content-upload"></UploadFile>
2730
<small for="content-upload" class="form-text text-muted">Drag and drop markdown files to upload and
@@ -83,6 +86,8 @@
8386

8487
private FeatureInfoDialog FeatureDialog { get; set; }
8588

89+
private ElementReference reference;
90+
8691
private CreateNewModel model = new();
8792

8893
protected override void OnParametersSet()
@@ -114,4 +119,25 @@
114119
{
115120
model.Content = content;
116121
}
122+
123+
private async Task MarkShortDescription(KeyboardEventArgs keyboardEventArgs)
124+
{
125+
model.ShortDescription = await GetNewMarkdownForElementAsync(keyboardEventArgs, model.ShortDescription, "short");
126+
}
127+
128+
private async Task MarkContent(KeyboardEventArgs keyboardEventArgs)
129+
{
130+
model.Content = await GetNewMarkdownForElementAsync(keyboardEventArgs, model.Content, "content");
131+
}
132+
133+
private async Task<string> GetNewMarkdownForElementAsync(KeyboardEventArgs keyboardEventArgs, string original, string elementId)
134+
{
135+
return keyboardEventArgs.CtrlKey ? keyboardEventArgs.Key switch
136+
{
137+
"b" => await markerService.GetNewMarkdownForElementAsync(elementId, original, "**", "**"),
138+
"i" => await markerService.GetNewMarkdownForElementAsync(elementId, original, "*", "*"),
139+
_ => original,
140+
} : original;
141+
}
142+
117143
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System.Threading.Tasks;
2+
3+
namespace LinkDotNet.Blog.Web.Shared.Services;
4+
5+
public interface IMarkerService
6+
{
7+
Task<string> GetNewMarkdownForElementAsync(string elementId, string content, string fenceBegin, string fenceEnd);
8+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Threading.Tasks;
2+
using Microsoft.JSInterop;
3+
4+
namespace LinkDotNet.Blog.Web.Shared.Services;
5+
6+
public class MarkerService : IMarkerService
7+
{
8+
private readonly IJSRuntime jsRuntime;
9+
10+
public MarkerService(IJSRuntime jsRuntime)
11+
{
12+
this.jsRuntime = jsRuntime;
13+
}
14+
15+
public async Task<string> GetNewMarkdownForElementAsync(string elementId, string content, string fenceBegin, string fenceEnd)
16+
{
17+
var selectionRange = await jsRuntime.InvokeAsync<SelectionRange>("getSelectionFromElement", elementId);
18+
if (selectionRange.Start == selectionRange.End)
19+
{
20+
return string.Empty;
21+
}
22+
23+
var beforeMarker = selectionRange.Start > 0 ? content[..selectionRange.Start] : string.Empty;
24+
var marker = content.Substring(selectionRange.Start, selectionRange.End - selectionRange.Start);
25+
var afterMarker = content.Substring(selectionRange.End, content.Length - selectionRange.End - 1);
26+
return beforeMarker + fenceBegin + marker + fenceEnd + afterMarker;
27+
}
28+
29+
private sealed class SelectionRange
30+
{
31+
public int Start { get; set; }
32+
33+
public int End { get; set; }
34+
}
35+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
window.getSelectionFromElement = function (id) {
2+
const elem = document.getElementById(id)
3+
const start = elem.selectionStart
4+
const end = elem.selectionEnd
5+
elem.selectionStart = elem.selectionEnd = 0
6+
return { start, end }
7+
}

tests/LinkDotNet.Blog.UnitTests/Web/Shared/Admin/CreateNewBlogPostTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class CreateNewBlogPostTests : TestContext
1414
{
1515
public CreateNewBlogPostTests()
1616
{
17-
ComponentFactories.AddStub<UploadFile>();
17+
ComponentFactories.Add<UploadFile, UploadFile>():
1818
}
1919

2020
[Fact]

0 commit comments

Comments
 (0)