Add support for Inline Macro- To enable: Add a Macro Parameter called: enableInlineMacro with Umbraco.TrueFalse set to True (value:"1") (#13628)
- Custom Macro Parameter with true as default value can be created for those prefering that in their project Co-authored-by: Jo Mehmet Sollihagen <jomehmet@solsol.no>
This commit is contained in:
@@ -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";
|
||||
// <div class="umb-macro-holder myMacro mceNonEditable">
|
||||
var alias = match.Groups[2].Value;
|
||||
var sb = new StringBuilder("<div class=\"umb-macro-holder ");
|
||||
|
||||
var sb = new StringBuilder($"<{macroElementType} class=\"umb-macro-holder ");
|
||||
if (macroCanBeInlinedInParagraph)
|
||||
{
|
||||
sb.Append("inlined-macro ");
|
||||
}
|
||||
// sb.Append(alias.ToSafeAlias());
|
||||
sb.Append("mceNonEditable\"");
|
||||
foreach (KeyValuePair<string, string> htmlAttribute in htmlAttributes)
|
||||
@@ -64,7 +69,7 @@ public class MacroTagParser
|
||||
sb.Append("Macro alias: ");
|
||||
sb.Append("<strong>");
|
||||
sb.Append(alias);
|
||||
sb.Append("</strong></ins></div>");
|
||||
sb.Append($"</strong></ins></{macroElementType}>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = "<!-- " + macroObject.syntax + " -->";
|
||||
//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 + '<ins>Macro alias: <strong>' + macroObject.macroAlias + '</strong></ins>');
|
||||
|
||||
//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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -396,4 +396,25 @@ asdfsdf
|
||||
@"<?UMBRACO_MACRO macroAlias=""Test"" content=""1089"" textArea=""asdfasdf"" title="""" bool=""0"" number="""" contentType="""" multiContentType="""" multiProperties="""" properties="""" tabs="""" multiTabs="""" />",
|
||||
result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Format_RTE_WhenMacroContainsParameter_EnableInlineMacro_WithValue_1_ItShouldBeInASpan()
|
||||
{
|
||||
var content = @"<p>asdfasdf</p>
|
||||
<p>asdfsadf</p>
|
||||
<?UMBRACO_MACRO macroAlias=""My.Map.isCool eh[boy!]"" test1=""value1"" enableInlineMacro=""1""/>
|
||||
<p>asdfasdf</p>";
|
||||
var result = MacroTagParser.FormatRichTextPersistedDataForEditor(
|
||||
content,
|
||||
new Dictionary<string, string> { { "test1", "value1" }, { "enableInlineMacro", "1"} });
|
||||
|
||||
Assert.AreEqual(
|
||||
@"<p>asdfasdf</p>
|
||||
<p>asdfsadf</p>
|
||||
<span class=""umb-macro-holder inlined-macro mceNonEditable"" test1=""value1"" enableInlineMacro=""1"">
|
||||
<!-- <?UMBRACO_MACRO macroAlias=""My.Map.isCool eh[boy!]"" test1=""value1"" enableInlineMacro=""1"" /> -->
|
||||
<ins>Macro alias: <strong>My.Map.isCool eh[boy!]</strong></ins></span>
|
||||
<p>asdfasdf</p>".StripNewLines(),
|
||||
result.StripNewLines());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user