diff --git a/src/Microsoft.AspNet.Razor.Runtime/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Razor.Runtime/Properties/Resources.Designer.cs index 5a0fccdfdb..e9d4cc8127 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/Properties/Resources.Designer.cs @@ -62,6 +62,22 @@ namespace Microsoft.AspNet.Razor.Runtime return GetString("TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull"); } + /// + /// Must call '{2}.{1}' before calling '{2}.{0}'. + /// + internal static string ScopeManager_EndCannotBeCalledWithoutACallToBegin + { + get { return GetString("ScopeManager_EndCannotBeCalledWithoutACallToBegin"); } + } + + /// + /// Must call '{2}.{1}' before calling '{2}.{0}'. + /// + internal static string FormatScopeManager_EndCannotBeCalledWithoutACallToBegin(object p0, object p1, object p2) + { + return string.Format(CultureInfo.CurrentCulture, GetString("ScopeManager_EndCannotBeCalledWithoutACallToBegin"), p0, p1, p2); + } + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNet.Razor.Runtime/Resources.resx b/src/Microsoft.AspNet.Razor.Runtime/Resources.resx index 8a7d783249..89259d17d4 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/Resources.resx +++ b/src/Microsoft.AspNet.Razor.Runtime/Resources.resx @@ -128,4 +128,7 @@ Tag helper directive assembly name cannot be null or empty. + + Must call '{2}.{1}' before calling '{2}.{0}'. + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelpersExecutionContext.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs similarity index 94% rename from src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelpersExecutionContext.cs rename to src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs index dd58d2c723..93087fab3b 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelpersExecutionContext.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs @@ -9,15 +9,15 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers /// /// Class used to store information about a 's execution lifetime. /// - public class TagHelpersExecutionContext + public class TagHelperExecutionContext { private readonly List _tagHelpers; /// - /// Instantiates a new . + /// Instantiates a new . /// /// The HTML tag name in the Razor source. - public TagHelpersExecutionContext([NotNull] string tagName) + public TagHelperExecutionContext([NotNull] string tagName) { AllAttributes = new Dictionary(StringComparer.Ordinal); HTMLAttributes = new Dictionary(StringComparer.Ordinal); diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperRunner.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperRunner.cs index a6aa597529..fd8ba3c408 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperRunner.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperRunner.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers /// Contains information associated with running s. /// Resulting from processing all of the /// 's s. - public async Task RunAsync([NotNull] TagHelpersExecutionContext context) + public async Task RunAsync([NotNull] TagHelperExecutionContext context) { return await RunAsyncCore(context, string.Empty); } @@ -29,13 +29,13 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers /// Contains the buffered content of the current HTML tag. /// Resulting from processing all of the /// 's s. - public async Task RunAsync([NotNull] TagHelpersExecutionContext context, + public async Task RunAsync([NotNull] TagHelperExecutionContext context, [NotNull] TextWriter bufferedBody) { return await RunAsyncCore(context, bufferedBody.ToString()); } - private async Task RunAsyncCore(TagHelpersExecutionContext executionContext, string outputContent) + private async Task RunAsyncCore(TagHelperExecutionContext executionContext, string outputContent) { var tagHelperContext = new TagHelperContext(executionContext.AllAttributes); var tagHelperOutput = new TagHelperOutput(executionContext.TagName, diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperScopeManager.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperScopeManager.cs new file mode 100644 index 0000000000..7ce38b69ba --- /dev/null +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperScopeManager.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic; + +namespace Microsoft.AspNet.Razor.Runtime.TagHelpers +{ + /// + /// Class that manages scopes. + /// + public class TagHelperScopeManager + { + private readonly Stack _executionScopes; + + /// + /// Instantiates a new . + /// + public TagHelperScopeManager() + { + _executionScopes = new Stack(); + } + + /// + /// Starts a scope. + /// + /// The HTML tag name that the scope is associated with. + /// A to use. + public TagHelperExecutionContext Begin(string tagName) + { + var executionContext = new TagHelperExecutionContext(tagName); + + _executionScopes.Push(executionContext); + + return executionContext; + } + + /// + /// Ends a scope. + /// + /// If the current scope is nested, the parent . + /// null otherwise. + public TagHelperExecutionContext End() + { + if (_executionScopes.Count == 0) + { + throw new InvalidOperationException( + Resources.FormatScopeManager_EndCannotBeCalledWithoutACallToBegin( + nameof(End), + nameof(Begin), + nameof(TagHelperScopeManager))); + } + + _executionScopes.Pop(); + + if (_executionScopes.Count != 0) + { + return _executionScopes.Peek(); + } + + return null; + } + } +} \ No newline at end of file