SWF-1313 Honor disabled attribute by rendering a commandLink as a span element

This commit is contained in:
Rossen Stoyanchev
2010-08-03 23:04:55 +00:00
parent ce99354c42
commit 6157e3dd5b
3 changed files with 92 additions and 56 deletions

View File

@@ -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));
}
/**

View File

@@ -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)) {

View File

@@ -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;