Skip to content

Commit 011ddbf

Browse files
committed
Put Shortcuts in own component instead of service
1 parent cd654a4 commit 011ddbf

File tree

11 files changed

+130
-157
lines changed

11 files changed

+130
-157
lines changed

src/LinkDotNet.Blog.Web/ServiceExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,5 @@ 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>();
2019
}
2120
}

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

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

65
<h3>@Title</h3>
76

@@ -17,14 +16,14 @@
1716
</div>
1817
<div class="mb-3">
1918
<label for="short">Short Description</label>
20-
<textarea class="form-control" id="short" rows="4" @onkeyup="MarkShortDescription"
21-
@oninput="args => model.ShortDescription = args.Value.ToString()">@model.ShortDescription</textarea>
19+
<TextAreaWithShortcuts Id="short" Class="form-control" Rows="4"
20+
@bind-Value="@model.ShortDescription"></TextAreaWithShortcuts>
2221
<small for="short" class="form-text text-muted">You can use markdown to style your component</small>
2322
</div>
2423
<div class="mb-3">
2524
<label for="content">Content</label>
26-
<textarea class="form-control" id="content" @oninput="args => model.Content = args.Value.ToString()" rows="10"
27-
@onkeyup="MarkContent">@model.Content</textarea>
25+
<TextAreaWithShortcuts Id="content" Class="form-control" Rows="10"
26+
@bind-Value="@model.Content"></TextAreaWithShortcuts>
2827
<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>
2928
<UploadFile OnFileUploaded="SetContentFromFile" id="content-upload"></UploadFile>
3029
<small for="content-upload" class="form-text text-muted">Drag and drop markdown files to upload and
@@ -117,27 +116,4 @@
117116
{
118117
model.Content = content;
119118
}
120-
121-
private async Task MarkShortDescription(KeyboardEventArgs keyboardEventArgs)
122-
{
123-
model.ShortDescription = await GetNewMarkdownForElementAsync(keyboardEventArgs, model.ShortDescription, "short");
124-
StateHasChanged();
125-
}
126-
127-
private async Task MarkContent(KeyboardEventArgs keyboardEventArgs)
128-
{
129-
model.Content = await GetNewMarkdownForElementAsync(keyboardEventArgs, model.Content, "content");
130-
StateHasChanged();
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-
143119
}

src/LinkDotNet.Blog.Web/Shared/Services/SelectionRange.cs renamed to src/LinkDotNet.Blog.Web/Shared/SelectionRange.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace LinkDotNet.Blog.Web.Shared.Services;
1+
namespace LinkDotNet.Blog.Web.Shared;
22

33
public sealed class SelectionRange
44
{

src/LinkDotNet.Blog.Web/Shared/Services/IMarkerService.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/LinkDotNet.Blog.Web/Shared/Services/MarkerService.cs

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
@inject IJSRuntime jsRuntime
2+
3+
<textarea class="@Class" id="@Id" rows="@Rows" @onkeyup="MarkShortDescription"
4+
@oninput="args => Value = args.Value.ToString()">@Value</textarea>
5+
6+
@code {
7+
private string textContent = string.Empty;
8+
9+
[Parameter]
10+
public string Value
11+
{
12+
get => textContent;
13+
set
14+
{
15+
if (textContent != value)
16+
{
17+
textContent = value;
18+
ValueChanged.InvokeAsync(value);
19+
}
20+
}
21+
}
22+
23+
[Parameter]
24+
public EventCallback<string> ValueChanged { get; set; }
25+
26+
[Parameter]
27+
public string Class { get; set; }
28+
29+
[Parameter]
30+
public string Id { get; set; }
31+
32+
[Parameter]
33+
public int Rows { get; set; }
34+
35+
private async Task MarkShortDescription(KeyboardEventArgs keyboardEventArgs)
36+
{
37+
Value = await GetNewMarkdownForElementAsync(keyboardEventArgs, Value, Id);
38+
StateHasChanged();
39+
}
40+
41+
private async Task<string> GetNewMarkdownForElementAsync(KeyboardEventArgs keyboardEventArgs, string original, string elementId)
42+
{
43+
return keyboardEventArgs.CtrlKey ? keyboardEventArgs.Key switch
44+
{
45+
"b" => await GetNewMarkdownForElementAsync(elementId, original, "**", "**"),
46+
"i" => await GetNewMarkdownForElementAsync(elementId, original, "*", "*"),
47+
_ => original,
48+
} : original;
49+
}
50+
51+
private async Task<string> GetNewMarkdownForElementAsync(
52+
string elementId,
53+
string content,
54+
string fenceBegin,
55+
string fenceEnd)
56+
{
57+
var selectionRange = await jsRuntime.InvokeAsync<SelectionRange>("getSelectionFromElement", elementId);
58+
if (selectionRange.Start == selectionRange.End)
59+
{
60+
return content;
61+
}
62+
63+
var beforeMarker = selectionRange.Start > 0 ? content[..selectionRange.Start] : string.Empty;
64+
var marker = content[selectionRange.Start..selectionRange.End];
65+
var afterMarker = content[selectionRange.End..];
66+
var shift = selectionRange.End + fenceBegin.Length + fenceEnd.Length;
67+
await jsRuntime.InvokeVoidAsync("setSelectionFromElement", elementId, shift);
68+
return beforeMarker + fenceBegin + marker + fenceEnd + afterMarker;
69+
}
70+
}

tests/LinkDotNet.Blog.IntegrationTests/Web/Pages/Admin/CreateNewBlogPostPageTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public async Task ShouldSaveBlogPostOnSave()
2828
ctx.Services.AddScoped(_ => toastService.Object);
2929
ctx.ComponentFactories.AddStub<UploadFile>();
3030
ctx.Services.AddScoped(_ => Mock.Of<IFileProcessor>());
31-
ctx.Services.AddScoped(_ => Mock.Of<IMarkerService>());
3231
using var cut = ctx.RenderComponent<CreateNewBlogPostPage>();
3332
var newBlogPost = cut.FindComponent<CreateNewBlogPost>();
3433

tests/LinkDotNet.Blog.IntegrationTests/Web/Pages/Admin/UpdateBlogPostPageTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using LinkDotNet.Blog.Web.Pages.Admin;
1111
using LinkDotNet.Blog.Web.Shared;
1212
using LinkDotNet.Blog.Web.Shared.Admin;
13-
using LinkDotNet.Blog.Web.Shared.Services;
1413
using Microsoft.EntityFrameworkCore;
1514
using Microsoft.Extensions.DependencyInjection;
1615
using Moq;
@@ -31,7 +30,6 @@ public async Task ShouldSaveBlogPostOnSave()
3130
ctx.Services.AddScoped<IRepository<BlogPost>>(_ => Repository);
3231
ctx.Services.AddScoped(_ => toastService.Object);
3332
ctx.ComponentFactories.AddStub<UploadFile>();
34-
ctx.Services.AddScoped(_ => Mock.Of<IMarkerService>());
3533
using var cut = ctx.RenderComponent<UpdateBlogPostPage>(
3634
p => p.Add(s => s.BlogPostId, blogPost.Id));
3735
var newBlogPost = cut.FindComponent<CreateNewBlogPost>();

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

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
using LinkDotNet.Blog.TestUtilities;
77
using LinkDotNet.Blog.Web.Shared;
88
using LinkDotNet.Blog.Web.Shared.Admin;
9-
using LinkDotNet.Blog.Web.Shared.Services;
10-
using Microsoft.Extensions.DependencyInjection;
11-
using Moq;
129
using Xunit;
1310

1411
namespace LinkDotNet.Blog.UnitTests.Web.Shared.Admin;
@@ -23,7 +20,6 @@ public CreateNewBlogPostTests()
2320
[Fact]
2421
public void ShouldCreateNewBlogPostWhenValidDataGiven()
2522
{
26-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
2723
BlogPost blogPost = null;
2824
var cut = RenderComponent<CreateNewBlogPost>(
2925
p => p.Add(c => c.OnBlogPostCreated, bp => blogPost = bp));
@@ -57,7 +53,6 @@ public void ShouldFillGivenBlogPost()
5753
.WithTags("tag1", "tag2")
5854
.Build();
5955
BlogPost blogPostFromComponent = null;
60-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
6156
var cut = RenderComponent<CreateNewBlogPost>(
6257
p =>
6358
p.Add(c => c.OnBlogPostCreated, bp => blogPostFromComponent = bp)
@@ -79,7 +74,6 @@ public void ShouldFillGivenBlogPost()
7974
public void ShouldNotDeleteModelWhenSet()
8075
{
8176
BlogPost blogPost = null;
82-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
8377
var cut = RenderComponent<CreateNewBlogPost>(
8478
p => p.Add(c => c.ClearAfterCreated, true)
8579
.Add(c => c.OnBlogPostCreated, post => blogPost = post));
@@ -100,7 +94,6 @@ public void ShouldNotDeleteModelWhenSet()
10094
public void ShouldNotDeleteModelWhenNotSet()
10195
{
10296
BlogPost blogPost = null;
103-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
10497
var cut = RenderComponent<CreateNewBlogPost>(
10598
p => p.Add(c => c.ClearAfterCreated, false)
10699
.Add(c => c.OnBlogPostCreated, post => blogPost = post));
@@ -120,7 +113,6 @@ public void ShouldNotDeleteModelWhenNotSet()
120113
[Fact]
121114
public void ShouldNotUpdateUpdatedDateWhenCheckboxSet()
122115
{
123-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
124116
var somewhen = new DateTime(1991, 5, 17);
125117
var originalBlogPost = new BlogPostBuilder().WithUpdatedDate(somewhen).Build();
126118
BlogPost blogPostFromComponent = null;
@@ -143,7 +135,6 @@ public void ShouldNotUpdateUpdatedDateWhenCheckboxSet()
143135
[Fact]
144136
public void ShouldNotSetOptionToNotUpdateUpdatedDateOnInitialCreate()
145137
{
146-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
147138
var cut = RenderComponent<CreateNewBlogPost>();
148139

149140
var found = cut.FindAll("#updatedate");
@@ -154,7 +145,6 @@ public void ShouldNotSetOptionToNotUpdateUpdatedDateOnInitialCreate()
154145
[Fact]
155146
public void ShouldAcceptInputWithoutLosingFocusOrEnter()
156147
{
157-
Services.AddScoped(_ => Mock.Of<IMarkerService>());
158148
BlogPost blogPost = null;
159149
var cut = RenderComponent<CreateNewBlogPost>(
160150
p => p.Add(c => c.OnBlogPostCreated, bp => blogPost = bp));
@@ -177,30 +167,4 @@ public void ShouldAcceptInputWithoutLosingFocusOrEnter()
177167
blogPost.Tags.Should().HaveCount(3);
178168
blogPost.Tags.Select(t => t.Content).Should().Contain(new[] { "Tag1", "Tag2", "Tag3" });
179169
}
180-
181-
[Theory]
182-
[InlineData("short", "b", true, "**", "**Test**")]
183-
[InlineData("short", "i", true, "*", "*Test*")]
184-
[InlineData("short", "h", true, "*", "Test")]
185-
[InlineData("short", "b", false, "**", "Test")]
186-
[InlineData("short", "f", false, "**", "Test")]
187-
[InlineData("content", "b", true, "**", "**Test**")]
188-
[InlineData("content", "i", true, "*", "*Test*")]
189-
[InlineData("content", "h", true, "*", "Test")]
190-
[InlineData("content", "b", false, "**", "Test")]
191-
[InlineData("content", "f", false, "**", "Test")]
192-
public void ShouldSetMarkerOnKeyUp(string id, string key, bool ctrlPressed, string fence, string expected)
193-
{
194-
var markerMock = new Mock<IMarkerService>();
195-
markerMock.Setup(m => m.GetNewMarkdownForElementAsync(id, "Test", fence, fence))
196-
.ReturnsAsync(expected);
197-
Services.AddScoped(_ => markerMock.Object);
198-
var cut = RenderComponent<CreateNewBlogPost>();
199-
cut.Find($"#{id}").Input("Test");
200-
cut.Find($"#{id}").KeyUp(key, ctrlKey: ctrlPressed);
201-
202-
var content = cut.Find($"#{id}").TextContent;
203-
204-
content.Should().Be(expected);
205-
}
206170
}

tests/LinkDotNet.Blog.UnitTests/Web/Shared/Services/MarkerServiceTests.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)