Add support for naming a page (#1204)
This commit is contained in:
parent
69b019ebd8
commit
e2267f54a6
|
|
@ -1,27 +1,40 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
public static class PageDirective
|
||||
public class PageDirective
|
||||
{
|
||||
public static readonly DirectiveDescriptor DirectiveDescriptor = DirectiveDescriptorBuilder
|
||||
.Create("page")
|
||||
.BeginOptionals()
|
||||
.AddString()
|
||||
.AddString() // Route template
|
||||
.AddString() // Page Name
|
||||
.Build();
|
||||
|
||||
private PageDirective(string routeTemplate, string pageName)
|
||||
{
|
||||
RouteTemplate = routeTemplate;
|
||||
PageName = pageName;
|
||||
}
|
||||
|
||||
public string RouteTemplate { get; }
|
||||
|
||||
public string PageName { get; }
|
||||
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
builder.AddDirective(DirectiveDescriptor);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static bool TryGetRouteTemplate(DocumentIRNode irDocument, out string routeTemplate)
|
||||
public static bool TryGetPageDirective(DocumentIRNode irDocument, out PageDirective pageDirective)
|
||||
{
|
||||
var visitor = new Visitor();
|
||||
for (var i = 0; i < irDocument.Children.Count; i++)
|
||||
|
|
@ -29,22 +42,46 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
visitor.Visit(irDocument.Children[i]);
|
||||
}
|
||||
|
||||
routeTemplate = visitor.RouteTemplate;
|
||||
return visitor.DirectiveNode != null;
|
||||
if (visitor.DirectiveNode == null)
|
||||
{
|
||||
pageDirective = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var tokens = visitor.DirectiveNode.Tokens.ToList();
|
||||
string routeTemplate = null;
|
||||
string pageName = null;
|
||||
if (tokens.Count > 0)
|
||||
{
|
||||
routeTemplate = TrimQuotes(tokens[0].Content);
|
||||
}
|
||||
|
||||
if (tokens.Count > 1)
|
||||
{
|
||||
pageName = TrimQuotes(tokens[1].Content);
|
||||
}
|
||||
|
||||
pageDirective = new PageDirective(routeTemplate, pageName);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string TrimQuotes(string content)
|
||||
{
|
||||
Debug.Assert(content.StartsWith("\"", StringComparison.Ordinal));
|
||||
Debug.Assert(content.EndsWith("\"", StringComparison.Ordinal));
|
||||
|
||||
return content.Substring(1, content.Length - 2);
|
||||
}
|
||||
|
||||
private class Visitor : RazorIRNodeWalker
|
||||
{
|
||||
public DirectiveIRNode DirectiveNode { get; private set; }
|
||||
|
||||
public string RouteTemplate { get; private set; }
|
||||
|
||||
public override void VisitDirective(DirectiveIRNode node)
|
||||
{
|
||||
if (node.Descriptor == DirectiveDescriptor)
|
||||
{
|
||||
DirectiveNode = node;
|
||||
RouteTemplate = node.Tokens.FirstOrDefault()?.Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
|
||||
protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIRNode irDocument)
|
||||
{
|
||||
string routePrefix;
|
||||
return PageDirective.TryGetRouteTemplate(irDocument, out routePrefix);
|
||||
return PageDirective.TryGetPageDirective(irDocument, out var directive);
|
||||
}
|
||||
|
||||
protected override void OnDocumentStructureCreated(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
public class PageDirectiveTest
|
||||
{
|
||||
[Fact]
|
||||
public void TryGetPageDirective_ReturnsFalse_IfPageDoesNotHaveDirective()
|
||||
{
|
||||
// Arrange
|
||||
var content = "Hello world";
|
||||
var sourceDocument = RazorSourceDocument.Create(content, "file");
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var engine = CreateEngine();
|
||||
var irDocument = CreateIRDocument(engine, codeDocument);
|
||||
|
||||
// Act
|
||||
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.Null(pageDirective);
|
||||
}
|
||||
|
||||
[Fact(Skip = "https://github.com/aspnet/Razor/issues/1201")]
|
||||
public void TryGetPageDirective_ReturnsFalse_IfPageDoesStartWithDirective()
|
||||
{
|
||||
// Arrange
|
||||
var content = "Hello @page";
|
||||
var sourceDocument = RazorSourceDocument.Create(content, "file");
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var engine = CreateEngine();
|
||||
var irDocument = CreateIRDocument(engine, codeDocument);
|
||||
|
||||
// Act
|
||||
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.Null(pageDirective);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_ReturnsTrue_IfContentHasDirective()
|
||||
{
|
||||
// Arrange
|
||||
var content = "@page";
|
||||
var sourceDocument = RazorSourceDocument.Create(content, "file");
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var engine = CreateEngine();
|
||||
var irDocument = CreateIRDocument(engine, codeDocument);
|
||||
|
||||
// Act
|
||||
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.Null(pageDirective.RouteTemplate);
|
||||
Assert.Null(pageDirective.PageName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_ParsesRouteTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var content = "@page \"some-route-template\"";
|
||||
var sourceDocument = RazorSourceDocument.Create(content, "file");
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var engine = CreateEngine();
|
||||
var irDocument = CreateIRDocument(engine, codeDocument);
|
||||
|
||||
// Act
|
||||
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.Equal("some-route-template", pageDirective.RouteTemplate);
|
||||
Assert.Null(pageDirective.PageName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_ParsesPageName()
|
||||
{
|
||||
// Arrange
|
||||
var content = "@page \"some-route\" \"some name\"";
|
||||
var sourceDocument = RazorSourceDocument.Create(content, "file");
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var engine = CreateEngine();
|
||||
var irDocument = CreateIRDocument(engine, codeDocument);
|
||||
|
||||
// Act
|
||||
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.Equal("some-route", pageDirective.RouteTemplate);
|
||||
Assert.Equal("some name", pageDirective.PageName);
|
||||
}
|
||||
|
||||
private RazorEngine CreateEngine()
|
||||
{
|
||||
return RazorEngine.Create(b =>
|
||||
{
|
||||
PageDirective.Register(b);
|
||||
});
|
||||
}
|
||||
|
||||
private DocumentIRNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
|
||||
{
|
||||
for (var i = 0; i < engine.Phases.Count; i++)
|
||||
{
|
||||
var phase = engine.Phases[i];
|
||||
phase.Execute(codeDocument);
|
||||
|
||||
if (phase is IRazorDocumentClassifierPhase)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return codeDocument.GetIRDocument();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue