diff --git a/src/Umbraco.Infrastructure/Macros/MacroTagParser.cs b/src/Umbraco.Infrastructure/Macros/MacroTagParser.cs index 07109729b6..08559f786a 100644 --- a/src/Umbraco.Infrastructure/Macros/MacroTagParser.cs +++ b/src/Umbraco.Infrastructure/Macros/MacroTagParser.cs @@ -40,10 +40,15 @@ public class MacroTagParser { if (match.Groups.Count >= 3) { + var macroCanBeInlinedInParagraph = match.Value?.Contains("enableInlineMacro=\"1\"") ?? false; + var macroElementType = macroCanBeInlinedInParagraph ? "span" : "div"; //
var alias = match.Groups[2].Value; - var sb = new StringBuilder("
htmlAttribute in htmlAttributes) @@ -64,7 +69,7 @@ public class MacroTagParser sb.Append("Macro alias: "); sb.Append(""); sb.Append(alias); - sb.Append("
"); + sb.Append($""); return sb.ToString(); } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index ea284ee2ce..e23e712046 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -766,14 +766,20 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s } var e = $(element).closest(".umb-macro-holder"); + if (e.length > 0) { - if (e.get(0).parentNode.nodeName === "P") { + var macroHolder = e.get(0); + // In case of Inline Macro we don't need the be backward compliant + if(macroHolder.tagName === 'SPAN'){ + return macroHolder; + } + if (macroHolder.parentNode.nodeName === "P") { //now check if we're the only element if (element.parentNode.childNodes.length === 1) { - return e.get(0).parentNode; + return macroHolder.parentNode; } } - return e.get(0); + return macroHolder; } return null; } @@ -830,35 +836,37 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s var macroSyntaxComment = ""; //create an id class for this element so we can re-select it after inserting var uniqueId = "umb-macro-" + editor.dom.uniqueId(); - var macroDiv = editor.dom.create('div', + var isInlined = macroObject.macroParamsDictionary["enableInlineMacro"] === "1"; + var macroElementType = isInlined ? 'span' : 'div'; + var macroElement = editor.dom.create(macroElementType, { - 'class': 'umb-macro-holder ' + macroObject.macroAlias + " " + uniqueId + ' mceNonEditable', + 'class': 'umb-macro-holder ' + macroObject.macroAlias + " " + uniqueId + ' mceNonEditable' + (isInlined ? ' inlined-macro' : ''), 'contenteditable': 'false' }, macroSyntaxComment + 'Macro alias: ' + macroObject.macroAlias + ''); //if there's an activeMacroElement then replace it, otherwise set the contents of the selected node if (activeMacroElement) { - activeMacroElement.replaceWith(macroDiv); //directly replaces the html node + activeMacroElement.replaceWith(macroElement); //directly replaces the html node } else { - editor.selection.setNode(macroDiv); + editor.selection.setNode(macroElement); } - var $macroDiv = $(editor.dom.select("div.umb-macro-holder." + uniqueId)); + var $macroElement = $(editor.dom.select(".umb-macro-holder." + uniqueId)); editor.setDirty(true); //async load the macro content - this.loadMacroContent($macroDiv, macroObject, editor); + this.loadMacroContent($macroElement, macroObject, editor); }, /** loads in the macro content async from the server */ - loadMacroContent: function ($macroDiv, macroData, editor) { + loadMacroContent: function ($macroElement, macroData, editor) { //if we don't have the macroData, then we'll need to parse it from the macro div if (!macroData) { - var contents = $macroDiv.contents(); + var contents = $macroElement.contents(); var comment = _.find(contents, function (item) { return item.nodeType === 8; }); @@ -870,15 +878,15 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s macroData = parsed; } - var $ins = $macroDiv.find("ins"); + var $ins = $macroElement.find("ins"); //show the throbber - $macroDiv.addClass("loading"); + $macroElement.addClass("loading"); // Add the contenteditable="false" attribute // As just the CSS class of .mceNonEditable is not working by itself?! // TODO: At later date - use TinyMCE editor DOM manipulation as opposed to jQuery - $macroDiv.attr("contenteditable", "false"); + $macroElement.attr("contenteditable", "false"); var contentId = $routeParams.id; @@ -887,7 +895,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s macroResource.getMacroResultAsHtmlForEditor(macroData.macroAlias, contentId, macroData.macroParamsDictionary) .then(function (htmlResult) { - $macroDiv.removeClass("loading"); + $macroElement.removeClass("loading"); htmlResult = htmlResult.trim(); if (htmlResult !== "") { var wasDirty = editor.isDirty(); diff --git a/src/Umbraco.Web.UI.Client/src/less/rte-content.less b/src/Umbraco.Web.UI.Client/src/less/rte-content.less index 3fe4e52f92..f19b1edb98 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte-content.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte-content.less @@ -4,9 +4,13 @@ .mce-content-body .umb-macro-holder { border: 3px dotted @pinkLight; padding: 7px; - display: block; margin: 3px; } +.mce-content-body .umb-macro-holder.inlined-macro { + border: 1px dotted @pinkLight; + padding: 1px; + margin: 0px; +} .umb-rte .mce-content-body .umb-macro-holder.loading { diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs index bbfcf2103e..63300eaa1b 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs @@ -396,4 +396,25 @@ asdfsdf @"", result); } + + [Test] + public void Format_RTE_WhenMacroContainsParameter_EnableInlineMacro_WithValue_1_ItShouldBeInASpan() + { + var content = @"

asdfasdf

+

asdfsadf

+ +

asdfasdf

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

asdfasdf

+

asdfsadf

+ + +Macro alias: My.Map.isCool eh[boy!] +

asdfasdf

".StripNewLines(), + result.StripNewLines()); + } }