You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by me...@apache.org on 2022/09/23 21:13:38 UTC

[myfaces] branch main updated: MYFACES-4456: Add type to HtmlInputText (#318)

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

melloware pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/main by this push:
     new 47ecc3c62 MYFACES-4456: Add type to HtmlInputText (#318)
47ecc3c62 is described below

commit 47ecc3c62b0828659ca1ac0d35d703a796c0cfdf
Author: Melloware <me...@gmail.com>
AuthorDate: Fri Sep 23 17:13:34 2022 -0400

    MYFACES-4456: Add type to HtmlInputText (#318)
---
 .../faces/component/html/_HtmlInputText.java       |  2 +-
 .../faces/component/html/_TypeProperty.java        | 34 +++++++++++
 .../renderkit/html/base/HtmlTextRendererBase.java  | 66 ++++++++++++++++++----
 .../renderkit/html/HtmlTextRendererTest.java       | 27 ++++++++-
 4 files changed, 117 insertions(+), 12 deletions(-)

diff --git a/api/src/main/java/jakarta/faces/component/html/_HtmlInputText.java b/api/src/main/java/jakarta/faces/component/html/_HtmlInputText.java
index 11fb9010f..754a8d037 100644
--- a/api/src/main/java/jakarta/faces/component/html/_HtmlInputText.java
+++ b/api/src/main/java/jakarta/faces/component/html/_HtmlInputText.java
@@ -38,7 +38,7 @@ abstract class _HtmlInputText extends UIInput implements _AccesskeyProperty,
     _AltProperty, _UniversalProperties, _DisabledReadonlyProperties,
     _FocusBlurProperties, _ChangeProperty, _SelectProperty, 
     _EventProperties, _StyleProperties, _TabindexProperty, _LabelProperty, 
-    _RoleProperty
+    _RoleProperty, _TypeProperty
 {
 
     static public final String COMPONENT_FAMILY = "jakarta.faces.Input";
diff --git a/api/src/main/java/jakarta/faces/component/html/_TypeProperty.java b/api/src/main/java/jakarta/faces/component/html/_TypeProperty.java
new file mode 100644
index 000000000..81f85f95c
--- /dev/null
+++ b/api/src/main/java/jakarta/faces/component/html/_TypeProperty.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package jakarta.faces.component.html;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
+
+interface _TypeProperty
+{
+    /**
+     * HTML: How an input works varies considerably depending on the value of its type attribute, 
+     * hence the different types are covered in their own separate reference pages. If this attribute 
+     * is not specified, the default type adopted is text.
+     * 
+     */
+    @JSFProperty
+    public abstract String getType();
+
+}
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/base/HtmlTextRendererBase.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/base/HtmlTextRendererBase.java
index 4c5e4b037..9e8f2aba3 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/base/HtmlTextRendererBase.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/base/HtmlTextRendererBase.java
@@ -18,16 +18,17 @@
  */
 package org.apache.myfaces.renderkit.html.base;
 
-import org.apache.myfaces.renderkit.html.util.HtmlRendererUtils;
-import org.apache.myfaces.renderkit.html.util.ClientBehaviorRendererUtils;
-import org.apache.myfaces.renderkit.html.util.CommonHtmlAttributesUtil;
-import org.apache.myfaces.renderkit.html.util.CommonHtmlEventsUtil;
+
 import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import jakarta.faces.application.FacesMessage;
+import jakarta.faces.application.ProjectStage;
 import jakarta.faces.component.UIComponent;
 import jakarta.faces.component.UIInput;
 import jakarta.faces.component.UIOutput;
@@ -38,13 +39,18 @@ import jakarta.faces.component.html.HtmlOutputText;
 import jakarta.faces.context.FacesContext;
 import jakarta.faces.context.ResponseWriter;
 import jakarta.faces.convert.ConverterException;
+
 import org.apache.myfaces.core.api.shared.AttributeUtils;
 import org.apache.myfaces.core.api.shared.CommonHtmlAttributes;
-
 import org.apache.myfaces.renderkit.RendererUtils;
-import org.apache.myfaces.renderkit.html.util.ResourceUtils;
-import org.apache.myfaces.renderkit.html.util.HTML;
+import org.apache.myfaces.renderkit.html.util.ClientBehaviorRendererUtils;
+import org.apache.myfaces.renderkit.html.util.CommonHtmlAttributesUtil;
+import org.apache.myfaces.renderkit.html.util.CommonHtmlEventsUtil;
 import org.apache.myfaces.renderkit.html.util.ComponentAttrs;
+import org.apache.myfaces.renderkit.html.util.HTML;
+import org.apache.myfaces.renderkit.html.util.HtmlRendererUtils;
+import org.apache.myfaces.renderkit.html.util.ResourceUtils;
+import org.apache.myfaces.util.lang.StringUtils;
 
 public class HtmlTextRendererBase
         extends HtmlRenderer
@@ -53,6 +59,24 @@ public class HtmlTextRendererBase
 
     private static final String AUTOCOMPLETE_VALUE_OFF = "off";
 
+    private static final Map<String, String> RECOMMENDED_COMPONENTS_BY_DISCOMMENDED_TYPES = 
+        mapRecommendedComponentsByDiscommendedTypes();
+
+    private static Map<String, String> mapRecommendedComponentsByDiscommendedTypes()
+    {
+        Map<String, String> map = new HashMap<>(9);
+        map.put("hidden", "<h:inputHidden>");
+        map.put("password", "<h:inputSecret>");
+        map.put("checkbox", "<h:selectBooleanCheckbox> or <h:selectManyCheckbox>");
+        map.put("radio", "<h:selectOneRadio>");
+        map.put("file", "<h:inputFile>");
+        map.put("submit", "<h:commandButton>");
+        map.put("image", "<h:commandButton type=\"image\">");
+        map.put("reset", "<h:commandButton type=\"reset\">");
+        map.put("button", "<h:commandButton type=\"button\"> or <h:button>");
+        return Collections.unmodifiableMap(map);
+    }
+
     @Override
     public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException
     {
@@ -214,7 +238,7 @@ public class HtmlTextRendererBase
         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
         
         //allow extending classes to modify html input element's type
-        String inputHtmlType = getInputHtmlType(component);
+        String inputHtmlType = getInputHtmlType(facesContext, component);
         writer.writeAttribute(HTML.TYPE_ATTR, inputHtmlType, null);
 
         renderValue(facesContext, component, writer);
@@ -401,9 +425,31 @@ public class HtmlTextRendererBase
     /**
      * Returns the HTML type attribute of HTML input element, which is being rendered.
      */
-    protected String getInputHtmlType(UIComponent component)
+    protected String getInputHtmlType(FacesContext context, UIComponent component)
     {
+        String type = null;
+        if (component instanceof HtmlInputText)
+        {
+            type = ((HtmlInputText)component).getType();
+        }
+        if (StringUtils.isEmpty(type))
+        {
+            type = HTML.INPUT_TYPE_TEXT;
+        }
+        type = type.trim().toLowerCase();
+        if (context.isProjectStage(ProjectStage.Development))
+        {
+            String recommendedComponent = RECOMMENDED_COMPONENTS_BY_DISCOMMENDED_TYPES.get(type);
+
+            if (recommendedComponent != null)
+            {
+                String message = "<h:inputText type=\"" + type + "\"> is discommended, you should instead use " +
+                    recommendedComponent;
+                context.addMessage(component.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_WARN,
+                    message, message));
+            }
+        }
         //subclasses may act on properties of the component
-        return HTML.INPUT_TYPE_TEXT;
+        return type;
     }
 }
diff --git a/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTextRendererTest.java b/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTextRendererTest.java
index a557835be..f4fe6dadf 100644
--- a/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTextRendererTest.java
+++ b/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTextRendererTest.java
@@ -102,6 +102,31 @@ public class HtmlTextRendererTest extends AbstractJsfTestCase
         Assert.assertEquals("<span class=\"myStyleClass\">Output</span>", output);
         Assert.assertNotSame("Output", output);
     }
+
+    public void testInputDefaultTypeAttr() throws IOException
+    {
+        inputText.encodeBegin(facesContext);
+        inputText.encodeEnd(facesContext);
+        facesContext.renderResponse();
+
+        String output = writer.getWriter().toString();
+        Assert.assertEquals("<input id=\"j_id__v_0\" name=\"j_id__v_0\" type=\"text\" value=\"\"/>", output);
+        Assert.assertNotSame("Output", output);
+    }
+
+    public void testInputTypeAttr() throws IOException
+    {
+        inputText.setType("tel");
+
+        inputText.encodeBegin(facesContext);
+        inputText.encodeEnd(facesContext);
+        facesContext.renderResponse();
+
+        String output = writer.getWriter().toString();
+        Assert.assertEquals("<input id=\"j_id__v_0\" name=\"j_id__v_0\" type=\"tel\" value=\"\"/>", output);
+        Assert.assertNotSame("Output", output);
+    }
+
     
     /**
      * Don't add span over escape
@@ -121,7 +146,7 @@ public class HtmlTextRendererTest extends AbstractJsfTestCase
         Assert.assertEquals("Output", output);
     }
 
-    public void testHtmlPropertyPassTru() throws Exception
+    public void testHtmlPropertyPassThru() throws Exception
     {
         HtmlRenderedAttr[] attrs = HtmlCheckAttributesUtil.generateBasicAttrs();