You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2009/09/18 19:40:16 UTC

svn commit: r816721 [1/2] - in /myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit: ./ html/

Author: lu4242
Date: Fri Sep 18 17:40:15 2009
New Revision: 816721

URL: http://svn.apache.org/viewvc?rev=816721&view=rev
Log:
MYFACES-2350 All renderers of components that implements ClientBehaviorHolder should encode javascript attributes

Added:
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java   (with props)
Modified:
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlBodyRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlCheckboxRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlGridRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlMessageRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlSecretRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextareaRendererBase.java

Added: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java?rev=816721&view=auto
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java (added)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java Fri Sep 18 17:40:15 2009
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.shared.renderkit;
+
+public interface ClientBehaviorEvents
+{
+    String BLUR = "blur";
+    String FOCUS = "focus";
+    
+    //VALUECHANGE and CHANGE are rendered in onchange
+    String VALUECHANGE = "valueChange";
+    String CHANGE = "change";
+    String SELECT = "select";
+    
+    //ACTION and CLICK are rendered in onclick
+    String ACTION = "action";
+    String CLICK = "click";
+    String DBLCLICK = "dblclick";
+    
+    String KEYDOWN = "keydown";
+    String KEYPRESS = "keypress";
+    String KEYUP = "keyup";
+    
+    String MOUSEDOWN = "mousedown";
+    String MOUSEMOVE = "mousemove";
+    String MOUSEOUT = "mouseout";
+    String MOUSEOVER = "mouseover";
+    String MOUSEUP = "mouseup";
+    
+    String LOAD = "load";
+    String UNLOAD = "unload";
+}

Propchange: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/ClientBehaviorEvents.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java Fri Sep 18 17:40:15 2009
@@ -122,6 +122,11 @@
 
         //NOTE: if changed, please verify universal attributes in HtmlMessageRenderer !
     };
+    String[] UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE_AND_TITLE =
+    {
+        DIR_ATTR,
+        LANG_ATTR,
+    };
     String[] UNIVERSAL_ATTRIBUTES =
             (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
                 UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE,
@@ -191,7 +196,15 @@
         (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
             EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT,
             UNIVERSAL_ATTRIBUTES);
-
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS =
+        (String[]) ArrayUtils.concat(
+            UNIVERSAL_ATTRIBUTES,
+            COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED);
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS =
+        (String[]) ArrayUtils.concat(
+            UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE,
+            COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED);
+    
     // <a>
     String TARGET_ATTR = "target";  //used by <a> and <form>
     String CHARSET_ATTR     = "charset";
@@ -230,6 +243,14 @@
             ANCHOR_ATTRIBUTES,
             COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE,
             COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+    String[] ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS =
+        (String[]) ArrayUtils.concat(
+            ANCHOR_ATTRIBUTES,
+            UNIVERSAL_ATTRIBUTES);
+    String[] ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_STYLE_AND_EVENTS =
+        (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
+            ANCHOR_ATTRIBUTES,
+            UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE);
 
     // <form>
     String ACCEPT_CHARSET_ATTR = "accept-charset";
@@ -249,7 +270,10 @@
         (String[]) ArrayUtils.concat(
             FORM_ATTRIBUTES,
             COMMON_PASSTROUGH_ATTRIBUTES);
-
+    String[] FORM_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS =
+        (String[]) ArrayUtils.concat(
+            FORM_ATTRIBUTES,
+            UNIVERSAL_ATTRIBUTES);
     // <img>
     String SRC_ATTR = "src";
     String ALT_ATTR = "alt";
@@ -281,6 +305,10 @@
         (String[]) ArrayUtils.concat(
            IMG_ATTRIBUTES,
            COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT);
+    String[] IMG_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS =
+        (String[]) ArrayUtils.concat(
+           IMG_ATTRIBUTES,
+           UNIVERSAL_ATTRIBUTES);
     // <input>
     String SIZE_ATTR = "size";
     String AUTOCOMPLETE_ATTR = "autocomplete";
@@ -309,6 +337,16 @@
                 INPUT_ATTRIBUTES,
                 COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK);
 
+    String[] INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS =
+        (String[]) ArrayUtils.concat(
+                INPUT_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
+    
+    String[] INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS =
+        (String[]) ArrayUtils.concat(
+                INPUT_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
+
     //values for input-type attribute
     String INPUT_TYPE_SUBMIT = "submit";
     String INPUT_TYPE_IMAGE = "image";
@@ -333,6 +371,10 @@
         (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
             BUTTON_ATTRIBUTES,
             COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONCLICK);
+    String[] BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS =
+        (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
+            BUTTON_ATTRIBUTES,
+            COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
 
     // <iframe>
     String FRAMEBORDER_ATTR = "frameborder";
@@ -347,16 +389,26 @@
         ONFOCUS_ATTR
         //FOR_ATTR is no pass through !
     };
+    String[] LABEL_ATTRIBUTES_WITHOUT_EVENTS =
+    {
+        ACCESSKEY_ATTR
+    };
     String[] LABEL_PASSTHROUGH_ATTRIBUTES =
         (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
             LABEL_ATTRIBUTES,
             COMMON_PASSTROUGH_ATTRIBUTES);
+    String[] LABEL_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS =
+        (String[]) org.apache.myfaces.shared.util.ArrayUtils.concat(
+            LABEL_ATTRIBUTES_WITHOUT_EVENTS,
+            UNIVERSAL_ATTRIBUTES);
 
     // <select>
     String MULTIPLE_ATTR = "multiple";
 
     String[] SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED = 
             COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED;
+    String[] SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS = 
+        COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS;
 
     // <table>
     String BGCOLOR_ATTR = "bgcolor";
@@ -380,6 +432,10 @@
         (String[]) ArrayUtils.concat(
             TABLE_ATTRIBUTES,
             COMMON_PASSTROUGH_ATTRIBUTES);
+    String[] TABLE_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS =
+        (String[]) ArrayUtils.concat(
+            TABLE_ATTRIBUTES,
+            UNIVERSAL_ATTRIBUTES);
 
     // <textarea>
     String COLS_ATTR = "cols";
@@ -396,6 +452,10 @@
         (String[]) ArrayUtils.concat(
             TEXTAREA_ATTRIBUTES,
             COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+    String[] TEXTAREA_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS =
+        (String[]) ArrayUtils.concat(
+            TEXTAREA_ATTRIBUTES,
+            COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
 
     // <input type=file>
     String[] INPUT_FILE_UPLOAD_ATTRIBUTES =
@@ -406,7 +466,10 @@
         (String[]) ArrayUtils.concat(
             INPUT_FILE_UPLOAD_ATTRIBUTES,
             INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
-
+    String[] INPUT_FILE_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS =
+        (String[]) ArrayUtils.concat(
+            INPUT_FILE_UPLOAD_ATTRIBUTES,
+            INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
 
     /*
     String[] MESSAGE_PASSTHROUGH_ATTRIBUTES =
@@ -456,14 +519,27 @@
         LINK_ATTR,
         TEXT_ATTR,
         BACKGROUND_ATTR,
-        HTML.BGCOLOR_ATTR
+        BGCOLOR_ATTR
+    };
+    
+    String[] BODY_ATTRIBUTES_WITHOUT_EVENTS =
+    {
+        ALINK_ATTR,
+        VLINK_ATTR,
+        LINK_ATTR,
+        TEXT_ATTR,
+        BACKGROUND_ATTR,
+        BGCOLOR_ATTR
     };
 
     String[] BODY_PASSTHROUGH_ATTRIBUTES =
         (String[]) ArrayUtils.concat(
                 COMMON_PASSTROUGH_ATTRIBUTES,
                 BODY_ATTRIBUTES);
-
+    String[] BODY_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS =
+        (String[]) ArrayUtils.concat(
+                UNIVERSAL_ATTRIBUTES,
+                BODY_ATTRIBUTES_WITHOUT_EVENTS);
     //HTML attributes needed for renderding only
     String ID_ATTR = "id";
     String NAME_ATTR = "name";

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlBodyRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlBodyRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlBodyRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlBodyRendererBase.java Fri Sep 18 17:40:15 2009
@@ -19,12 +19,19 @@
 package org.apache.myfaces.shared.renderkit.html;
 
 import java.io.IOException;
+import java.util.List;
+import java.util.Map;
 
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 
+import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
+
 /**
  * Renderer used by h:body component
  * 
@@ -44,8 +51,24 @@
         ResponseWriter writer = facesContext.getResponseWriter();
         writer.startElement(HTML.BODY_ELEM, component);
         HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
-        HtmlRendererUtils.renderHTMLAttributes(writer, component,
-                HTML.BODY_PASSTHROUGH_ATTRIBUTES);
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (component instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
+            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
+            HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, component, behaviors,
+                    ClientBehaviorEvents.LOAD, HTML.ONLOAD_ATTR, HTML.ONLOAD_ATTR);
+            HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, component, behaviors,
+                    ClientBehaviorEvents.UNLOAD, HTML.ONUNLOAD_ATTR, HTML.ONUNLOAD_ATTR);
+            HtmlRendererUtils.renderHTMLAttributes(writer, component,
+                    HTML.BODY_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+            
+        }
+        else
+        {
+            HtmlRendererUtils.renderHTMLAttributes(writer, component,
+                    HTML.BODY_PASSTHROUGH_ATTRIBUTES);
+        }
     }
 
     @Override

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java Fri Sep 18 17:40:15 2009
@@ -18,23 +18,30 @@
  */
 package org.apache.myfaces.shared.renderkit.html;
 
-import org.apache.myfaces.shared.config.MyfacesConfig;
-import org.apache.myfaces.shared.renderkit.JSFAttr;
-import org.apache.myfaces.shared.renderkit.RendererUtils;
-import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
-import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import javax.faces.component.UICommand;
 import javax.faces.component.UIComponent;
+import javax.faces.component.UIParameter;
 import javax.faces.component.ValueHolder;
+import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlCommandButton;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.event.ActionEvent;
-import java.io.IOException;
-import java.util.Map;
+
+import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
+import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
@@ -138,20 +145,46 @@
                 writer.writeAttribute(org.apache.myfaces.shared.renderkit.html.HTML.VALUE_ATTR, value, org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
             }
         }
-        if (JavascriptUtils.isJavascriptAllowed(externalContext))
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (uiComponent instanceof ClientBehaviorHolder)
         {
-            StringBuffer onClick = buildOnClick(uiComponent, facesContext, writer);
-            if (onClick.length() != 0){
+            behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+        }
+        
+        if (JavascriptUtils.isJavascriptAllowed(externalContext) &&
+            (HtmlRendererUtils.hasClientBehavior(ClientBehaviorEvents.CLICK, behaviors, facesContext) ||
+             HtmlRendererUtils.hasClientBehavior(ClientBehaviorEvents.ACTION, behaviors, facesContext)))
+        {
+            //TODO add the behavior attched rendering here
+            String onClick = buildBehaviorizedOnClick(uiComponent, behaviors, facesContext, writer);
+            if (onClick.length() != 0) {
                 writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
             }
+            
+            Map<String, Object> attributes = uiComponent.getAttributes(); 
+            
+            HtmlRendererUtils.buildBehaviorChain(
+                    facesContext, uiComponent, behaviors, ClientBehaviorEvents.DBLCLICK,   
+                        (String) attributes.get(HTML.ONDBLCLICK_ATTR), "",null);
+            
             HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
-                                                   HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONCLICK);
+                                                   HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
         }
-        else
-        {
+        //fallback into the pre 2.0 code to keep backwards comptability with libraries which rely on internals
+        else if (JavascriptUtils.isJavascriptAllowed(externalContext)) {
+            StringBuffer onClick = buildOnClick(uiComponent, facesContext, writer);
+            if (onClick.length() != 0) {
+                writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
+            }
             HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
-                                                   HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+                                                   HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
+        } else {
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
+                                                   HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
         }
+        
+        HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer, uiComponent, behaviors);
+        HtmlRendererUtils.renderBehaviorizedFieldEventHandlers(facesContext, writer, uiComponent, behaviors);
 
         if (isDisabled(facesContext, uiComponent))
         {
@@ -169,6 +202,45 @@
             findNestingForm(uiComponent, facesContext).getForm(), facesContext, writer);
     }
 
+    protected String buildBehaviorizedOnClick(UIComponent uiComponent, Map<String, List<ClientBehavior>> behaviors, FacesContext facesContext, ResponseWriter writer) {
+        //TODO fetch parameters from the button
+
+        //we can omit autoscroll here for now maybe we should check if it is an ajax behavior and omit it only in this case
+        StringBuilder userOnClick = new StringBuilder();
+        //user onclick part 
+        String commandOnClick = (String) uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
+
+        if (commandOnClick != null) {
+            userOnClick.append(commandOnClick);
+            userOnClick.append(';');
+        }
+
+        FormInfo formInfo = findNestingForm(uiComponent, facesContext);
+        if (formInfo == null) {
+            throw new IllegalArgumentException("Component " + uiComponent.getClientId(facesContext) + " must be embedded in an form");
+        }
+        String formName = formInfo.getFormName();
+
+        StringBuffer rendererOnClick = new StringBuffer();
+        if (JavascriptUtils.isRenderClearJavascriptOnButton(facesContext.getExternalContext())) {
+            //call the script to clear the form (clearFormHiddenParams_<formName>) method
+            HtmlRendererUtils.appendClearHiddenCommandFormParamsFunctionCall(rendererOnClick, formName);
+        }
+
+        if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll()) {
+            HtmlRendererUtils.appendAutoScrollAssignment(rendererOnClick, formName);
+        }
+
+        //TODO make parameter resolution here
+
+        //according to the specification in jsf.util.chain jdocs and the spec document we have to use
+        //jsf.util.chain to chain the functions and
+        return HtmlRendererUtils.buildBehaviorChain(facesContext, uiComponent, behaviors,
+                ClientBehaviorEvents.CLICK, ClientBehaviorEvents.ACTION, 
+                userOnClick.toString() , rendererOnClick.toString(),
+                HtmlRendererUtils.mapAttachedParamsToStringValues(facesContext, uiComponent));
+
+    }
 
     protected StringBuffer buildOnClick(UIComponent uiComponent, FacesContext facesContext, ResponseWriter writer)
         throws IOException

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlCheckboxRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlCheckboxRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlCheckboxRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlCheckboxRendererBase.java Fri Sep 18 17:40:15 2009
@@ -21,12 +21,14 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 import javax.faces.FacesException;
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UISelectBoolean;
 import javax.faces.component.UISelectMany;
+import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlSelectBooleanCheckbox;
 import javax.faces.component.html.HtmlSelectManyCheckbox;
@@ -38,6 +40,8 @@
 import javax.faces.model.SelectItemGroup;
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -261,15 +265,40 @@
             writer.writeAttribute(HTML.VALUE_ATTR, value, null);
         }
 
+        Map<String, List<ClientBehavior>> behaviors = null;
         if (uiComponent instanceof UISelectBoolean)
         {
-            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
-                HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+            if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+                
+                HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
+                        HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+            }
         }
         else
         {
-            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
-                HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
+            if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+                
+                HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
+                        HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
+            }
         }
         if (isDisabled(facesContext, uiComponent)) {
             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java Fri Sep 18 17:40:15 2009
@@ -20,16 +20,19 @@
 
 import org.apache.myfaces.shared.config.MyfacesConfig;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIForm;
+import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlForm;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import java.io.IOException;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -76,7 +79,17 @@
                                  facesContext.getExternalContext().encodeActionURL(actionURL),
                                  null);
 
-        HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_PASSTHROUGH_ATTRIBUTES);
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (htmlForm instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) htmlForm).getClientBehaviors();
+            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, htmlForm, behaviors);
+            HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+        }
+        else
+        {
+            HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_PASSTHROUGH_ATTRIBUTES);
+        }
 
         writer.write(""); // force start element tag to be closed
 

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlGridRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlGridRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlGridRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlGridRendererBase.java Fri Sep 18 17:40:15 2009
@@ -22,16 +22,21 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 import org.apache.myfaces.shared.util.ArrayUtils;
 import org.apache.myfaces.shared.util.StringUtils;
 
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIPanel;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlPanelGrid;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author Martin Marinschek
@@ -89,7 +94,18 @@
         ResponseWriter writer = facesContext.getResponseWriter();
         writer.startElement(HTML.TABLE_ELEM, component);
         HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
-        HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
+        
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (component instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
+            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
+            HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.TABLE_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+        }
+        else
+        {
+            HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
+        }
 
         writer.flush();
 

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java Fri Sep 18 17:40:15 2009
@@ -21,14 +21,19 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 import javax.faces.application.Resource;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIGraphic;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlGraphicImage;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import java.io.IOException;
+import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -100,7 +105,17 @@
             log.warn("ALT attribute is missing for : " + uiComponent.getId());
         }
 
-        HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.IMG_PASSTHROUGH_ATTRIBUTES);
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.IMG_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+        }
+        else
+        {
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.IMG_PASSTHROUGH_ATTRIBUTES);
+        }
 
         writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.IMG_ELEM);
 

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java Fri Sep 18 17:40:15 2009
@@ -21,22 +21,17 @@
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import javax.faces.FacesException;
-import javax.faces.application.ConfigurableNavigationHandler;
-import javax.faces.application.NavigationCase;
-import javax.faces.application.NavigationHandler;
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UICommand;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIOutcomeTarget;
 import javax.faces.component.UIOutput;
 import javax.faces.component.UIParameter;
+import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlCommandLink;
 import javax.faces.context.FacesContext;
@@ -44,6 +39,7 @@
 import javax.faces.event.ActionEvent;
 
 import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 import org.apache.myfaces.shared.renderkit.RendererUtils;
 import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
@@ -197,20 +193,42 @@
             throws IOException
     {
         ResponseWriter writer = facesContext.getResponseWriter();
+        Map<String, List<ClientBehavior>> behaviors = null;
 
         if (HtmlRendererUtils.isDisabled(component))
         {
             writer.startElement(HTML.SPAN_ELEM, component);
             HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
-            HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            if (component instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, component, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            }
         }
         else
         {
             String[] anchorAttrsToRender;
             if (JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
             {
-                renderJavaScriptAnchorStart(facesContext, writer, component, clientId);
-                anchorAttrsToRender = HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE;
+                if (component instanceof ClientBehaviorHolder)
+                {
+                    behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
+                    renderBehaviorizedJavaScriptAnchorStart(facesContext, writer, component, clientId, behaviors);
+                    HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer, component, behaviors);
+                    HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, component, behaviors);
+                    anchorAttrsToRender = HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_STYLE_AND_EVENTS;
+                }
+                else
+                {
+                    renderJavaScriptAnchorStart(facesContext, writer, component, clientId);
+                    anchorAttrsToRender = HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE;
+                }
             }
             else
             {
@@ -320,6 +338,106 @@
         writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
     }
 
+    
+    protected void renderBehaviorizedJavaScriptAnchorStart(FacesContext facesContext,
+            ResponseWriter writer,
+            UIComponent component,
+            String clientId,
+            Map<String, List<ClientBehavior>> behaviors)
+    throws IOException
+    {
+        FormInfo formInfo = findNestingForm(component, facesContext);
+        
+        if (formInfo == null)
+        {
+            String path = RendererUtils.getPathToComponent(component);
+            String msg = "Link is not embedded in a form. Change component/tag '" + clientId + "' from javax.faces.*/<h:tagName /> " +
+                "to org.apache.myfaces.*/<t:tagName />, or embed it in a form.  This is not a bug. " +
+                "Please see: http://wiki.apache.org/myfaces/Upgrading_to_Tomahawk_1.1.3 " +
+                "The path to this component is " + path + ". If you need to render a special form and a JSF-form's attributes are not enough," +
+                "consider using the s:form tag of the MyFaces sandbox.";
+            throw new IllegalArgumentException(msg);
+        }
+
+        String commandOnclick;
+        if (component instanceof HtmlCommandLink)
+        {
+            commandOnclick = ((HtmlCommandLink)component).getOnclick();
+        }
+        else
+        {
+            commandOnclick = (String)component.getAttributes().get(HTML.ONCLICK_ATTR);
+        }
+
+        //Calculate the script necessary to submit form
+        String serverEventCode = buildServerOnclick(facesContext, component, clientId, formInfo);
+        
+        String onclick = null;
+        
+        if (commandOnclick == null && (behaviors.isEmpty() || 
+            (!behaviors.containsKey(ClientBehaviorEvents.CLICK) && 
+             !behaviors.containsKey(ClientBehaviorEvents.ACTION) ) ) )
+        {
+            //we need to render only the submit script
+            onclick = serverEventCode;
+        }
+        else
+        {
+            //render a javascript that chain the related code
+            onclick = HtmlRendererUtils.buildBehaviorChain(facesContext, component, behaviors,
+                    ClientBehaviorEvents.CLICK, ClientBehaviorEvents.ACTION, 
+                    commandOnclick , serverEventCode,
+                    HtmlRendererUtils.mapAttachedParamsToStringValues(facesContext, component));
+        }
+        
+        writer.startElement(HTML.ANCHOR_ELEM, component);
+        writer.writeURIAttribute(HTML.HREF_ATTR, "#", null);
+        writer.writeAttribute(HTML.ONCLICK_ATTR, onclick, null);
+    }
+
+    protected String buildServerOnclick(FacesContext facesContext, UIComponent component, 
+            String clientId, FormInfo formInfo) throws IOException
+    {
+        UIComponent nestingForm = formInfo.getForm();
+        String formName = formInfo.getFormName();
+
+        StringBuffer onClick = new StringBuffer();
+
+        if (RendererUtils.isAdfOrTrinidadForm(formInfo.getForm())) {
+            onClick.append("submitForm('");
+            onClick.append(formInfo.getForm().getClientId(facesContext));
+            onClick.append("',1,{source:'");
+            onClick.append(component.getClientId(facesContext));
+            onClick.append("'});return false;");
+        }
+        else {
+            HtmlRendererUtils.renderFormSubmitScript(facesContext);
+
+            StringBuffer params = addChildParameters(component, nestingForm);
+
+            String target = getTarget(component);
+
+            onClick.append("return ").
+                append(HtmlRendererUtils.SUBMIT_FORM_FN_NAME).append("('").
+                append(formName).append("','").
+                append(clientId).append("'");
+
+            if (params.length() > 2 || target != null) {
+                onClick.append(",").
+                    append(target == null ? "null" : ("'" + target + "'")).append(",").
+                    append(params);
+            }
+            onClick.append(");");
+
+            //Not necessary since we are using oamSetHiddenInput to create input hidden fields
+            //render hidden field - todo: in here for backwards compatibility
+            //String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formInfo);
+            //addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
+
+        }
+        return onClick.toString();
+    }
+
     private String getTarget(UIComponent component) {
         // for performance reason: double check for the target attribute
         String target;
@@ -467,12 +585,23 @@
             throws IOException
     {
         ResponseWriter writer = facesContext.getResponseWriter();
+        Map<String, List<ClientBehavior>> behaviors = null;
 
         if (HtmlRendererUtils.isDisabled(output))
         {
             writer.startElement(HTML.SPAN_ELEM, output);
             HtmlRendererUtils.writeIdIfNecessary(writer, output, facesContext);
-            HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            if (output instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) output).getClientBehaviors();
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            }
         }
         else
         {
@@ -506,7 +635,17 @@
             writer.startElement(HTML.ANCHOR_ELEM, output);
             HtmlRendererUtils.writeIdAndNameIfNecessary(writer, output, facesContext);
             writer.writeURIAttribute(HTML.HREF_ATTR, href, null);
-            HtmlRendererUtils.renderHTMLAttributes(writer, output, org.apache.myfaces.shared.renderkit.html.HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            if (output instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) output).getClientBehaviors();
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            }
             writer.flush();
         }
     }
@@ -515,12 +654,22 @@
             throws IOException
     {
         ResponseWriter writer = facesContext.getResponseWriter();
-
+        Map<String, List<ClientBehavior>> behaviors = null;
         if (HtmlRendererUtils.isDisabled(output))
         {
             writer.startElement(HTML.SPAN_ELEM, output);
             HtmlRendererUtils.writeIdIfNecessary(writer, output, facesContext);
-            HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            if (output instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) output).getClientBehaviors();
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            }
         }
         else
         {
@@ -532,7 +681,17 @@
             writer.startElement(HTML.ANCHOR_ELEM, output);
             HtmlRendererUtils.writeIdAndNameIfNecessary(writer, output, facesContext);
             writer.writeURIAttribute(HTML.HREF_ATTR, href, null);
-            HtmlRendererUtils.renderHTMLAttributes(writer, output, org.apache.myfaces.shared.renderkit.html.HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            if (output instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) output).getClientBehaviors();
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, output, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, output, HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES);
+            }
             writer.flush();
         }
     }

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlMessageRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlMessageRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlMessageRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlMessageRendererBase.java Fri Sep 18 17:40:15 2009
@@ -20,12 +20,15 @@
 
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import javax.faces.application.FacesMessage;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIMessage;
 import javax.faces.component.UIViewRoot;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlMessage;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
@@ -35,6 +38,7 @@
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 import org.apache.myfaces.shared.renderkit.RendererUtils;
 import org.apache.myfaces.shared.renderkit.html.HTML;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
@@ -156,8 +160,13 @@
 
         boolean span = false;
 
-
-        if (message.getId() != null && !message.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (message instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) message).getClientBehaviors();
+        }
+        
+        if (message.getId() != null && (!message.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX) || !behaviors.isEmpty()))
         {
             span = true;
 
@@ -167,8 +176,16 @@
             {
                 HtmlRendererUtils.writeIdIfNecessary(writer, message, facesContext);
             }
-
-            HtmlRendererUtils.renderHTMLAttributes(writer, message, HTML.MESSAGE_PASSTHROUGH_ATTRIBUTES_WITHOUT_TITLE_STYLE_AND_STYLE_CLASS);
+            if (message instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+            {
+                behaviors = ((ClientBehaviorHolder) message).getClientBehaviors();
+                HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, message, behaviors);
+                HtmlRendererUtils.renderHTMLAttributes(writer, message, HTML.UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE_AND_TITLE);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, message, HTML.MESSAGE_PASSTHROUGH_ATTRIBUTES_WITHOUT_TITLE_STYLE_AND_STYLE_CLASS);
+            }
         }
         else
         {

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java Fri Sep 18 17:40:15 2009
@@ -22,6 +22,8 @@
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import javax.faces.FacesException;
 import javax.faces.application.ConfigurableNavigationHandler;
@@ -31,14 +33,18 @@
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIOutcomeTarget;
 import javax.faces.component.UIParameter;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlOutcomeTargetButton;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 
 import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 /**
  * @since 2.0
@@ -124,15 +130,26 @@
             writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
         }
 
-        HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
-                HTML.COMMON_PASSTROUGH_ATTRIBUTES);
-        HtmlRendererUtils
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();            
+            HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, uiComponent, behaviors);
+        }
+        else
+        {
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
+                    HTML.EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK);
+            HtmlRendererUtils
                 .renderHTMLAttributes(
-                        writer,
-                        uiComponent,
-                        HTML.COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+                    writer,
+                    uiComponent,
+                    HTML.COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+
+        }
         HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
-                HTML.COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED);
+                HTML.COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
         HtmlRendererUtils.renderHTMLAttribute(writer, uiComponent,
                 HTML.ALT_ATTR, HTML.ALT_ATTR);
 

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java Fri Sep 18 17:40:15 2009
@@ -22,8 +22,10 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 import javax.faces.component.*;
+import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlSelectOneRadio;
 import javax.faces.context.FacesContext;
@@ -35,6 +37,7 @@
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
@@ -263,8 +266,22 @@
         {
             writer.writeAttribute(HTML.VALUE_ATTR, value, null);
         }
+        
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+            
+            HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
+        }
+        else
+        {
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
+        }
 
-        HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
         if (isDisabled(facesContext, uiComponent))
         {
             writer.writeAttribute(org.apache.myfaces.shared.renderkit.html.HTML.DISABLED_ATTR, Boolean.TRUE, null);

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java?rev=816721&r1=816720&r2=816721&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java Fri Sep 18 17:40:15 2009
@@ -18,24 +18,35 @@
  */
 package org.apache.myfaces.shared.renderkit.html;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.myfaces.shared.component.DisplayValueOnlyCapable;
-import org.apache.myfaces.shared.component.EscapeCapable;
-import org.apache.myfaces.shared.config.MyfacesConfig;
-import org.apache.myfaces.shared.renderkit.JSFAttr;
-import org.apache.myfaces.shared.renderkit.RendererUtils;
-import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
-import org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder;
-import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
 
 import javax.faces.FacesException;
 import javax.faces.application.ConfigurableNavigationHandler;
 import javax.faces.application.NavigationCase;
 import javax.faces.application.NavigationHandler;
 import javax.faces.application.ViewHandler;
-import javax.faces.component.*;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIOutcomeTarget;
+import javax.faces.component.UIOutput;
+import javax.faces.component.UIParameter;
+import javax.faces.component.UISelectBoolean;
+import javax.faces.component.UISelectMany;
+import javax.faces.component.UISelectOne;
+import javax.faces.component.UIViewRoot;
 import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorContext;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlDataTable;
 import javax.faces.component.html.HtmlPanelGrid;
@@ -45,8 +56,19 @@
 import javax.faces.convert.Converter;
 import javax.faces.model.SelectItem;
 import javax.faces.model.SelectItemGroup;
-import java.io.IOException;
-import java.util.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.shared.component.DisplayValueOnlyCapable;
+import org.apache.myfaces.shared.component.EscapeCapable;
+import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
+import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
+import org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
+import org.apache.myfaces.shared.util.StringUtils;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
@@ -83,6 +105,7 @@
     + "  You cannot submit a form after disabling an input element via javascript."
     + "  Consider setting read-only to true instead"
     + " or resetting the disabled value back to false prior to form submission.";
+    private static final String STR_EMPTY = "";
 
 
     private HtmlRendererUtils() {
@@ -249,6 +272,11 @@
         }
     }
     
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param component
+     */
     public static void decodeClientBehaviors(FacesContext facesContext,
             UIComponent component)
     {
@@ -370,8 +398,22 @@
         } else {
             writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null);
         }
-        renderHTMLAttributes(writer, uiComponent,
-                             HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+            
+            renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
+            renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+            renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, behaviors);
+            renderHTMLAttributes(writer, uiComponent, HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
+        }
+        else
+        {
+            renderHTMLAttributes(writer, uiComponent,
+                    HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+        }
+
         if (disabled) {
             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
         }
@@ -386,7 +428,7 @@
         renderSelectOptions(facesContext, uiComponent, converter, lookupSet,
                             selectItemList);
         // bug #970747: force separate end tag
-        writer.writeText("", null);
+        writer.writeText(STR_EMPTY, null);
         writer.endElement(HTML.SELECT_ELEM);
     }
 
@@ -772,7 +814,7 @@
                                       selectItemList, isSelectOne);
 
             // bug #970747: force separate end tag
-            writer.writeText("", null);
+            writer.writeText(STR_EMPTY, null);
             writer.endElement(isSelectOne ? HTML.SPAN_ELEM : HTML.UL_ELEM);
         }
 
@@ -1062,7 +1104,7 @@
         context.prettyLine();
         context.append("if(typeof form.elements[name]!='undefined' && form.elements[name].nodeName=='INPUT')");
         context.append("{");
-        context.append("form.elements[name].value=value;");        
+        context.append("form.elements[name].value=value;");
         context.append("}");
         context.append("else");
         context.append("{");
@@ -1130,9 +1172,9 @@
             context.append("if (agentString.indexOf('msie') != -1)");
         
             context.append("{");
-            context.append("if (!(agentString.indexOf('ppc') != -1 && agentString.indexOf('windows ce') != -1 && version >= 4.0))");              
+            context.append("if (!(agentString.indexOf('ppc') != -1 && agentString.indexOf('windows ce') != -1 && version >= 4.0))");
             context.append("{");
-            context.append("window.external.AutoCompleteSaveForm(form);");        
+            context.append("window.external.AutoCompleteSaveForm(form);");
 //        context.append("isIE = false;");
             context.append("}");
 //        context.append("else");
@@ -1193,10 +1235,10 @@
         context.append("else ");
         context.append("{");
         context.append("try");
-        context.append("{");        
+        context.append("{");
         context.append("form.submit();");
         context.append("}");
-        context.append("catch(e){}");        
+        context.append("catch(e){}");
         context.append("}");
 
         //reset the target
@@ -1211,7 +1253,7 @@
         context.append("if((typeof params!='undefined') && params != null)");
         context.append("{");
         context.prettyLine();
-        context.append("for(var i=0, param; (param = params[i]); i++)");        
+        context.append("for(var i=0, param; (param = params[i]); i++)");
         context.append("{");
         context.append(CLEAR_HIDDEN_INPUT_FN_NAME).append("(formName,param[0], param[1]);");
         context.append("}");
@@ -1413,7 +1455,7 @@
     }
 
     /**
-     * @deprecated Replaced by 
+     * @deprecated Replaced by
      * renderLabel(ResponseWriter writer,
                                    UIComponent component,
                                    String forClientId,
@@ -1526,16 +1568,16 @@
             
             if(selected)
             {
-                labelSelectedClass = (String) component.getAttributes().get(JSFAttr.SELECTED_CLASS_ATTR);    
+                labelSelectedClass = (String) component.getAttributes().get(JSFAttr.SELECTED_CLASS_ATTR);
             }
-            else 
+            else
             {
                 labelSelectedClass = (String) component.getAttributes().get(JSFAttr.UNSELECTED_CLASS_ATTR);
             }
             
             if(labelSelectedClass != null) 
             {
-                if(labelClass == null) 
+                if(labelClass == null)
                 {
                     labelClass = labelSelectedClass;
                 }
@@ -1688,7 +1730,7 @@
     }
 
     /**
-     * 
+     *
      * @param formInfo
      * @deprecated Use getHiddenCommandLinkFieldNameMyfaces(FormInfo) instead
      * @return
@@ -1707,7 +1749,7 @@
         
         // The href for an HtmlOutcomeTargetLink is outcome#fragment.
         
-        href = ((href == null) ? "" : href.trim());
+        href = ((href == null) ? STR_EMPTY : href.trim());
         
         // Get the correct URL for the outcome.
         
@@ -1903,6 +1945,471 @@
         return (String)component.getAttributes().get(JSFAttr.STYLE_LOCATION);
     }
 
+    /**
+     * checks if the given component has behaviors attachements
+     * 
+     * @since 4.0.0
+     * @param eventName the event name to be checked for
+     * @param uiComponent the component which possibly has attached client behaviors
+     * @return true if client behaviors are attached, false otherwise
+     */
+    public static boolean hasClientBehavior(String eventName,
+            Map<String, List<ClientBehavior>> behaviors,
+            FacesContext facesContext)
+    {
+        if (behaviors == null)
+        {
+            return false;
+        }
+        return (behaviors.get(eventName) != null);
+    }
+
+    /**
+    * builds the chained behavior script which then can be reused
+    * in following order by the other script building parts
+    *
+    * user defined event handling script
+    * behavior script
+    * renderer default script
+    *
+    * @since 4.0.0
+    * @param eventName event name ("onclick" etc...)
+    * @param uiComponent   the component which has the attachement (or should have)
+    * @param facesContext  the facesContext
+    * @param params    params map of params which have to be dragged into the request
+    * @return a string representation of the javascripts for the attached event behavior, an empty string if none is present
+    */
+    private static void getClientBehaviorScript(FacesContext facesContext,
+            UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors,
+            ScriptContext target, String eventName, Map<String, String> params)
+    {
+        if (!(uiComponent instanceof ClientBehaviorHolder))
+        {
+            target.append(STR_EMPTY);
+            return;
+        }
+
+        ExternalContext externalContext = facesContext.getExternalContext();
+
+        boolean renderClientBehavior = JavascriptUtils
+                .isJavascriptAllowed(externalContext)
+                && clientBehaviors != null && clientBehaviors.size() > 0;
+        if (!renderClientBehavior)
+        {
+            target.append(STR_EMPTY);
+            return;
+        }
+
+        List<ClientBehavior> attachedEventBehaviors = clientBehaviors
+                .get(eventName);
+        if (attachedEventBehaviors == null
+                || attachedEventBehaviors.size() == 0)
+        {
+            target.append(STR_EMPTY);
+            return;
+        }
+
+        List<ClientBehaviorContext.Parameter> paramList = null;
+        if (params != null)
+        {
+            paramList = new ArrayList<ClientBehaviorContext.Parameter>(
+                    params.size());
+            for (Map.Entry<String, String> paramEntry : params.entrySet())
+            {
+                paramList.add(new ClientBehaviorContext.Parameter(paramEntry
+                        .getKey(), paramEntry.getValue()));
+            }
+        }
+
+        ClientBehaviorContext context = ClientBehaviorContext
+                .createClientBehaviorContext(facesContext, uiComponent,
+                        eventName, uiComponent.getClientId(facesContext),
+                        paramList);
+
+        Iterator<ClientBehavior> clientIterator = attachedEventBehaviors
+                .iterator();
+        while (clientIterator.hasNext())
+        {
+
+            //either strings or functions, but I assume string is more appropriate since it allows access to the
+            //origin as this!
+            target.append("'"
+                    + StringUtils.replace(clientIterator.next().getScript(context), '\'', "\\'") + "'");
+            if (clientIterator.hasNext())
+            {
+                target.append(", ");
+            }
+        }
+
+        return;
+    }
+
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param uiComponent
+     * @param clientBehaviors
+     * @param eventName
+     * @param userEventCode
+     * @param serverEventCode
+     * @param params
+     * @return
+     */
+    public static String buildBehaviorChain(FacesContext facesContext,
+            UIComponent uiComponent, Map<String, List<ClientBehavior>> clientBehaviors,
+            String eventName,             
+            String userEventCode, String serverEventCode,
+            Map<String, String> params)
+    {
+        ExternalContext externalContext = facesContext.getExternalContext();
+        boolean renderCode = JavascriptUtils
+                .isJavascriptAllowed(externalContext);
+        if (!renderCode)
+        {
+            return STR_EMPTY;
+        }
+        List<String> finalParams = new ArrayList<String>(3);
+        if (userEventCode != null && !userEventCode.trim().equals(STR_EMPTY))
+        {
+            finalParams.add('\''+userEventCode+'\'');
+        }
+
+        final MyfacesConfig currentInstance = MyfacesConfig
+                .getCurrentInstance(externalContext);
+        ScriptContext behaviorCode = new ScriptContext();
+        ScriptContext retVal = new ScriptContext(currentInstance.isPrettyHtml());
+
+        getClientBehaviorScript(facesContext, uiComponent, clientBehaviors, 
+                behaviorCode, eventName, params);
+        if (behaviorCode != null
+                && !behaviorCode.toString().trim().equals(STR_EMPTY))
+        {
+            finalParams.add(behaviorCode.toString());
+        }
+        if (serverEventCode != null
+                && !serverEventCode.trim().equals(STR_EMPTY))
+        {
+            finalParams.add('\''+serverEventCode+'\'');
+        }
+        Iterator<String> it = finalParams.iterator();
+
+        //according to the spec jsf.util.chain has to be used to build up the behavior and scripts
+        retVal.append("jsf.util.chain(document.getElementById('"
+                + uiComponent.getClientId(facesContext) + "'), event,");
+        while (it.hasNext())
+        {
+            retVal.append(it.next());
+            if(it.hasNext())
+            {
+                retVal.append(", ");
+            }
+        }
+        retVal.append(");");
+        return retVal.toString();
+
+    }
+
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param uiComponent
+     * @param clientBehaviors
+     * @param eventName1
+     * @param eventName2
+     * @param userEventCode
+     * @param serverEventCode
+     * @param params
+     * @return
+     */
+    public static String buildBehaviorChain(FacesContext facesContext,
+            UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors,
+            String eventName1, String eventName2, String userEventCode,
+            String serverEventCode, Map<String, String> params)
+    {
+        ExternalContext externalContext = facesContext.getExternalContext();
+        boolean renderCode = JavascriptUtils
+                .isJavascriptAllowed(externalContext);
+        if (!renderCode)
+        {
+            return STR_EMPTY;
+        }
+        List<String> finalParams = new ArrayList<String>(3);
+        if (userEventCode != null && !userEventCode.trim().equals(STR_EMPTY))
+        {
+            finalParams.add('\''+userEventCode+'\'');
+        }
+
+        final MyfacesConfig currentInstance = MyfacesConfig
+                .getCurrentInstance(externalContext);
+        ScriptContext behaviorCode = new ScriptContext();
+        ScriptContext retVal = new ScriptContext(currentInstance.isPrettyHtml());
+
+        getClientBehaviorScript(facesContext, uiComponent, clientBehaviors, 
+                behaviorCode, eventName1, params);
+        getClientBehaviorScript(facesContext, uiComponent, clientBehaviors, 
+                behaviorCode, eventName2, params);
+
+        if (behaviorCode != null
+                && !behaviorCode.toString().trim().equals(STR_EMPTY))
+        {
+            finalParams.add(behaviorCode.toString());
+        }
+        if (serverEventCode != null
+                && !serverEventCode.trim().equals(STR_EMPTY))
+        {
+            finalParams.add('\''+serverEventCode+'\'');
+        }
+        Iterator<String> it = finalParams.iterator();
+
+        //according to the spec jsf.util.chain has to be used to build up the behavior and scripts
+        retVal.append("jsf.util.chain(document.getElementById('"
+                + uiComponent.getClientId(facesContext) + "'), event,");
+        while (it.hasNext())
+        {
+            retVal.append(it.next());
+            if (it.hasNext())
+            {
+                retVal.append(", ");
+            }
+        }
+        retVal.append(");");
+        return retVal.toString();
+
+    }
+    
+    /**
+     * 
+     * 
+     * @param facesContext
+     * @param uiComponent
+     * @return
+     */
+    public static Map<String, String> mapAttachedParamsToStringValues(FacesContext facesContext, UIComponent uiComponent) {
+        Map<String, String> retVal = new HashMap<String, String>();
+
+        //we cannot use invokeContextCallback
+        
+        for (Iterator<UIComponent> it = uiComponent.getFacetsAndChildren(); it.hasNext();) {
+            UIComponent target = it.next();
+            if (!(target instanceof UIParameter)) continue;
+            UIParameter param = (UIParameter) target;
+            if (param.isRendered() && param.getValue() != null) {
+                String name = param.getName();
+                Object value = param.getValue();
+                if (value instanceof String) {
+                    value = "'" + ((String) value) + "'";
+                }
+                retVal.put(name, value.toString());
+            }
+        }
+        return retVal;
+   }
+    
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param writer
+     * @param component
+     * @param clientBehaviors
+     * @param eventName
+     * @param componentProperty
+     * @param htmlAttrName
+     * @return
+     * @throws IOException
+     */
+    public static boolean renderBehaviorizedAttribute(
+            FacesContext facesContext, ResponseWriter writer,
+            UIComponent component, Map<String, List<ClientBehavior>> clientBehaviors, String eventName, String componentProperty, 
+            String htmlAttrName) throws IOException
+    {
+        List<ClientBehavior> cbl = clientBehaviors.get(eventName);
+        
+        if (cbl == null || cbl.size() == 0)
+        {
+            return renderHTMLAttribute(writer, component, componentProperty, htmlAttrName);
+        }
+        
+        String attrValue = (String) component.getAttributes().get(componentProperty);
+        if (cbl.size() > 1 || (cbl.size() == 1 && attrValue != null) )
+        {
+            Object value = HtmlRendererUtils.buildBehaviorChain(facesContext,
+                    component, clientBehaviors, eventName, 
+                    attrValue, STR_EMPTY, null);
+            return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
+                    value);
+        }
+        else
+        {
+            //Only 1 behavior and attrValue == null, so just render it directly
+            ClientBehaviorContext behaviorContext = ClientBehaviorContext
+                .createClientBehaviorContext(facesContext, component,
+                    eventName, component.getClientId(facesContext),
+                    null);
+            return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
+                    cbl.get(0).getScript(behaviorContext));
+        }
+    }
+
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param writer
+     * @param uiComponent
+     * @param clientBehaviors
+     * @throws IOException
+     */
+    public static void renderBehaviorizedEventHandlers(
+            FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors) throws IOException
+    {
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.CLICK, HTML.ONCLICK_ATTR, HTML.ONCLICK_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.DBLCLICK, HTML.ONDBLCLICK_ATTR, HTML.ONDBLCLICK_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEDOWN, HTML.ONMOUSEDOWN_ATTR, HTML.ONMOUSEDOWN_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEUP, HTML.ONMOUSEUP_ATTR, HTML.ONMOUSEUP_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEOVER, HTML.ONMOUSEOVER_ATTR, HTML.ONMOUSEOVER_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEMOVE, HTML.ONMOUSEMOVE_ATTR, HTML.ONMOUSEMOVE_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEOUT, HTML.ONMOUSEOUT_ATTR, HTML.ONMOUSEOUT_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.KEYPRESS, HTML.ONKEYPRESS_ATTR, HTML.ONKEYPRESS_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.KEYDOWN, HTML.ONKEYDOWN_ATTR, HTML.ONKEYDOWN_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.KEYUP, HTML.ONKEYUP_ATTR, HTML.ONKEYUP_ATTR);
+    }
+
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param writer
+     * @param uiComponent
+     * @param clientBehaviors
+     * @throws IOException
+     */
+    public static void renderBehaviorizedEventHandlersWithoutOnclick(
+            FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors) throws IOException
+    {
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.DBLCLICK, HTML.ONDBLCLICK_ATTR, HTML.ONDBLCLICK_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEDOWN, HTML.ONMOUSEDOWN_ATTR, HTML.ONMOUSEDOWN_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEUP, HTML.ONMOUSEUP_ATTR, HTML.ONMOUSEUP_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEOVER, HTML.ONMOUSEOVER_ATTR, HTML.ONMOUSEOVER_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEMOVE, HTML.ONMOUSEMOVE_ATTR, HTML.ONMOUSEMOVE_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.MOUSEOUT, HTML.ONMOUSEOUT_ATTR, HTML.ONMOUSEOUT_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.KEYPRESS, HTML.ONKEYPRESS_ATTR, HTML.ONKEYPRESS_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.KEYDOWN, HTML.ONKEYDOWN_ATTR, HTML.ONKEYDOWN_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.KEYUP, HTML.ONKEYUP_ATTR, HTML.ONKEYUP_ATTR);
+    }
+    
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param writer
+     * @param uiComponent
+     * @param clientBehaviors
+     * @throws IOException
+     */
+    public static void renderBehaviorizedFieldEventHandlers(
+            FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors) throws IOException
+    {
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.FOCUS, HTML.ONFOCUS_ATTR, HTML.ONFOCUS_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.BLUR, HTML.ONBLUR_ATTR, HTML.ONBLUR_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.CHANGE, HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.SELECT, HTML.ONSELECT_ATTR, HTML.ONSELECT_ATTR);
+    }
+    
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param writer
+     * @param uiComponent
+     * @param clientBehaviors
+     * @throws IOException
+     */
+    public static void renderBehaviorizedFieldEventHandlersWithoutOnchange(
+            FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors) throws IOException
+    {
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.FOCUS, HTML.ONFOCUS_ATTR, HTML.ONFOCUS_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.BLUR, HTML.ONBLUR_ATTR, HTML.ONBLUR_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.SELECT, HTML.ONSELECT_ATTR, HTML.ONSELECT_ATTR);
+    }
+    
+    public static void renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
+            FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors) throws IOException
+    {    
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.FOCUS, HTML.ONFOCUS_ATTR, HTML.ONFOCUS_ATTR);
+        renderBehaviorizedAttribute(facesContext, writer, uiComponent, clientBehaviors,
+                ClientBehaviorEvents.BLUR, HTML.ONBLUR_ATTR, HTML.ONBLUR_ATTR);
+    }
+    
+    /**
+     * @since 4.0.0
+     * @param facesContext
+     * @param writer
+     * @param uiComponent
+     * @param clientBehaviors
+     * @return
+     * @throws IOException
+     */
+    public static boolean renderBehaviorizedOnchangeEventHandler(
+            FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+            Map<String, List<ClientBehavior>> clientBehaviors) throws IOException
+    {
+        boolean hasChange = HtmlRendererUtils.hasClientBehavior(ClientBehaviorEvents.CHANGE, clientBehaviors, facesContext);
+        boolean hasValueChange = HtmlRendererUtils.hasClientBehavior(ClientBehaviorEvents.VALUECHANGE, clientBehaviors, facesContext); 
+        
+        if (hasChange && hasValueChange)
+        {
+            String chain = HtmlRendererUtils.buildBehaviorChain(facesContext,
+                    uiComponent, clientBehaviors, ClientBehaviorEvents.CHANGE, ClientBehaviorEvents.VALUECHANGE, 
+                    (String) uiComponent.getAttributes().get(HTML.ONCHANGE_ATTR), null, null);
+            
+            return HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR, chain);
+        }
+        else if (hasChange)
+        {
+            return HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, uiComponent, 
+                    clientBehaviors, ClientBehaviorEvents.CHANGE, HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR);                
+        }
+        else if (hasValueChange)
+        {
+            return HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, uiComponent, 
+                    clientBehaviors, ClientBehaviorEvents.VALUECHANGE, HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR);
+        }
+        else
+        {
+            return HtmlRendererUtils.renderHTMLAttribute(writer, uiComponent, HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR);
+        }
+    }
+
     public static void renderViewStateJavascript(FacesContext facesContext, String hiddenId, String serializedState) throws IOException {
         ResponseWriter writer = facesContext.getResponseWriter();