From afe09c08500db9b529e7ba1ada0bd11579add3cf Mon Sep 17 00:00:00 2001 From: Tom Rankin Date: Tue, 9 Jun 2015 14:19:59 -0500 Subject: [PATCH 1/3] Fix U4-6687: Can't add multiple instances of a macro in RTE in 7.2.6 without ruining RTE formatting We found that the MacroTagParser.cs was being greedy and matching all UMBRACO_MACRO tags instead of getting them individually. macro.service.js was updated for posterity purposes to match the regex in the .cs side, but testing showed that it was functioning as expected without this change. --- src/Umbraco.Core/Macros/MacroTagParser.cs | 2 +- src/Umbraco.Web.UI.Client/src/common/services/macro.service.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Macros/MacroTagParser.cs b/src/Umbraco.Core/Macros/MacroTagParser.cs index 0ed7c5bad2..7193bc2ba4 100644 --- a/src/Umbraco.Core/Macros/MacroTagParser.cs +++ b/src/Umbraco.Core/Macros/MacroTagParser.cs @@ -12,7 +12,7 @@ namespace Umbraco.Core.Macros internal class MacroTagParser { private static readonly Regex MacroRteContent = new Regex(@"()", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); - private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO (?:.+)?macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); + private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO (?:.+?)?macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); /// /// This formats the persisted string to something useful for the rte so that the macro renders properly since we diff --git a/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js b/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js index 172c0836e7..f0f1649bbe 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js @@ -15,7 +15,7 @@ function macroService() { //This regex will match an alias of anything except characters that are quotes or new lines (for legacy reasons, when new macros are created // their aliases are cleaned an invalid chars are stripped) - var expression = /(<\?UMBRACO_MACRO (?:.+)?macroAlias=["']([^\"\'\n\r]+?)["'][\s\S]+?)(\/>|>.*?<\/\?UMBRACO_MACRO>)/i; + var expression = /(<\?UMBRACO_MACRO (?:.+?)?macroAlias=["']([^\"\'\n\r]+?)["'][\s\S]+?)(\/>|>.*?<\/\?UMBRACO_MACRO>)/i; var match = expression.exec(syntax); if (!match || match.length < 3) { return null; From a979f7ab12fdffe907c5d2964809103361b23ed5 Mon Sep 17 00:00:00 2001 From: Tom Rankin Date: Wed, 10 Jun 2015 11:20:51 -0500 Subject: [PATCH 2/3] Missed a test case when the properties were not in front of MacroAlias --- src/Umbraco.Core/Macros/MacroTagParser.cs | 2 +- src/Umbraco.Web.UI.Client/src/common/services/macro.service.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Macros/MacroTagParser.cs b/src/Umbraco.Core/Macros/MacroTagParser.cs index 7193bc2ba4..7da2e1d3fc 100644 --- a/src/Umbraco.Core/Macros/MacroTagParser.cs +++ b/src/Umbraco.Core/Macros/MacroTagParser.cs @@ -12,7 +12,7 @@ namespace Umbraco.Core.Macros internal class MacroTagParser { private static readonly Regex MacroRteContent = new Regex(@"()", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); - private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO (?:.+?)?macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); + private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO(?:.+?)?macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); /// /// This formats the persisted string to something useful for the rte so that the macro renders properly since we diff --git a/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js b/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js index f0f1649bbe..f36b932d5f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js @@ -15,7 +15,7 @@ function macroService() { //This regex will match an alias of anything except characters that are quotes or new lines (for legacy reasons, when new macros are created // their aliases are cleaned an invalid chars are stripped) - var expression = /(<\?UMBRACO_MACRO (?:.+?)?macroAlias=["']([^\"\'\n\r]+?)["'][\s\S]+?)(\/>|>.*?<\/\?UMBRACO_MACRO>)/i; + var expression = /(<\?UMBRACO_MACRO(?:.+?)?macroAlias=["']([^\"\'\n\r]+?)["'][\s\S]+?)(\/>|>.*?<\/\?UMBRACO_MACRO>)/i; var match = expression.exec(syntax); if (!match || match.length < 3) { return null; From 6be183f11b011008ac9aff552bd324d31d891521 Mon Sep 17 00:00:00 2001 From: Tom Rankin Date: Wed, 10 Jun 2015 12:53:32 -0500 Subject: [PATCH 3/3] FIX U4-6687: Adding tests for RTE Macro parsing when macroAlias is the first attribute and a new test for multiple Macros of various format. --- src/Umbraco.Tests/Macros/MacroParserTests.cs | 68 ++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/Umbraco.Tests/Macros/MacroParserTests.cs b/src/Umbraco.Tests/Macros/MacroParserTests.cs index 08477a1649..6a6a6d6ffc 100644 --- a/src/Umbraco.Tests/Macros/MacroParserTests.cs +++ b/src/Umbraco.Tests/Macros/MacroParserTests.cs @@ -132,6 +132,74 @@ namespace Umbraco.Tests.Macros

asdfasdf

".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); } + [Test] + public void Format_RTE_Data_For_Editor_With_Params_When_MacroAlias_Is_First() + { + + var content = @"

asdfasdf

+

asdfsadf

+ +

asdfasdf

"; + var result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary() { { "test1", "value1" }, { "test2", "value2" } }); + + // Assert.AreEqual(@"

asdfasdf

+ //

asdfsadf

+ //
+ // + //Macro alias: Map
+ //

asdfasdf

".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); + Assert.AreEqual(@"

asdfasdf

+

asdfsadf

+
+ +Macro alias: Map
+

asdfasdf

".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); + } + + [Test] + public void Format_RTE_Data_For_Editor_With_Params_When_Multiple_Macros() + { + var content = @"

asdfasdf

+

asdfsadf

+ +

asdfsadf

+ +

asdfsadf

+ +

asdfasdf

"; + var result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary() { { "test1", "value1" }, { "test2", "value2" } }); + + // Assert.AreEqual(@"

asdfasdf

+ //

asdfsadf

+ //
+ // + //Macro alias: Map
+ //

asdfsadf

+ //
+ // + //Macro alias: Map
+ //

asdfsadf

+ //
+ // + //Macro alias: Map
+ //

asdfasdf

".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); + + Assert.AreEqual(@"

asdfasdf

+

asdfsadf

+
+ +Macro alias: Map
+

asdfsadf

+
+ +Macro alias: Map
+

asdfsadf

+
+ +Macro alias: Map
+

asdfasdf

".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); + } + [Test] public void Format_RTE_Data_For_Editor_With_Params_Closing_Tag() {