From 6157e3dd5b15409edefe5ea4dddec94cb32f46d6 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 3 Aug 2010 23:04:55 +0000 Subject: [PATCH] SWF-1313 Honor disabled attribute by rendering a commandLink as a span element --- .../faces/ui/BaseHtmlTagRenderer.java | 4 +- .../ui/ProgressiveCommandButtonRenderer.java | 3 +- .../ui/ProgressiveCommandLinkRenderer.java | 141 +++++++++++------- 3 files changed, 92 insertions(+), 56 deletions(-) diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java index c915f38f..802d1baa 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java @@ -59,7 +59,7 @@ abstract class BaseHtmlTagRenderer extends Renderer { */ public void encodeBegin(FacesContext context, UIComponent component) throws IOException { ResponseWriter writer = context.getResponseWriter(); - writer.startElement(getRenderedTagName(null), component); + writer.startElement(getRenderedTagName(component), component); writeAttributes(context, component); } @@ -95,7 +95,7 @@ abstract class BaseHtmlTagRenderer extends Renderer { */ public void encodeEnd(FacesContext context, UIComponent component) throws IOException { ResponseWriter writer = context.getResponseWriter(); - writer.endElement(getRenderedTagName(null)); + writer.endElement(getRenderedTagName(component)); } /** diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java index 097b5e81..406c9784 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java @@ -75,8 +75,9 @@ public class ProgressiveCommandButtonRenderer extends BaseDojoComponentRenderer } Boolean ajaxEnabled = (Boolean) component.getAttributes().get("ajaxEnabled"); + Boolean disabled = (Boolean) component.getAttributes().get("disabled"); String processIds = (String) component.getAttributes().get("processIds"); - if (Boolean.TRUE.equals(ajaxEnabled)) { + if (Boolean.TRUE.equals(ajaxEnabled) && Boolean.FALSE.equals(disabled)) { if (StringUtils.hasText(processIds) && processIds.indexOf(component.getClientId(context)) == -1) { processIds = component.getClientId(context) + ", " + processIds; } else if (!StringUtils.hasText(processIds)) { diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java index ec7e1319..d858e701 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java @@ -51,17 +51,28 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend private static String[] ATTRIBUTES_TO_RENDER; - private static String ANCHOR_TAG_NAME = "a"; + private static String[] ATTRIBUTES_TO_RENDER_WHEN_DISABLED; + + private static String TAG_NAME = "a"; + + private static String TAG_NAME_WHEN_DISABLED = "span"; static { + List tempList = new ArrayList(); tempList.addAll(Arrays.asList(HTML.STANDARD_ATTRIBUTES)); - tempList.addAll(Arrays.asList(HTML.ANCHOR_ATTRIBUTES)); tempList.addAll(Arrays.asList(HTML.COMMON_ELEMENT_EVENTS)); tempList.addAll(Arrays.asList(HTML.KEYBOARD_EVENTS)); tempList.addAll(Arrays.asList(HTML.MOUSE_EVENTS)); - ATTRIBUTES_TO_RENDER = new String[tempList.size()]; + ATTRIBUTES_TO_RENDER_WHEN_DISABLED = new String[tempList.size()]; ListIterator i = tempList.listIterator(); + while (i.hasNext()) { + ATTRIBUTES_TO_RENDER_WHEN_DISABLED[i.nextIndex()] = (String) i.next(); + } + + tempList.addAll(Arrays.asList(HTML.ANCHOR_ATTRIBUTES)); + ATTRIBUTES_TO_RENDER = new String[tempList.size()]; + i = tempList.listIterator(); while (i.hasNext()) { ATTRIBUTES_TO_RENDER[i.nextIndex()] = (String) i.next(); } @@ -98,28 +109,36 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend }; public void encodeBegin(FacesContext context, UIComponent component) throws IOException { - // No need to be progressive if this is an AJAX request since it can be assumed JavaScript is enabled - if (!JsfUtils.isAsynchronousFlowRequest()) { - // Render a plain submit button first if this is not an ajax request - ProgressiveUICommand button = new ProgressiveUICommand(); - button.getAttributes().putAll(component.getAttributes()); - BeanUtils.copyProperties(component, button); - button.setRendererType("spring.faces.ProgressiveCommandButtonRenderer"); - button.setAjaxEnabled(Boolean.FALSE); - button.encodeBegin(context); - button.encodeChildren(context); - button.encodeEnd(context); - - // Now render the link's HTML into a javascript variable - ResourceHelper.beginScriptBlock(context); - + if (isProgressiveCommandDisabled(component)) { + // Ideally this code should not be here. However, the base class inserts script links, which is even less + // than ideal when a link is disabled. ResponseWriter writer = context.getResponseWriter(); - String scriptVarStart = "var " + component.getClientId(context).replaceAll(":", "_") + "_link = \""; - writer.writeText(scriptVarStart, null); - writer = new DoubleQuoteEscapingWriter(writer); - context.setResponseWriter(writer); + writer.startElement(getRenderedTagName(component), component); + writeAttributes(context, component); + } else { + // No need to be progressive if this is an AJAX request since it can be assumed JavaScript is enabled + if (!JsfUtils.isAsynchronousFlowRequest()) { + // Render a plain submit button first if this is not an ajax request + ProgressiveUICommand button = new ProgressiveUICommand(); + button.getAttributes().putAll(component.getAttributes()); + BeanUtils.copyProperties(component, button); + button.setRendererType("spring.faces.ProgressiveCommandButtonRenderer"); + button.setAjaxEnabled(Boolean.FALSE); + button.encodeBegin(context); + button.encodeChildren(context); + button.encodeEnd(context); + + // Now render the link's HTML into a javascript variable + ResourceHelper.beginScriptBlock(context); + + ResponseWriter writer = context.getResponseWriter(); + String scriptVarStart = "var " + component.getClientId(context).replaceAll(":", "_") + "_link = \""; + writer.writeText(scriptVarStart, null); + writer = new DoubleQuoteEscapingWriter(writer); + context.setResponseWriter(writer); + } + super.encodeBegin(context, component); } - super.encodeBegin(context, component); } public void encodeChildren(FacesContext context, UIComponent component) throws IOException { @@ -133,36 +152,44 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend } public void encodeEnd(FacesContext context, UIComponent component) throws IOException { - super.encodeEnd(context, component); + if (isProgressiveCommandDisabled(component)) { + // Ideally this code should not be here. However, the base class inserts script links, which is even less + // than ideal when a link is disabled. + ResponseWriter writer = context.getResponseWriter(); + writer.endElement(getRenderedTagName(component)); + } else { + super.encodeEnd(context, component); - StringBuffer decorationParams = new StringBuffer(); - decorationParams.append("{"); - decorationParams.append("elementId : '" + component.getClientId(context) + "'"); + StringBuffer decorationParams = new StringBuffer(); + decorationParams.append("{"); + decorationParams.append("elementId : '" + component.getClientId(context) + "'"); - ResponseWriter writer = context.getResponseWriter(); - // Close the script variable started in encodeBegin if this is not an AJAX request - if (!JsfUtils.isAsynchronousFlowRequest()) { - DoubleQuoteEscapingWriter tempWriter = (DoubleQuoteEscapingWriter) writer; - String scriptVarValue = tempWriter.escapeResult(); - context.setResponseWriter(tempWriter.original); - writer = tempWriter.original; - writer.writeText(scriptVarValue, null); + ResponseWriter writer = context.getResponseWriter(); + // Close the script variable started in encodeBegin if this is not an AJAX request + if (!JsfUtils.isAsynchronousFlowRequest()) { + DoubleQuoteEscapingWriter tempWriter = (DoubleQuoteEscapingWriter) writer; + String scriptVarValue = tempWriter.escapeResult(); + context.setResponseWriter(tempWriter.original); + writer = tempWriter.original; + writer.writeText(scriptVarValue, null); - String scriptVarEnd = "\";\n"; - writer.writeText(scriptVarEnd, null); + String scriptVarEnd = "\";\n"; + writer.writeText(scriptVarEnd, null); - decorationParams.append(", linkHtml : " + component.getClientId(context).replaceAll(":", "_") + "_link"); + decorationParams + .append(", linkHtml : " + component.getClientId(context).replaceAll(":", "_") + "_link"); + ResourceHelper.endScriptBlock(context); + } + + decorationParams.append("}"); + StringBuffer advisorScript = new StringBuffer(); + advisorScript.append("Spring.addDecoration(new Spring.CommandLinkDecoration(" + decorationParams.toString() + + "));"); + ResourceHelper.beginScriptBlock(context); + writer.writeText(advisorScript, null); ResourceHelper.endScriptBlock(context); } - - decorationParams.append("}"); - StringBuffer advisorScript = new StringBuffer(); - advisorScript.append("Spring.addDecoration(new Spring.CommandLinkDecoration(" + decorationParams.toString() - + "));"); - ResourceHelper.beginScriptBlock(context); - writer.writeText(advisorScript, null); - ResourceHelper.endScriptBlock(context); } public boolean getRendersChildren() { @@ -170,11 +197,11 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend } protected String[] getAttributesToRender(UIComponent component) { - return ATTRIBUTES_TO_RENDER; + return isProgressiveCommandDisabled(component) ? ATTRIBUTES_TO_RENDER_WHEN_DISABLED : ATTRIBUTES_TO_RENDER; } protected String getRenderedTagName(UIComponent component) { - return ANCHOR_TAG_NAME; + return isProgressiveCommandDisabled(component) ? TAG_NAME_WHEN_DISABLED : TAG_NAME; } protected Map getAttributeCallbacks(UIComponent component) { @@ -189,11 +216,15 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend } protected String getOnClickNoAjax(FacesContext context, UIComponent component) { - String params = encodeParamsAsArray(context, component); - StringBuffer onclick = new StringBuffer(); - onclick.append("this.submitFormFromLink('" + RendererUtils.getFormId(context, component) + "','" - + component.getClientId(context) + "', " + params + "); return false;"); - return onclick.toString(); + if (isProgressiveCommandDisabled(component)) { + return ""; + } else { + String params = encodeParamsAsArray(context, component); + StringBuffer onclick = new StringBuffer(); + onclick.append("this.submitFormFromLink('" + RendererUtils.getFormId(context, component) + "','" + + component.getClientId(context) + "', " + params + "); return false;"); + return onclick.toString(); + } } protected String encodeParamsAsArray(FacesContext context, UIComponent component) { @@ -215,6 +246,10 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend return paramArray.toString(); } + private Boolean isProgressiveCommandDisabled(UIComponent component) { + return ((ProgressiveUICommand) component).getDisabled(); + } + private class DoubleQuoteEscapingWriter extends ResponseWriter { private ResponseWriter original;