This is an automated email from the ASF dual-hosted git repository. danwatford pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push: new 9597ddce15 Fixed: Support title attribute on hyperlinks (OFBIZ-12697) 9597ddce15 is described below commit 9597ddce15d106ffd34cae00c164fd519e179e77 Author: Florian Motteau <florian.mott...@nereide.fr> AuthorDate: Thu Sep 29 18:01:12 2022 +0200 Fixed: Support title attribute on hyperlinks (OFBIZ-12697) --- .../java/org/apache/ofbiz/widget/WidgetWorker.java | 17 +++++++- .../ofbiz/widget/model/CommonWidgetModels.java | 8 ++++ .../apache/ofbiz/widget/model/ModelFormField.java | 8 ++++ .../widget/renderer/macro/MacroFormRenderer.java | 28 +++++++----- .../macro/RenderableFtlFormElementsBuilder.java | 22 +++++----- .../renderer/macro/MacroFormRendererTest.java | 51 ++++++++++++++++++++++ .../template/macro/HtmlFormMacroLibrary.ftl | 6 +-- 7 files changed, 113 insertions(+), 27 deletions(-) diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/WidgetWorker.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/WidgetWorker.java index af342107d2..858c3a6b76 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/WidgetWorker.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/WidgetWorker.java @@ -140,7 +140,6 @@ public final class WidgetWorker { final String href = "javascript:document." + makeLinkHiddenFormName(context, modelFormField) + ".submit()"; anchorElement.attr("href", href); - if (isNotEmpty(modelFormField.getEvent()) && isNotEmpty(modelFormField.getAction(context))) { anchorElement.attr(modelFormField.getEvent(), modelFormField.getAction(context)); } @@ -149,6 +148,22 @@ public final class WidgetWorker { anchorElement.attr("onclick", "return confirm('" + confirmation + "')"); } + int size = 0; + String title = request.getAttribute("title").toString(); + if (UtilValidate.isNotEmpty(request.getAttribute("descriptionSize"))) { + size = Integer.parseInt(request.getAttribute("descriptionSize").toString()); + } + + // if description is truncated, always use description as title + if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) { + title = description; + description = description.substring(0, size) + "…"; + } + + if (isNotEmpty(title)) { + anchorElement.attr("title", title); + } + anchorElement.text(description); if (isNotEmpty(request.getAttribute("image"))) { diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java index 94f3695fc6..258d6a9e59 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java @@ -332,6 +332,7 @@ public final class CommonWidgetModels { private final boolean encode; private final boolean fullPath; private final FlexibleStringExpander idExdr; + private final String title; private final Image image; private final String linkType; // anchor or hidden form private final FlexibleStringExpander nameExdr; @@ -354,6 +355,7 @@ public final class CommonWidgetModels { public Link(Element linkElement) { this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text")); this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id")); + this.title = linkElement.getAttribute("title"); this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style")); this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name")); this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target")); @@ -436,6 +438,7 @@ public final class CommonWidgetModels { this.encode = false; this.fullPath = false; this.idExdr = FlexibleStringExpander.getInstance(""); + this.title = ""; this.image = null; this.linkType = ""; this.nameExdr = FlexibleStringExpander.getInstance(""); @@ -462,6 +465,7 @@ public final class CommonWidgetModels { this.encode = false; this.fullPath = false; this.idExdr = FlexibleStringExpander.getInstance(""); + this.title = ""; this.image = null; this.linkType = ""; this.nameExdr = FlexibleStringExpander.getInstance(""); @@ -520,6 +524,10 @@ public final class CommonWidgetModels { return idExdr; } + public String getTitle() { + return this.title; + } + public Image getImage() { return this.image; } diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelFormField.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelFormField.java index c1d16e3f26..093f6c0a43 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelFormField.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelFormField.java @@ -3018,6 +3018,14 @@ public final class ModelFormField { return link.getIdExdr(); } + /** + * Gets title. + * @return the title + */ + public String getTitle() { + return link.getTitle(); + } + /** * Gets image. * @return the image diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java index 38fb5ebfdd..5e5f4f4276 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java @@ -215,6 +215,7 @@ public final class MacroFormRenderer implements FormStringRenderer { this.request.setAttribute("imageTitle", encodedImageTitle); this.request.setAttribute("descriptionSize", hyperlinkField.getSize()); this.request.setAttribute("id", modelFormField.getCurrentContainerId(context)); + this.request.setAttribute("title", hyperlinkField.getTitle()); this.request.setAttribute("width", hyperlinkField.getWidth()); this.request.setAttribute("height", hyperlinkField.getHeight()); makeHyperlinkByType(writer, hyperlinkField.getLinkType(), modelFormField.getWidgetStyle(), hyperlinkField.getUrlMode(), @@ -2971,12 +2972,13 @@ public final class MacroFormRenderer implements FormStringRenderer { String event = ""; String action = ""; String imgSrc = ""; + String imgTitle = ""; String alt = ""; String id = ""; String uniqueItemName = ""; String width = ""; String height = ""; - String imgTitle = ""; + String title = ""; String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField); if (UtilValidate.isNotEmpty(modelFormField.getEvent()) && UtilValidate.isNotEmpty(modelFormField.getAction(context))) { event = modelFormField.getEvent(); @@ -2985,22 +2987,22 @@ public final class MacroFormRenderer implements FormStringRenderer { if (UtilValidate.isNotEmpty(request.getAttribute("image"))) { imgSrc = request.getAttribute("image").toString(); } - if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) { - alt = request.getAttribute("alternate").toString(); - } if (UtilValidate.isNotEmpty(request.getAttribute("imageTitle"))) { imgTitle = request.getAttribute("imageTitle").toString(); } - Integer size = Integer.valueOf("0"); + if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) { + alt = request.getAttribute("alternate").toString(); + } + int size = 0; if (UtilValidate.isNotEmpty(request.getAttribute("descriptionSize"))) { - size = Integer.valueOf(request.getAttribute("descriptionSize").toString()); + size = Integer.parseInt(request.getAttribute("descriptionSize").toString()); } + // if description is truncated, always use description as title if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) { - imgTitle = description; - description = description.substring(0, size - 8) + "..." + description.substring(description.length() - 5); - } - if (UtilValidate.isEmpty(imgTitle)) { - imgTitle = modelFormField.getTitle(context); + title = description; + description = description.substring(0, size) + "…"; + } else if (UtilValidate.isNotEmpty(request.getAttribute("title"))) { + title = request.getAttribute("title").toString(); } if (UtilValidate.isNotEmpty(request.getAttribute("id"))) { id = request.getAttribute("id").toString(); @@ -3037,8 +3039,10 @@ public final class MacroFormRenderer implements FormStringRenderer { sr.append(action); sr.append("\" imgSrc=\""); sr.append(imgSrc); - sr.append("\" title=\""); + sr.append("\" imgTitle=\""); sr.append(imgTitle); + sr.append("\" title=\""); + sr.append(title); sr.append("\" alternate=\""); sr.append(alt); sr.append("\" targetParameters=\""); diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java index 5bde105eea..4a39a1b675 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilder.java @@ -414,12 +414,13 @@ public final class RenderableFtlFormElementsBuilder { String event = ""; String action = ""; String imgSrc = ""; + String imgTitle = ""; String alt = ""; String id = ""; String uniqueItemName = ""; String width = ""; String height = ""; - String imgTitle = ""; + String title = ""; String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField); if (UtilValidate.isNotEmpty(modelFormField.getEvent()) && UtilValidate.isNotEmpty(modelFormField.getAction(context))) { @@ -429,23 +430,21 @@ public final class RenderableFtlFormElementsBuilder { if (UtilValidate.isNotEmpty(request.getAttribute("image"))) { imgSrc = request.getAttribute("image").toString(); } - if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) { - alt = request.getAttribute("alternate").toString(); - } if (UtilValidate.isNotEmpty(request.getAttribute("imageTitle"))) { imgTitle = request.getAttribute("imageTitle").toString(); } + if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) { + alt = request.getAttribute("alternate").toString(); + } Integer size = Integer.valueOf("0"); if (UtilValidate.isNotEmpty(request.getAttribute("descriptionSize"))) { size = Integer.valueOf(request.getAttribute("descriptionSize").toString()); } if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) { - imgTitle = description; - description = description.substring(0, size - 8) + "..." - + description.substring(description.length() - 5); - } - if (UtilValidate.isEmpty(imgTitle)) { - imgTitle = modelFormField.getTitle(context); + title = description; + description = description.substring(0, size) + "…"; + } else if (UtilValidate.isNotEmpty(request.getAttribute("title"))) { + title = request.getAttribute("title").toString(); } if (UtilValidate.isNotEmpty(request.getAttribute("id"))) { id = request.getAttribute("id").toString(); @@ -463,7 +462,8 @@ public final class RenderableFtlFormElementsBuilder { .stringParameter("event", event) .stringParameter("action", action) .stringParameter("imgSrc", imgSrc) - .stringParameter("title", imgTitle) + .stringParameter("imgTitle", imgTitle) + .stringParameter("title", title) .stringParameter("alternate", alt) .mapParameter("targetParameters", parameterMap) .stringParameter("linkUrl", linkUrl.toString()) diff --git a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRendererTest.java b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRendererTest.java index a30fb15b01..03daf5ddf9 100644 --- a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRendererTest.java +++ b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRendererTest.java @@ -887,6 +887,57 @@ public class MacroFormRendererTest { "linkUrl", new FreemarkerRawString(linkFromQbeString))); } + @Test + public void hyperlinkFieldMacroRenderedTitleNotTruncated(@Mocked ModelFormField.HyperlinkField hyperlinkField) throws IOException { + final String description = "DESCRIPTION"; + final String title = "TITLE"; + + new Expectations() { + { + hyperlinkField.getDescription(withNotNull()); result = description; + hyperlinkField.getTarget(withNotNull()); result = "#"; + request.getAttribute("title"); result = title; + } + }; + + macroFormRenderer.renderHyperlinkField(appendable, new HashMap<>(), hyperlinkField); + assertAndGetMacroString("makeHyperlinkString", ImmutableMap.of("description", description, "title", title)); + } + + @Test + public void hyperlinkFieldMacroRenderedTruncatedNoTitle(@Mocked ModelFormField.HyperlinkField hyperlinkField) throws IOException { + final String description = "DESCRIPTION"; + + new Expectations() { + { + hyperlinkField.getDescription(withNotNull()); result = description; + hyperlinkField.getTarget(withNotNull()); result = "#"; + request.getAttribute("descriptionSize"); result = 5; + } + }; + + macroFormRenderer.renderHyperlinkField(appendable, new HashMap<>(), hyperlinkField); + assertAndGetMacroString("makeHyperlinkString", ImmutableMap.of("description", "DESCR…", "title", description)); + } + + @Test + public void hyperlinkFieldMacroRenderedTruncatedWithTitle(@Mocked ModelFormField.HyperlinkField hyperlinkField) throws IOException { + final String description = "DESCRIPTION"; + final String title = "TITLE"; + + new Expectations() { + { + hyperlinkField.getDescription(withNotNull()); result = description; + hyperlinkField.getTarget(withNotNull()); result = "#"; + hyperlinkField.getTitle(); result = title; + request.getAttribute("descriptionSize"); result = 5; + } + }; + + macroFormRenderer.renderHyperlinkField(appendable, new HashMap<>(), hyperlinkField); + assertAndGetMacroString("makeHyperlinkString", ImmutableMap.of("description", "DESCR…", "title", description)); + } + private String assertAndGetMacroString(final String expectedName) { return assertAndGetMacroString(expectedName, ImmutableMap.of()); } diff --git a/themes/common-theme/template/macro/HtmlFormMacroLibrary.ftl b/themes/common-theme/template/macro/HtmlFormMacroLibrary.ftl index fc68825029..201863cf11 100644 --- a/themes/common-theme/template/macro/HtmlFormMacroLibrary.ftl +++ b/themes/common-theme/template/macro/HtmlFormMacroLibrary.ftl @@ -735,7 +735,7 @@ Parameter: delegatorName, String, optional - name of the delegator in context. <#if confirmation?has_content> onclick="return confirm('${confirmation?js_string}')"</#if>> <#if imgSrc?has_content><img src="${imgSrc}" alt=""/></#if>${description}</a> </#macro> -<#macro makeHyperlinkString hiddenFormName imgSrc title alternate linkUrl description linkStyle="" event="" action="" targetParameters="" targetWindow="" confirmation="" uniqueItemName="" height="" width="" id=""> +<#macro makeHyperlinkString hiddenFormName imgSrc imgTitle title alternate linkUrl description linkStyle="" event="" action="" targetParameters="" targetWindow="" confirmation="" uniqueItemName="" height="" width="" id=""> <#if uniqueItemName?has_content> <#local params = "{"presentation": "layer""> <#if targetParameters?has_content && !targetParameters?is_hash> @@ -760,7 +760,7 @@ Parameter: delegatorName, String, optional - name of the delegator in context. <#if action?has_content && event?has_content> ${event}="${action}"</#if> <#if confirmation?has_content> data-confirm-message="${confirmation}"</#if> <#if id?has_content> id="${id}"</#if> - <#if imgSrc?length == 0 && title?has_content> title="${title}"</#if>> - <#if imgSrc?has_content><img src="${imgSrc}" alt="${alternate}" title="${title}"/></#if>${description?html}</a> + <#if title?has_content> title="${title}"</#if>> + <#if imgSrc?has_content><img src="${imgSrc}" alt="${alternate}" <#if imgTitle?has_content>title="${imgTitle}"</#if>/></#if>${description?html}</a> </#if> </#macro>