protected void renderCommandLinkStart()

in impl/src/main/java/org/apache/myfaces/renderkit/html/base/HtmlLinkRendererBase.java [226:441]


    protected void renderCommandLinkStart(FacesContext facesContext, UIComponent component,
                                          String clientId,
                                          Object value,
                                          String style,
                                          String styleClass)
            throws IOException
    {
        ResponseWriter writer = facesContext.getResponseWriter();
        Map<String, List<ClientBehavior>> behaviors = null;

        // h:commandLink can be rendered outside a form, but with warning (jsf 2.0 TCK)
        UIForm form = ComponentUtils.findClosest(UIForm.class, component);
        
        boolean disabled = HtmlRendererUtils.isDisabled(component);
        
        if (disabled || form == null)
        {
            writer.startElement(HTML.SPAN_ELEM, component);
            if (component instanceof ClientBehaviorHolder holder)
            {
                behaviors = holder.getClientBehaviors();
                if (!behaviors.isEmpty())
                {
                    HtmlRendererUtils.writeIdAndName(writer, component, facesContext);
                }
                else
                {
                    HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
                }
                long commonPropertiesMarked = 0L;
                if (isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    commonPropertiesMarked = CommonHtmlAttributesUtil.getMarkedAttributes(component);
                }
                
                // only render onclick if != disabled
                if (!disabled)
                {
                    if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
                    {
                        CommonHtmlAttributesUtil.renderEventProperties(writer, 
                                commonPropertiesMarked, component);
                        CommonHtmlAttributesUtil.renderFocusBlurEventProperties(writer,
                                commonPropertiesMarked, component);
                    }
                    else
                    {
                        if (isCommonEventsOptimizationEnabled(facesContext))
                        {
                            long commonEventsMarked = CommonHtmlEventsUtil.getMarkedEvents(component);
                            CommonHtmlEventsUtil.renderBehaviorizedEventHandlers(facesContext, writer, 
                                    commonPropertiesMarked, commonEventsMarked, component, behaviors);
                            CommonHtmlEventsUtil.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
                                facesContext, writer, commonPropertiesMarked, commonEventsMarked, component, behaviors);
                        }
                        else
                        {
                            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, 
                                    behaviors);
                            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
                                    facesContext, writer, component, behaviors);
                        }
                    }
                }
                else
                {
                    if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
                    {
                        CommonHtmlAttributesUtil.renderEventPropertiesWithoutOnclick(writer, 
                                commonPropertiesMarked, component);
                        CommonHtmlAttributesUtil.renderFocusBlurEventProperties(writer,
                                commonPropertiesMarked, component);
                    }
                    else
                    {
                        if (isCommonEventsOptimizationEnabled(facesContext))
                        {
                            long commonEventsMarked = CommonHtmlEventsUtil.getMarkedEvents(component);
                            CommonHtmlEventsUtil.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer, 
                                    commonPropertiesMarked, commonEventsMarked, component, behaviors);
                            CommonHtmlEventsUtil.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
                                facesContext, writer, commonPropertiesMarked, commonEventsMarked, component, behaviors);
                        }
                        else
                        {
                            HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer,
                                    component, behaviors);
                            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
                                    facesContext, writer, component, behaviors);
                        }
                    }
                }
                if (isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    CommonHtmlAttributesUtil.renderAnchorPassthroughPropertiesDisabledWithoutEvents(writer, 
                            commonPropertiesMarked, component);
                }
                else
                {
                    HtmlRendererUtils.renderHTMLAttributes(writer, component, 
                            HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_DISABLED_WITHOUT_EVENTS);
                }
            }
            else
            {
                HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
                if (isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    CommonHtmlAttributesUtil.renderAnchorPassthroughPropertiesDisabled(writer, 
                            CommonHtmlAttributesUtil.getMarkedAttributes(component), component);
                }
                else
                {
                    HtmlRendererUtils.renderHTMLAttributes(writer, component, 
                            HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_DISABLED);
                }
            }
        }
        else
        {
            if (component instanceof ClientBehaviorHolder holder)
            {
                behaviors = holder.getClientBehaviors();
                renderBehaviorizedJavaScriptAnchorStart(
                        facesContext, writer, component, clientId, behaviors, form);
                if (!behaviors.isEmpty())
                {
                    HtmlRendererUtils.writeIdAndName(writer, component, facesContext);
                }
                else 
                {
                    // If onclick is not null, both onclick and server side script are rendered 
                    // using faces.util.chain(...) js function. We need to check that case and force
                    // id/name rendering. It is possible to do something else in that case and 
                    // do not render the script using faces.util.chain, but for now it is ok.
                    String commandOnclick;
                    if (component instanceof HtmlCommandLink link)
                    {
                        commandOnclick = link.getOnclick();
                    }
                    else
                    {
                        commandOnclick = (String)component.getAttributes().get(HTML.ONCLICK_ATTR);
                    }

                    if (commandOnclick != null)
                    {
                        HtmlRendererUtils.writeIdAndName(writer, component, facesContext);
                    }
                    else
                    {
                        HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
                    }
                }
                long commonPropertiesMarked = 0L;
                if (isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    commonPropertiesMarked = CommonHtmlAttributesUtil.getMarkedAttributes(component);
                }
                if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    CommonHtmlAttributesUtil.renderEventPropertiesWithoutOnclick(writer,
                        commonPropertiesMarked, component);
                    CommonHtmlAttributesUtil.renderFocusBlurEventProperties(writer,
                            commonPropertiesMarked, component);
                }
                else
                {
                    HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(
                            facesContext, writer, component, behaviors);
                    HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
                            facesContext, writer, component, behaviors);
                }
                if (isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    CommonHtmlAttributesUtil.renderAnchorPassthroughPropertiesWithoutStyleAndEvents(writer, 
                            commonPropertiesMarked, component);
                }
                else
                {
                    HtmlRendererUtils.renderHTMLAttributes(writer, component, 
                            HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_STYLE_AND_EVENTS);
                }
            }
            else
            {
                renderJavaScriptAnchorStart(facesContext, writer, component, clientId, form);
                HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
                if (isCommonPropertiesOptimizationEnabled(facesContext))
                {
                    CommonHtmlAttributesUtil.renderAnchorPassthroughPropertiesWithoutOnclickAndStyle(writer, 
                            CommonHtmlAttributesUtil.getMarkedAttributes(component), component);
                }
                else
                {
                    HtmlRendererUtils.renderHTMLAttributes(writer, component, 
                            HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE);
                }
            }

            HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, style);
            HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR, styleClass);
        }

        // render value as required by Faces 1.1 renderkitdocs
        if(value != null)
        {
            writer.writeText(value.toString(), ComponentAttrs.VALUE_ATTR);
        }
        
        // render warning message for a h:commandLink with no nesting form
        if (form == null)
        {
            writer.writeText(": This link is deactivated, because it is not embedded in a Faces form.", null);
        }
    }