- Improvement to alignment/wrapping issues with dynamic HTML DIV menus in IE
. Refactor of ActionLinkRenderer code, fixes subtle alignment issues in IE and improves performance

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5023 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2007-02-02 17:33:31 +00:00
parent 14f2f44785
commit 9e40f41824
3 changed files with 225 additions and 237 deletions

View File

@@ -79,9 +79,15 @@ public class ActionLinkRenderer extends BaseRenderer
{ {
return; return;
} }
Writer out = context.getResponseWriter();
UIActionLink link = (UIActionLink)component; UIActionLink link = (UIActionLink)component;
// if there is no value for the link there will be no visible output
// on the page so don't bother rendering anything
if (link.getValue() != null)
{
Writer out = context.getResponseWriter();
UIComponent verticalContiner = getVerticalContainer(link); UIComponent verticalContiner = getVerticalContainer(link);
if (verticalContiner != null) if (verticalContiner != null)
{ {
@@ -92,12 +98,13 @@ public class ActionLinkRenderer extends BaseRenderer
padding = ((UIActions)verticalContiner).getVerticalSpacing(); padding = ((UIActions)verticalContiner).getVerticalSpacing();
} }
// render as menu item style action link // render as menu item style action link
out.write( renderMenuAction(context, link, padding) ); renderMenuAction(context, out, link, padding);
} }
else else
{ {
// render as action link // render as action link
out.write( renderActionLink(context, link) ); renderActionLink(context, out, link);
}
} }
} }
@@ -106,161 +113,151 @@ public class ActionLinkRenderer extends BaseRenderer
* *
* @param context * @param context
* @param link * @param link
*
* @return action link HTML
*/ */
private String renderActionLink(FacesContext context, UIActionLink link) private void renderActionLink(FacesContext context, Writer out, UIActionLink link)
throws IOException
{ {
// if there is no value for the link there will be no visible output // output the action link - with an image icon if specified, else just the text link part
// on the page so don't bother rendering anything String image = link.getImage();
String linkHtml = ""; if (image != null)
Object linkValue = link.getValue(); {
int padding = link.getPadding();
if (padding != 0)
{
// TODO: make this width value a property!
out.write("<table cellspacing=0 cellpadding=0><tr><td width=16>");
}
if (linkValue != null) // if we are not show the text link, then the image is the clickable element
if (link.getShowLink() == false)
{
renderActionLinkAnchor(context, out, link);
}
out.write(Utils.buildImageTag(context, image, (String)link.getValue(), "absmiddle"));
if (link.getShowLink() == false)
{
out.write("</a>");
}
else
{
if (padding != 0)
{
out.write("</td><td style=\"padding:");
out.write(Integer.toString(padding));
out.write("px\">");
}
// else the text is the clickable element
renderActionLinkAnchor(context, out, link);
out.write(Utils.encode(link.getValue().toString()));
out.write("</a>");
}
if (padding != 0)
{
out.write("</td></tr></table>");
}
}
else
{
// no image, so text is the clickable element
renderActionLinkAnchor(context, out, link);
out.write(Utils.encode(link.getValue().toString()));
out.write("</a>");
}
}
/**
* Render ActionLink as plain link and image
*
* @param context
* @param link
*/
private void renderActionLinkAnchor(FacesContext context, Writer out, UIActionLink link)
throws IOException
{ {
Map attrs = link.getAttributes(); Map attrs = link.getAttributes();
StringBuilder linkBuf = new StringBuilder(256);
// generate the href link - output later in the process depending on various rendering options
if (link.getHref() == null) if (link.getHref() == null)
{ {
linkBuf.append("<a href='#' onclick=\""); out.write("<a href='#' onclick=\"");
// if we have an overriden onclick add that // if we have an overriden onclick add that
if (link.getOnclick() != null) if (link.getOnclick() != null)
{ {
linkBuf.append(link.getOnclick()); out.write(link.getOnclick());
} }
else else
{ {
// generate JavaScript to set a hidden form field and submit // generate JavaScript to set a hidden form field and submit
// a form which request attributes that we can decode // a form which request attributes that we can decode
linkBuf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link))); out.write(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link)));
} }
linkBuf.append('"'); out.write('"');
} }
else else
{ {
String href = link.getHref(); String href = link.getHref();
// prefix the web context path if required // prefix the web context path if required
linkBuf.append("<a href=\""); out.write("<a href=\"");
if (href.startsWith("/")) if (href.startsWith("/"))
{ {
linkBuf.append(context.getExternalContext().getRequestContextPath()); out.write(context.getExternalContext().getRequestContextPath());
} }
linkBuf.append(href); out.write(href);
// append the href params if any are present // append the href params if any are present
renderHrefParams(link, linkBuf, href); renderHrefParams(link, out, href);
linkBuf.append('"'); out.write('"');
// output href 'target' attribute if supplied // output href 'target' attribute if supplied
if (link.getTarget() != null) if (link.getTarget() != null)
{ {
linkBuf.append(" target=\"") out.write(" target=\"");
.append(link.getTarget()) out.write(link.getTarget());
.append("\""); out.write("\"");
} }
} }
// common link attributes
if (attrs.get("id") != null) if (attrs.get("id") != null)
{ {
linkBuf.append(" id=\"") out.write(" id=\"");
.append(attrs.get("id")) out.write((String)attrs.get("id"));
.append("\""); out.write("\"");
} }
boolean appliedStyle = false;
if (attrs.get("style") != null) if (attrs.get("style") != null)
{ {
linkBuf.append(" style=\"") out.write(" style=\"");
.append(attrs.get("style")) out.write((String)attrs.get("style"));
.append('"'); out.write('"');
appliedStyle = true;
} }
if (attrs.get("styleClass") != null) if (attrs.get("styleClass") != null)
{ {
linkBuf.append(" class=") out.write(" class=");
.append(attrs.get("styleClass")); out.write((String)attrs.get("styleClass"));
appliedStyle = true;
}
if (appliedStyle == false && link.getShowLink() == true && link.getImage() != null && link.getPadding() == 0)
{
// apply default alignment style if we have an image and no outer table padding
out.write(" style='padding-left:2px;vertical-align:0%'");
} }
if (link.getTooltip() != null) if (link.getTooltip() != null)
{ {
linkBuf.append(" title=\"") out.write(" title=\"");
.append(Utils.encode(link.getTooltip())) out.write(Utils.encode(link.getTooltip()));
.append('"'); out.write('"');
} }
linkBuf.append('>'); out.write('>');
StringBuilder buf = new StringBuilder(350);
if (link.getImage() != null)
{
int padding = link.getPadding();
if (padding != 0)
{
// TODO: make this width value a property!
buf.append("<table cellspacing=0 cellpadding=0><tr><td width=16>");
}
if (link.getShowLink() == false)
{
buf.append(linkBuf.toString());
}
// TODO: allow configuring of alignment attribute
buf.append(Utils.buildImageTag(context, link.getImage(), (String)link.getValue(), "absmiddle"));
if (link.getShowLink() == false)
{
buf.append("</a>");
}
else
{
if (padding != 0)
{
buf.append("</td><td style=\"padding:")
.append(padding)
.append("px\">");
}
else
{
// TODO: add horizontal spacing as component property
buf.append("<span style='padding-left:2px");
// text next to an image may need alignment
if (attrs.get("verticalAlign") != null)
{
buf.append(";vertical-align:")
.append(attrs.get("verticalAlign"));
}
buf.append("'>");
}
buf.append(linkBuf.toString());
buf.append(Utils.encode(link.getValue().toString()));
buf.append("</a>");
if (padding == 0)
{
buf.append("</span>");
}
}
if (padding != 0)
{
buf.append("</td></tr></table>");
}
}
else
{
buf.append(linkBuf.toString());
buf.append(Utils.encode(link.getValue().toString()));
buf.append("</a>");
}
linkHtml = buf.toString();
}
return linkHtml;
} }
/** /**
@@ -268,7 +265,8 @@ public class ActionLinkRenderer extends BaseRenderer
* @param linkBuf * @param linkBuf
* @param href * @param href
*/ */
private void renderHrefParams(UIActionLink link, StringBuilder linkBuf, String href) private void renderHrefParams(UIActionLink link, Writer out, String href)
throws IOException
{ {
// append arguments if specified // append arguments if specified
Map<String, String> actionParams = getParameterComponents(link); Map<String, String> actionParams = getParameterComponents(link);
@@ -280,16 +278,18 @@ public class ActionLinkRenderer extends BaseRenderer
String paramValue = actionParams.get(name); String paramValue = actionParams.get(name);
if (first) if (first)
{ {
linkBuf.append('?'); out.write('?');
first = false; first = false;
} }
else else
{ {
linkBuf.append('&'); out.write('&');
} }
try try
{ {
linkBuf.append(name).append("=").append(URLEncoder.encode(paramValue, "UTF-8")); out.write(name);
out.write("=");
out.write(URLEncoder.encode(paramValue, "UTF-8"));
} }
catch (UnsupportedEncodingException err) catch (UnsupportedEncodingException err)
{ {
@@ -304,43 +304,36 @@ public class ActionLinkRenderer extends BaseRenderer
* *
* @param context * @param context
* @param link * @param link
*
* @return action link HTML
*/ */
private String renderMenuAction(FacesContext context, UIActionLink link, int padding) private void renderMenuAction(FacesContext context, Writer out, UIActionLink link, int padding)
throws IOException
{ {
// if there is no value for the link there will be no visible output out.write("<tr><td>");
// on the page so don't bother rendering anything
String linkHtml = "";
Object linkValue = link.getValue();
if (linkValue != null)
{
StringBuilder buf = new StringBuilder(256);
buf.append("<tr><td>");
// render image cell first for a menu // render image cell first for a menu
if (link.getImage() != null) if (link.getImage() != null)
{ {
buf.append(Utils.buildImageTag(context, link.getImage(), (String)link.getValue())); out.write(Utils.buildImageTag(context, link.getImage(), (String)link.getValue()));
} }
buf.append("</td><td"); out.write("</td><td");
if (padding != 0) if (padding != 0)
{ {
buf.append(" style=\"padding:") out.write(" style=\"padding:");
.append(padding) out.write(Integer.toString(padding));
.append("px\""); out.write("px\">");
}
else
{
out.write(">");
} }
buf.append(">");
// render text link cell for the menu // render text link cell for the menu
if (link.getHref() == null) if (link.getHref() == null)
{ {
buf.append("<a href='#' onclick=\""); out.write("<a href='#' onclick=\"");
buf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link))); out.write(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link)));
buf.append('"'); out.write('"');
} }
else else
{ {
@@ -349,45 +342,40 @@ public class ActionLinkRenderer extends BaseRenderer
{ {
href = context.getExternalContext().getRequestContextPath() + href; href = context.getExternalContext().getRequestContextPath() + href;
} }
buf.append("<a href=\"") out.write("<a href=\"");
.append(href); out.write(href);
// append the href params if any are present // append the href params if any are present
renderHrefParams(link, buf, href); renderHrefParams(link, out, href);
buf.append('"'); out.write('"');
// output href 'target' attribute if supplied // output href 'target' attribute if supplied
if (link.getTarget() != null) if (link.getTarget() != null)
{ {
buf.append(" target=\"") out.write(" target=\"");
.append(link.getTarget()) out.write(link.getTarget());
.append("\""); out.write("\"");
} }
} }
Map attrs = link.getAttributes(); Map attrs = link.getAttributes();
if (attrs.get("style") != null) if (attrs.get("style") != null)
{ {
buf.append(" style=\"") out.write(" style=\"");
.append(attrs.get("style")) out.write((String)attrs.get("style"));
.append('"'); out.write('"');
} }
if (attrs.get("styleClass") != null) if (attrs.get("styleClass") != null)
{ {
buf.append(" class=") out.write(" class=");
.append(attrs.get("styleClass")); out.write((String)attrs.get("styleClass"));
} }
buf.append('>'); out.write('>');
buf.append(Utils.encode(link.getValue().toString())); out.write(Utils.encode(link.getValue().toString()));
buf.append("</a>"); out.write("</a>");
buf.append("</td></tr>"); out.write("</td></tr>");
linkHtml = buf.toString();
}
return linkHtml;
} }

View File

@@ -74,11 +74,11 @@
<div class="mainSubText"><h:outputText value="#{msg.sandbox_info}" id="msg3" /></div> <div class="mainSubText"><h:outputText value="#{msg.sandbox_info}" id="msg3" /></div>
<div class="mainSubText"><h:outputText value="#{NavigationBean.nodeProperties.description}" id="msg4" /></div> <div class="mainSubText"><h:outputText value="#{NavigationBean.nodeProperties.description}" id="msg4" /></div>
</td> </td>
<td align=right> <td style="white-space:nowrap">
<a:actionLink value="#{msg.sandbox_preview}" image="/images/icons/preview_website.gif" href="#{AVMBrowseBean.sandboxPreviewUrl}" target="new" /> <a:actionLink value="#{msg.sandbox_preview}" image="/images/icons/preview_website.gif" href="#{AVMBrowseBean.sandboxPreviewUrl}" target="new" />
</td> </td>
<r:permissionEvaluator value="#{AVMBrowseBean.currentPathNode}" allow="CreateChildren" id="eval1"> <r:permissionEvaluator value="#{AVMBrowseBean.currentPathNode}" allow="CreateChildren" id="eval1">
<td style="padding-left:4px;white-space:nowrap" width=80> <td style="padding-left:4px;white-space:nowrap" width=120>
<%-- Create actions menu --%> <%-- Create actions menu --%>
<a:menu id="createMenu" itemSpacing="4" label="#{msg.create_options}" image="/images/icons/menu.gif" menuStyleClass="moreActionsMenu" style="white-space:nowrap"> <a:menu id="createMenu" itemSpacing="4" label="#{msg.create_options}" image="/images/icons/menu.gif" menuStyleClass="moreActionsMenu" style="white-space:nowrap">
<r:actions id="acts_create" value="avm_create_menu" context="#{AVMBrowseBean.currentPathNode}" /> <r:actions id="acts_create" value="avm_create_menu" context="#{AVMBrowseBean.currentPathNode}" />

View File

@@ -74,7 +74,7 @@
<div class="mainSubText"><h:outputText value="#{msg.website_info}" id="msg3" /></div> <div class="mainSubText"><h:outputText value="#{msg.website_info}" id="msg3" /></div>
<div class="mainSubText"><h:outputText value="#{NavigationBean.nodeProperties.description}" id="msg4" /></div> <div class="mainSubText"><h:outputText value="#{NavigationBean.nodeProperties.description}" id="msg4" /></div>
</td> </td>
<td align="right" style="white-space:nowrap" width=150> <td style="white-space:nowrap" width=150>
<nobr> <nobr>
<%-- More actions menu --%> <%-- More actions menu --%>
<a:menu id="actions-menu" itemSpacing="4" label="#{msg.actions}" image="/images/icons/menu.gif" menuStyleClass="moreActionsMenu" style="white-space:nowrap"> <a:menu id="actions-menu" itemSpacing="4" label="#{msg.actions}" image="/images/icons/menu.gif" menuStyleClass="moreActionsMenu" style="white-space:nowrap">