You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by da...@apache.org on 2022/12/12 13:48:46 UTC

[ofbiz-framework] branch release22.01 updated: Fixed: Support title attribute on hyperlinks (OFBIZ-12697)

This is an automated email from the ASF dual-hosted git repository.

danwatford pushed a commit to branch release22.01
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/release22.01 by this push:
     new b6e202b0ab Fixed: Support title attribute on hyperlinks (OFBIZ-12697)
b6e202b0ab is described below

commit b6e202b0ab75a8511ad29c3a89d0f2f6cc574ae5
Author: Daniel Watford <da...@watfordconsulting.com>
AuthorDate: Mon Dec 12 13:46:42 2022 +0000

    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 b05c6314b0..0f1779d706 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
@@ -330,6 +330,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;
@@ -352,6 +353,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"));
@@ -426,6 +428,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("");
@@ -452,6 +455,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("");
@@ -510,6 +514,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 6b13c4d42a..21b08ca383 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 = "{&quot;presentation&quot;: &quot;layer&quot;">
         <#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>