- 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,25 +79,32 @@ 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)
{
int padding = link.getPadding();
if (verticalContiner instanceof UIActions)
{ {
padding = ((UIActions)verticalContiner).getVerticalSpacing(); int padding = link.getPadding();
if (verticalContiner instanceof UIActions)
{
padding = ((UIActions)verticalContiner).getVerticalSpacing();
}
// render as menu item style action link
renderMenuAction(context, out, link, padding);
}
else
{
// render as action link
renderActionLink(context, out, link);
} }
// render as menu item style action link
out.write( renderMenuAction(context, link, padding) );
}
else
{
// render as action link
out.write( renderActionLink(context, 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();
if (linkValue != null)
{ {
Map attrs = link.getAttributes(); int padding = link.getPadding();
StringBuilder linkBuf = new StringBuilder(256); if (padding != 0)
if (link.getHref() == null)
{ {
linkBuf.append("<a href='#' onclick=\""); // TODO: make this width value a property!
out.write("<table cellspacing=0 cellpadding=0><tr><td width=16>");
// if we have an overriden onclick add that }
if (link.getOnclick() != null)
{ // if we are not show the text link, then the image is the clickable element
linkBuf.append(link.getOnclick()); if (link.getShowLink() == false)
} {
else renderActionLinkAnchor(context, out, link);
{ }
// generate JavaScript to set a hidden form field and submit
// a form which request attributes that we can decode out.write(Utils.buildImageTag(context, image, (String)link.getValue(), "absmiddle"));
linkBuf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link)));
} if (link.getShowLink() == false)
{
linkBuf.append('"'); out.write("</a>");
} }
else else
{ {
String href = link.getHref();
// prefix the web context path if required
linkBuf.append("<a href=\"");
if (href.startsWith("/"))
{
linkBuf.append(context.getExternalContext().getRequestContextPath());
}
linkBuf.append(href);
// append the href params if any are present
renderHrefParams(link, linkBuf, href);
linkBuf.append('"');
// output href 'target' attribute if supplied
if (link.getTarget() != null)
{
linkBuf.append(" target=\"")
.append(link.getTarget())
.append("\"");
}
}
if (attrs.get("id") != null)
{
linkBuf.append(" id=\"")
.append(attrs.get("id"))
.append("\"");
}
if (attrs.get("style") != null)
{
linkBuf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
linkBuf.append(" class=")
.append(attrs.get("styleClass"));
}
if (link.getTooltip() != null)
{
linkBuf.append(" title=\"")
.append(Utils.encode(link.getTooltip()))
.append('"');
}
linkBuf.append('>');
StringBuilder buf = new StringBuilder(350);
if (link.getImage() != null)
{
int padding = link.getPadding();
if (padding != 0) if (padding != 0)
{ {
// TODO: make this width value a property! out.write("</td><td style=\"padding:");
buf.append("<table cellspacing=0 cellpadding=0><tr><td width=16>"); out.write(Integer.toString(padding));
out.write("px\">");
} }
if (link.getShowLink() == false) // else the text is the clickable element
{ renderActionLinkAnchor(context, out, link);
buf.append(linkBuf.toString()); out.write(Utils.encode(link.getValue().toString()));
} out.write("</a>");
}
// TODO: allow configuring of alignment attribute
buf.append(Utils.buildImageTag(context, link.getImage(), (String)link.getValue(), "absmiddle")); if (padding != 0)
{
if (link.getShowLink() == false) out.write("</td></tr></table>");
{ }
buf.append("</a>"); }
} else
else {
{ // no image, so text is the clickable element
if (padding != 0) renderActionLinkAnchor(context, out, link);
{ out.write(Utils.encode(link.getValue().toString()));
buf.append("</td><td style=\"padding:") out.write("</a>");
.append(padding) }
.append("px\">"); }
}
else /**
{ * Render ActionLink as plain link and image
// TODO: add horizontal spacing as component property *
buf.append("<span style='padding-left:2px"); * @param context
* @param link
// text next to an image may need alignment */
if (attrs.get("verticalAlign") != null) private void renderActionLinkAnchor(FacesContext context, Writer out, UIActionLink link)
{ throws IOException
buf.append(";vertical-align:") {
.append(attrs.get("verticalAlign")); Map attrs = link.getAttributes();
}
// generate the href link - output later in the process depending on various rendering options
buf.append("'>"); if (link.getHref() == null)
} {
out.write("<a href='#' onclick=\"");
buf.append(linkBuf.toString());
buf.append(Utils.encode(link.getValue().toString())); // if we have an overriden onclick add that
buf.append("</a>"); if (link.getOnclick() != null)
{
if (padding == 0) out.write(link.getOnclick());
{
buf.append("</span>");
}
}
if (padding != 0)
{
buf.append("</td></tr></table>");
}
} }
else else
{ {
buf.append(linkBuf.toString()); // generate JavaScript to set a hidden form field and submit
buf.append(Utils.encode(link.getValue().toString())); // a form which request attributes that we can decode
buf.append("</a>"); out.write(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link)));
} }
linkHtml = buf.toString(); out.write('"');
}
else
{
String href = link.getHref();
// prefix the web context path if required
out.write("<a href=\"");
if (href.startsWith("/"))
{
out.write(context.getExternalContext().getRequestContextPath());
}
out.write(href);
// append the href params if any are present
renderHrefParams(link, out, href);
out.write('"');
// output href 'target' attribute if supplied
if (link.getTarget() != null)
{
out.write(" target=\"");
out.write(link.getTarget());
out.write("\"");
}
} }
return linkHtml; // common link attributes
if (attrs.get("id") != null)
{
out.write(" id=\"");
out.write((String)attrs.get("id"));
out.write("\"");
}
boolean appliedStyle = false;
if (attrs.get("style") != null)
{
out.write(" style=\"");
out.write((String)attrs.get("style"));
out.write('"');
appliedStyle = true;
}
if (attrs.get("styleClass") != null)
{
out.write(" class=");
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)
{
out.write(" title=\"");
out.write(Utils.encode(link.getTooltip()));
out.write('"');
}
out.write('>');
} }
/** /**
@@ -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,90 +304,78 @@ 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) // render image cell first for a menu
if (link.getImage() != null)
{ {
StringBuilder buf = new StringBuilder(256); out.write(Utils.buildImageTag(context, link.getImage(), (String)link.getValue()));
buf.append("<tr><td>");
// render image cell first for a menu
if (link.getImage() != null)
{
buf.append(Utils.buildImageTag(context, link.getImage(), (String)link.getValue()));
}
buf.append("</td><td");
if (padding != 0)
{
buf.append(" style=\"padding:")
.append(padding)
.append("px\"");
}
buf.append(">");
// render text link cell for the menu
if (link.getHref() == null)
{
buf.append("<a href='#' onclick=\"");
buf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link)));
buf.append('"');
}
else
{
String href = link.getHref();
if (href.startsWith("http") == false)
{
href = context.getExternalContext().getRequestContextPath() + href;
}
buf.append("<a href=\"")
.append(href);
// append the href params if any are present
renderHrefParams(link, buf, href);
buf.append('"');
// output href 'target' attribute if supplied
if (link.getTarget() != null)
{
buf.append(" target=\"")
.append(link.getTarget())
.append("\"");
}
}
Map attrs = link.getAttributes();
if (attrs.get("style") != null)
{
buf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
buf.append(" class=")
.append(attrs.get("styleClass"));
}
buf.append('>');
buf.append(Utils.encode(link.getValue().toString()));
buf.append("</a>");
buf.append("</td></tr>");
linkHtml = buf.toString();
} }
return linkHtml; out.write("</td><td");
if (padding != 0)
{
out.write(" style=\"padding:");
out.write(Integer.toString(padding));
out.write("px\">");
}
else
{
out.write(">");
}
// render text link cell for the menu
if (link.getHref() == null)
{
out.write("<a href='#' onclick=\"");
out.write(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterComponents(link)));
out.write('"');
}
else
{
String href = link.getHref();
if (href.startsWith("http") == false)
{
href = context.getExternalContext().getRequestContextPath() + href;
}
out.write("<a href=\"");
out.write(href);
// append the href params if any are present
renderHrefParams(link, out, href);
out.write('"');
// output href 'target' attribute if supplied
if (link.getTarget() != null)
{
out.write(" target=\"");
out.write(link.getTarget());
out.write("\"");
}
}
Map attrs = link.getAttributes();
if (attrs.get("style") != null)
{
out.write(" style=\"");
out.write((String)attrs.get("style"));
out.write('"');
}
if (attrs.get("styleClass") != null)
{
out.write(" class=");
out.write((String)attrs.get("styleClass"));
}
out.write('>');
out.write(Utils.encode(link.getValue().toString()));
out.write("</a>");
out.write("</td></tr>");
} }

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">