You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ma...@apache.org on 2007/11/23 10:19:28 UTC

svn commit: r597611 - in /myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared: config/MyfacesConfig.java renderkit/html/HTML.java renderkit/html/HtmlLinkRendererBase.java

Author: manolito
Date: Fri Nov 23 01:19:27 2007
New Revision: 597611

URL: http://svn.apache.org/viewvc?rev=597611&view=rev
Log:
MYFACES-1774 HtmlLinkRenderer should output & instead of & as the url param separator within href attribute according to HTML Spec
(merged from JSF 1.1 trunk)

Modified:
    myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
    myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java
    myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java

Modified: myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java?rev=597611&r1=597610&r2=597611&view=diff
==============================================================================
--- myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java (original)
+++ myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java Fri Nov 23 01:19:27 2007
@@ -80,6 +80,9 @@
     private static final String  INIT_PARAM_RENDER_VIEWSTATE_ID = "org.apache.myfaces.RENDER_VIEWSTATE_ID";
     private static final boolean INIT_PARAM_RENDER_VIEWSTATE_ID_DEFAULT = true;
 
+    private static final String  INIT_PARAM_STRICT_XHTML_LINKS = "org.apache.myfaces.STRICT_XHTML_LINKS";
+    private static final boolean INIT_PARAM_STRICT_XHTML_LINKS_DEFAULT = true;
+
     private boolean _prettyHtml;
     private boolean _detectJavascript;
     private boolean _allowJavascript;
@@ -91,6 +94,7 @@
     private long _configRefreshPeriod;
     private boolean _viewStateJavascript;
     private boolean _renderViewStateId;
+    private boolean _strictXhtmlLinks;
 
 
     private static final boolean TOMAHAWK_AVAILABLE;
@@ -170,7 +174,9 @@
         myfacesConfig.setReadonlyAsDisabledForSelect(getBooleanInitParameter(extCtx, INIT_READONLY_AS_DISABLED_FOR_SELECT,
                                                                  INIT_READONLY_AS_DISABLED_FOR_SELECT_DEFAULT));
         myfacesConfig.setRenderViewStateId(getBooleanInitParameter(extCtx, INIT_PARAM_RENDER_VIEWSTATE_ID,
-                                                            INIT_PARAM_RENDER_VIEWSTATE_ID_DEFAULT));
+                                                                   INIT_PARAM_RENDER_VIEWSTATE_ID_DEFAULT));
+        myfacesConfig.setStrictXhtmlLinks(getBooleanInitParameter(extCtx, INIT_PARAM_STRICT_XHTML_LINKS,
+                                                                  INIT_PARAM_STRICT_XHTML_LINKS_DEFAULT));
 
         myfacesConfig.setConfigRefreshPeriod(getLongInitParameter(extCtx, INIT_PARAM_CONFIG_REFRESH_PERIOD,
                 INIT_PARAM_CONFIG_REFRESH_PERIOD_DEFAULT));
@@ -352,6 +358,28 @@
 
     public void setRenderViewStateId(boolean renderViewStateId) {
         _renderViewStateId = renderViewStateId;
+    }
+
+    /**
+     * <p>W3C recommends to use the "&amp;amp;" entity instead of a plain "&amp;" character within HTML.
+     * This also applies to attribute values and thus to the "href" attribute of &lt;a&gt; elements as well.
+     * Even more, when XHTML is used as output the usage of plain "&amp;" characters is forbidden and would lead to
+     * invalid XML code.
+     * Therefore, since version 1.1.6 MyFaces renders the correct "&amp;amp;" entity for links.</p>
+     * <p>The init parameter
+     * {@link #INIT_PARAM_STRICT_XHTML_LINKS} makes it possible to restore the old behaviour and to make MyFaces
+     * "bug compatible" to the Sun RI which renders plain "&amp;" chars in links as well.</p>
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3.2">HTML 4.01 Specification</a>
+     * @see <a href="http://issues.apache.org/jira/browse/MYFACES-1774">Jira: MYFACES-1774</a>
+     * @return true if ampersand characters ("&amp;") should be correctly rendered as "&amp;amp;" entities within link urls (=default),
+     *         false for old (XHTML incompatible) behaviour
+     */
+    public boolean isStrictXhtmlLinks() {
+        return _strictXhtmlLinks;
+    }
+
+    public void setStrictXhtmlLinks(boolean strictXhtmlLinks) {
+        _strictXhtmlLinks = strictXhtmlLinks;
     }
 
     public boolean isTomahawkAvailable()

Modified: myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java?rev=597611&r1=597610&r2=597611&view=diff
==============================================================================
--- myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java (original)
+++ myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java Fri Nov 23 01:19:27 2007
@@ -477,7 +477,7 @@
 
     String HREF_PATH_SEPARATOR = "/";
     String HREF_PATH_FROM_PARAM_SEPARATOR = "?";
-    String HREF_PARAM_SEPARATOR = "&";
+    //removed because wrong for XHTML and not used anyway: String HREF_PARAM_SEPARATOR = "&";
     String HREF_PARAM_NAME_FROM_VALUE_SEPARATOR = "=";
 
 }

Modified: myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java?rev=597611&r1=597610&r2=597611&view=diff
==============================================================================
--- myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java (original)
+++ myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java Fri Nov 23 01:19:27 2007
@@ -23,6 +23,7 @@
 import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 import org.apache.myfaces.shared.util._ComponentUtils;
+import org.apache.myfaces.shared.config.MyfacesConfig;
 
 import javax.faces.application.StateManager;
 import javax.faces.application.ViewHandler;
@@ -364,6 +365,9 @@
         String viewId = facesContext.getViewRoot().getViewId();
         String path = viewHandler.getActionURL(facesContext, viewId);
 
+        boolean strictXhtmlLinks
+                = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isStrictXhtmlLinks();
+
         StringBuffer hrefBuf = new StringBuffer(path);
 
         //add clientId parameter for decode
@@ -374,7 +378,11 @@
         }
         else
         {
-            hrefBuf.append('&');
+            if (strictXhtmlLinks) {
+                hrefBuf.append("&amp;");
+            } else {
+                hrefBuf.append('&');
+            }
         }
         String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(findNestingForm(component, facesContext));
         hrefBuf.append(hiddenFieldName);
@@ -383,13 +391,17 @@
 
         if (getChildCount(component) > 0)
         {
-            addChildParametersToHref(component, hrefBuf,
+            addChildParametersToHref(facesContext, component, hrefBuf,
                                      false, //not the first url parameter
                                      writer.getCharacterEncoding());
         }
 
         StateManager stateManager = facesContext.getApplication().getStateManager();
-        hrefBuf.append("&");
+        if (strictXhtmlLinks) {
+            hrefBuf.append("&amp;");
+        } else {
+            hrefBuf.append('&');
+        }
         if (stateManager.isSavingStateInClient(facesContext))
         {
             hrefBuf.append(URL_STATE_MARKER);
@@ -407,12 +419,15 @@
                                  null);
     }
 
-    private void addChildParametersToHref(UIComponent linkComponent,
+    private void addChildParametersToHref(FacesContext facesContext,
+                                          UIComponent linkComponent,
                                           StringBuffer hrefBuf,
                                           boolean firstParameter,
                                           String charEncoding)
             throws IOException
     {
+        boolean strictXhtmlLinks
+                = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isStrictXhtmlLinks();
         for (Iterator it = getChildren(linkComponent).iterator(); it.hasNext(); )
         {
             UIComponent child = (UIComponent)it.next();
@@ -420,8 +435,7 @@
             {
                 String name = ((UIParameter)child).getName();
                 Object value = ((UIParameter)child).getValue();
-
-                addParameterToHref(name, value, hrefBuf, firstParameter, charEncoding);
+                addParameterToHref(name, value, hrefBuf, firstParameter, charEncoding, strictXhtmlLinks);
                 firstParameter = false;
             }
         }
@@ -437,7 +451,7 @@
         if (getChildCount(output) > 0)
         {
             StringBuffer hrefBuf = new StringBuffer(href);
-            addChildParametersToHref(output, hrefBuf,
+            addChildParametersToHref(facesContext, output, hrefBuf,
                                      (href.indexOf('?') == -1), //first url parameter?
                                      writer.getCharacterEncoding());
             href = hrefBuf.toString();
@@ -471,15 +485,26 @@
         addHiddenCommandParameter(FacesContext.getCurrentInstance(), nestingForm, name);
     }
 
-    private static void addParameterToHref(String name, Object value, StringBuffer hrefBuf, boolean firstParameter, String charEncoding)
-            throws UnsupportedEncodingException
-    {
-        if (name == null)
-        {
+    private static void addParameterToHref(String name,
+                                           Object value,
+                                           StringBuffer hrefBuf,
+                                           boolean firstParameter,
+                                           String charEncoding,
+                                           boolean strictXhtmlLinks) throws UnsupportedEncodingException {
+        if (name == null) {
             throw new IllegalArgumentException("Unnamed parameter value not allowed within command link.");
         }
 
-        hrefBuf.append(firstParameter ? '?' : '&');
+        if (firstParameter) {
+            hrefBuf.append('?');
+        } else {
+            if (strictXhtmlLinks) {
+                hrefBuf.append("&amp;");
+            } else {
+                hrefBuf.append('&');
+            }
+        }
+
         hrefBuf.append(URLEncoder.encode(name, charEncoding));
         hrefBuf.append('=');
         if (value != null)