You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by al...@apache.org on 2010/07/31 00:37:34 UTC

svn commit: r980988 [3/8] - in /myfaces/gsoc/html5-comp-lib/trunk: ./ html5-comp-lib-core/ html5-comp-lib-core/src/ html5-comp-lib-core/src/main/ html5-comp-lib-core/src/main/java/ html5-comp-lib-core/src/main/java/META-INF/ html5-comp-lib-core/src/mai...

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,249 @@
+/*
+ * 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.html5.handler;
+
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.el.MethodExpression;
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.Behavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.BehaviorConfig;
+import javax.faces.view.facelets.ComponentHandler;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagException;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+import org.apache.myfaces.html5.behavior.DropTargetBehavior;
+import org.apache.myfaces.html5.event.DropEvent;
+import org.apache.myfaces.html5.event.DropListener;
+import org.apache.myfaces.html5.renderkit.util.ClientBehaviorEvents;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+
+@JSFFaceletTag(name = "fx:dropTarget")
+// TODO: doc me
+public class DropTargetBehaviorHandler extends javax.faces.view.facelets.BehaviorHandler
+{
+
+    private static final Logger log = Logger.getLogger(DropTargetBehaviorHandler.class.getName());
+
+    /**
+     * @see DropTargetBehavior#getAction()
+     */
+    @JSFFaceletAttribute(name = "action", className = "javax.el.ValueExpression", deferredValueType = "java.lang.String")
+    private final TagAttribute _action;
+
+    /**
+     * @see DropTargetBehavior#getTypes()
+     */
+    @JSFFaceletAttribute(name = "types", className = "javax.el.ValueExpression", deferredValueType = "java.lang.Object")
+    private final TagAttribute _types;
+
+    /**
+     * @see DropTargetBehavior#getAcceptMimeTypes()
+     */
+    @JSFFaceletAttribute(name = "acceptMimeTypes", className = "javax.el.ValueExpression", deferredValueType = "java.lang.Object")
+    private final TagAttribute _acceptMimeTypes;
+
+    /**
+     * @see DropTargetBehavior#getRerender()
+     */
+    @JSFFaceletAttribute(name = "rerender", className = "javax.el.ValueExpression", deferredValueType = "java.lang.Object")
+    private final TagAttribute _rerender;
+
+    /**
+     * Drop listener to trigger when a successful drop event is happened into this drop target. <br/>
+     * Listener method must have a signature of :
+     * <code>public void m(org.apache.myfaces.html5.event.DropEvent evt) throws javax.faces.event.AbortProcessingException</code>
+     * <br/>
+     * In the listener, application can get the parameter sent and other data sent.
+     */
+    @JSFFaceletAttribute(name = "dropListener", className = "javax.el.MethodExpression", deferredMethodSignature = "public void m(org.apache.myfaces.html5.event.DropEvent evt) throws javax.faces.event.AbortProcessingException")
+    private final TagAttribute _dropListener;
+
+    public DropTargetBehaviorHandler(BehaviorConfig config)
+    {
+        super(config);
+        _action = getAttribute("action");
+        _types = getAttribute("types");
+        _acceptMimeTypes = getAttribute("acceptMimeTypes");
+        _rerender = getAttribute("rerender");
+        _dropListener = getAttribute("dropListener");
+    }
+
+    @Override
+    public void apply(FaceletContext faceletContext, UIComponent parent)
+    {
+        if (!ComponentHandler.isNew(parent))
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("Component" + RendererUtils.getPathToComponent(parent)
+                        + " is not new, thus return without any operation.");
+            return;
+        }
+
+        if (parent instanceof ClientBehaviorHolder)
+        {
+            ClientBehaviorHolder holder = _getClientBehaviorHolder(parent);
+
+            FacesContext context = faceletContext.getFacesContext();
+            Application app = context.getApplication();
+            String behaviorId = getBehaviorId();
+            Behavior behavior = app.createBehavior(behaviorId);
+
+            if (!(behavior instanceof DropTargetBehavior))
+            {
+                throw new FacesException("Behavior is not a DropTargetBehavior");
+            }
+
+            // manually added all of the properties, so no need for this:
+            // setAttributes(faceletContext, behavior);
+
+            DropTargetBehavior dropTargetBehavior = (DropTargetBehavior) behavior;
+
+            if (_dropListener != null)
+            {
+
+                MethodExpression expr = _dropListener.getMethodExpression(faceletContext, Void.TYPE, new Class<?>[]
+                {
+                    DropEvent.class
+                });
+                dropTargetBehavior.addDropTargetBehaviorListener(new DropListener(expr));
+            }
+
+            // XXX: see https://issues.apache.org/jira/browse/MYFACES-2616
+            // see the thread http://www.mail-archive.com/dev@myfaces.apache.org/msg46764.html
+            // using the same approach in DropSourceBehavior too... see there for explanation!
+            if (_action != null)
+            {
+                if (_action.isLiteral())
+                {
+                    dropTargetBehavior.setAction(_action.getValue(faceletContext));
+                }
+                else
+                {
+                    dropTargetBehavior.setValueExpression("action", _action.getValueExpression(faceletContext,
+                            String.class));
+                }
+            }
+            if (_types != null)
+            {
+                if (_types.isLiteral())
+                {
+                    dropTargetBehavior.setTypes(_types.getObject(faceletContext));
+                }
+                else
+                {
+                    dropTargetBehavior.setValueExpression("types", _types.getValueExpression(faceletContext,
+                            Object.class));
+                }
+            }
+            if (_acceptMimeTypes != null)
+            {
+                if (_acceptMimeTypes.isLiteral())
+                {
+                    dropTargetBehavior.setAcceptMimeTypes(_acceptMimeTypes.getObject(faceletContext));
+                }
+                else
+                {
+                    dropTargetBehavior.setValueExpression("acceptMimeTypes", _acceptMimeTypes.getValueExpression(
+                            faceletContext, Object.class));
+                }
+            }
+            if (_rerender != null)
+            {
+                if (_rerender.isLiteral())
+                {
+                    dropTargetBehavior.setRerender(_rerender.getObject(faceletContext));
+                }
+                else
+                {
+                    dropTargetBehavior.setValueExpression("rerender", _rerender.getValueExpression(faceletContext,
+                            Object.class));
+                }
+            }
+
+            holder.addClientBehavior(ClientBehaviorEvents.DRAGENTER_EVENT, dropTargetBehavior);
+            holder.addClientBehavior(ClientBehaviorEvents.DRAGOVER_EVENT, dropTargetBehavior);
+            holder.addClientBehavior(ClientBehaviorEvents.DROP_EVENT, dropTargetBehavior);
+        }
+        // XXX: check this out
+        /*
+         * else if (UIComponent.isCompositeComponent(parent)) { // COPIED FROM AjaxHandler! // It is supposed that for
+         * composite components, this tag should // add itself as a target, but note that on whole api does not exists
+         * // some tag that expose client behaviors as targets for composite // components. In RI, there exists a tag
+         * called composite:clientBehavior, // but does not appear on spec or javadoc, maybe because this could be //
+         * understand as an implementation detail, after all there exists a key // called
+         * AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY that could be // used to create a tag outside jsf
+         * implementation to attach targets. CompositeComponentResourceTagHandler.addAttachedObjectHandler(parent,
+         * this); }
+         */
+    }
+
+    private ClientBehaviorHolder _getClientBehaviorHolder(UIComponent parent)
+    {
+        if (!(parent instanceof ClientBehaviorHolder))
+        {
+            throw new TagException(getTag(),
+                    "DropTargetBehavior must be attached to a ClientBehaviorHolder parent. Component "
+                            + RendererUtils.getPathToComponent(parent) + "is not a ClientBehaviorHolder");
+        }
+
+        ClientBehaviorHolder holder = (ClientBehaviorHolder) parent;
+
+        _checkEvent(holder, ClientBehaviorEvents.DRAGENTER_EVENT);
+        _checkEvent(holder, ClientBehaviorEvents.DRAGOVER_EVENT);
+        _checkEvent(holder, ClientBehaviorEvents.DROP_EVENT);
+
+        return holder;
+    }
+
+    private void _checkEvent(ClientBehaviorHolder holder, String eventName)
+    {
+        Collection<String> eventNames = holder.getEventNames();
+
+        if (!eventNames.contains(eventName))
+        {
+            StringBuilder message = new StringBuilder();
+            message.append("Unable to attach DropTargetBehavior.  ");
+            message.append("DropTargetBehavior may only be attached to ");
+            message.append("ClientBehaviorHolders that support the '");
+            message.append(eventName);
+            message.append("' event.  The parent ClientBehaviorHolder "
+                    + RendererUtils.getPathToComponent((UIComponent) holder) + " only ");
+            message.append("supports the following events: ");
+
+            for (String supportedEventName : eventNames)
+            {
+                message.append(supportedEventName);
+                message.append(" ");
+            }
+
+            throw new TagException(getTag(), message.toString());
+        }
+    }
+
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,139 @@
+/*
+ * 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.html5.handler;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagHandler;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+import org.apache.myfaces.html5.holder.MediaSourceHolder;
+import org.apache.myfaces.html5.model.MediaInfo;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+
+/**
+ * Provides media sources for media components. This should be nested inside of an instance of {@link MediaSourceHolder}
+ * . Creates a {@link MediaInfo} and adds it to parent component's media info set.
+ * <br/>
+ * Even if 'disabled' is set to true, created {@link MediaInfo} instance will be added. In this case, renderer of the
+ * parent media component should ignore that instance.
+ * 
+ * @author Ali Ok
+ * @see MediaSourceHolder
+ */
+@JSFFaceletTag(name = "fx:mediaSource")
+public class MediaSourceHandler extends TagHandler
+{
+
+    private static final Logger log = Logger.getLogger(MediaSourceHandler.class.getName());
+
+    /**
+     * URL of the media source. This attribute is required.
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.String", required = true)
+    private final TagAttribute src;
+
+    /**
+     * MIME content type of the resource (for example : "video/ogg")
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.String")
+    private final TagAttribute contentType;
+
+    /**
+     * Codecs of the resource (for example: "avc1.64001E, mp4a.40.2"). If this property is defined, contentType property
+     * should be defined too.
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.String")
+    private final TagAttribute codec;
+
+    /**
+     * This property defines the intended media type of the media resource, to help the browser determine if this media
+     * resource is useful to the user before fetching it. Its value must be a valid media query. Just like the "@media"
+     * declaration in CSS.
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.String")
+    private final TagAttribute media;
+
+    /**
+     * If set to true, renderer of the parent{@link MediaSourceHolder} will ignore this resource.
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.Boolean")
+    private final TagAttribute disabled;
+
+    public MediaSourceHandler(TagConfig config)
+    {
+        super(config);
+
+        this.src = getRequiredAttribute("src"); // this is required
+        this.codec = getAttribute("codec");
+        this.contentType = getAttribute("contentType");
+        this.media = getAttribute("media");
+        this.disabled = getAttribute("disabled");
+
+    }
+
+    public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException
+    {
+        if (!(parent instanceof MediaSourceHolder))
+        {
+            if (log.isLoggable(Level.WARNING))
+                log.warning("parent component " + RendererUtils.getPathToComponent(parent) + " is not a MediaSourceHolder. handler will not apply anything.");
+            return;
+        }
+        else
+        {
+            String valueVal = null;
+            String codecVal = null;
+            String contentTypeVal = null;
+            String mediaVal = null;
+            boolean disabledVal = false;
+
+            // src is required, no need to check nullness
+            valueVal = this.src.getValue(faceletContext);
+
+            if (this.codec != null)
+                codecVal = this.codec.getValue(faceletContext);
+
+            if (this.contentType != null)
+                contentTypeVal = this.contentType.getValue(faceletContext);
+
+            if (this.media != null)
+                mediaVal = this.media.getValue(faceletContext);
+
+            if (this.disabled != null)
+                disabledVal = this.disabled.getBoolean(faceletContext);
+
+            MediaInfo mediaInfo = new MediaInfo(valueVal, contentTypeVal, codecVal, mediaVal, disabledVal);
+
+            if (log.isLoggable(Level.FINE))
+                log.fine("MediaInfo instance created, adding it into parent's set.");
+
+            // add mediaInfo to parent
+            MediaSourceHolder msh = (MediaSourceHolder) parent;
+            msh.addMediaInfo(mediaInfo);
+        }
+    }
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,151 @@
+/*
+ * 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.html5.handler;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagHandler;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+import org.apache.myfaces.html5.holder.MediaSourceHolder;
+import org.apache.myfaces.html5.model.MediaInfo;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+
+/**
+ * Provides media sources for media components. This should be nested inside of an instance of {@link MediaSourceHolder}
+ * . Gets {@link MediaInfo} instances and adds them to parent component's media info set.
+ * <p>
+ * If 'disabled' is set to true, {@link MediaInfo} instances of "items" attribute will not be added.
+ * </p>
+ * 
+ * @author Ali Ok
+ * @see MediaSourceHolder
+ */
+@JSFFaceletTag(name = "fx:mediaSources")
+public class MediaSourcesHandler extends TagHandler
+{
+
+    private static final Logger log = Logger.getLogger(MediaSourcesHandler.class.getName());
+
+    /**
+     * Array/collection of {@link MediaInfo} instances to use in media elements. This attribute is required.
+     * 
+     * @see MediaSourceHolder
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.Object", required = true)
+    private final TagAttribute items;
+
+    /**
+     * If set to true, {@link MediaInfo} instances of "items" attribute will not be added.
+     */
+    @JSFFaceletAttribute(className = "javax.el.ValueExpression", deferredValueType = "java.lang.Boolean")
+    private final TagAttribute disabled;
+
+    public MediaSourcesHandler(TagConfig config)
+    {
+        super(config);
+
+        this.items = getRequiredAttribute("items"); // this is required
+        this.disabled = getAttribute("disabled");
+    }
+
+    @SuppressWarnings("unchecked")
+    public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException
+    {
+        /*
+         * algo: if this is not disabled and parent is a MediaSourceHolder - get value of 'items' attr - convert the
+         * value to one of MediaInfo[] or Collection<Info> - add elements of array/collection into parent's MediaInfo
+         * set
+         */
+
+        // if this is disabled, don't apply anything
+        if (this.disabled != null && this.disabled.getBoolean(faceletContext) == true)
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("'disabled' is true. handler will not apply anything.");
+
+            return;
+        }
+
+        if (!(parent instanceof MediaSourceHolder))
+        {
+            if (log.isLoggable(Level.WARNING))
+                log.warning("parent component " + RendererUtils.getPathToComponent(parent) + " is not a MediaSourceHolder. handler will not apply anything.");
+            return;
+        }
+
+        MediaSourceHolder msh = (MediaSourceHolder) parent;
+
+        if (this.items.isLiteral())
+            throw new FacesException("'items' attribute of <fx:mediaSources> cannot be literal.");
+
+        Object objItems = this.items.getObject(faceletContext);
+        if (objItems == null)
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("'items' is null. continue silently.");
+            return;
+        }
+
+        if (objItems instanceof MediaInfo[])
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("type of 'items' is MediaInfo[]");
+            MediaInfo[] mediaInfoArr = (MediaInfo[]) objItems;
+            msh.addMediaInfo(mediaInfoArr);
+        }
+        else if (objItems instanceof Collection)
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("type of 'items' is Collection<MediaInfo>");
+            Collection<MediaInfo> mediaInfoCollection = (Collection<MediaInfo>) objItems;
+            try
+            {
+                if (log.isLoggable(Level.FINE))
+                    log.fine("Trying to convert Collection<MediaInfo> to MediaInfo[]");
+                MediaInfo[] mediaInfoArr = mediaInfoCollection.toArray(new MediaInfo[0]);
+                msh.addMediaInfo(mediaInfoArr);
+            }
+            catch (ArrayStoreException e)
+            {
+                // if there is one non-MediaInfo element in the collection,
+                // we'll fall in here during conversion to array.
+
+                throw new FacesException(
+                        "All elements of 'items' attribute of <fx:mediaSources> must be an instance of MediaInfo class.",
+                        e);
+            }
+        }
+        else
+        {
+            throw new FacesException(
+                    "'items' attribute of <fx:mediaSources> must be an array or collection of MediaInfo instances. Type of the object provided : "
+                            + objItems.getClass());
+        }
+    }
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/holder/MediaSourceHolder.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/holder/MediaSourceHolder.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/holder/MediaSourceHolder.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/holder/MediaSourceHolder.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,46 @@
+/*
+ * 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.html5.holder;
+
+import java.util.Set;
+
+import org.apache.myfaces.html5.model.MediaInfo;
+
+/**
+ * This interface defines the capability of holding {@link MediaInfo} objects.
+ * 
+ * @author Ali Ok
+ * 
+ */
+public interface MediaSourceHolder
+{
+
+    /**
+     * Add media info to media info array/collection.
+     */
+    public void addMediaInfo(MediaInfo... mediaInfo);
+
+    /**
+     * Returns the {@link MediaInfo} instances held by this component.
+     * 
+     * @return
+     */
+    public Set<MediaInfo> getMediaInfos();
+
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/model/MediaInfo.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/model/MediaInfo.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/model/MediaInfo.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/model/MediaInfo.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,147 @@
+/*
+ * 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.html5.model;
+
+import org.apache.myfaces.html5.component.media.Video;
+import org.apache.myfaces.html5.handler.MediaSourceHandler;
+import org.apache.myfaces.html5.holder.MediaSourceHolder;
+
+/**
+ * Model of media resources to use at media elements.
+ * 
+ * @author Ali Ok
+ * 
+ * @see MediaSourceHolder
+ * @see MediaSourceHandler
+ * @see Video
+ */
+public class MediaInfo
+{
+
+    /*
+     * Fields are not final on purpose (to make this class extensible), even if they don't have setters.
+     */
+    protected String src;
+    protected String contentType;
+    protected String media;
+    protected String codec;
+    protected boolean disabled;
+
+    /**
+     * @param src
+     *            URL of the media resource
+     * @param contentType
+     *            MIME content type of the resource (for example : "video/ogg")
+     * @param codec
+     *            encoding method of the media resource. eg: "avc1.64001E, mp4a.40.2". If this is defined, it is an
+     *            error to not define contentType.
+     * @param media
+     *            Intended media type of the media resource. eg: "tv" or "3d-glasses"
+     * @param disabled
+     *            Is this media resource should not be rendered or used, this field should be set to true.
+     * 
+     */
+    public MediaInfo(String src, String contentType, String codec, String media, boolean disabled)
+    {
+        this.src = src;
+        this.contentType = contentType;
+        this.codec = codec;
+        this.media = media;
+        this.disabled = disabled;
+    }
+
+    // overloaded constructors
+
+    /**
+     * @see #MediaInfo(String, String, String, String, boolean)
+     */
+    public MediaInfo(String src, String contentType, String codec, String media)
+    {
+        this(src, contentType, codec, media, false);
+    }
+
+    /**
+     * @see #MediaInfo(String, String, String, String, boolean)
+     */
+    public MediaInfo(String src, String contentType, String codec)
+    {
+        this(src, contentType, codec, null);
+    }
+
+    /**
+     * @see #MediaInfo(String, String, String, String, boolean)
+     */
+    public MediaInfo(String src, String contentType)
+    {
+        this(src, contentType, null);
+    }
+
+    /**
+     * @see #MediaInfo(String, String, String, String, boolean)
+     */
+    public MediaInfo(String src)
+    {
+        this(src, null);
+    }
+
+    // getters
+
+    /**
+     * Returns the URL of the media source.
+     */
+    public String getSrc()
+    {
+        return src;
+    }
+
+    /**
+     * Returns the MIME content type of the resource (for example : "video/ogg");
+     */
+    public String getContentType()
+    {
+        return contentType;
+    }
+
+    /**
+     * Returns the intended media type of the media resource, to help the browser determine if this media resource is
+     * useful to the user before fetching it. Returned value is a valid media query. Just like the "@media" declaration
+     * in CSS.
+     */
+    public String getMedia()
+    {
+        return media;
+    }
+
+    /**
+     * Returns the codecs of the resource (for example: "avc1.64001E, mp4a.40.2").
+     */
+    public String getCodec()
+    {
+        return codec;
+    }
+
+    /**
+     * If set to true, media renderer will ignore this resource.
+     */
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DragSourceBehaviorRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DragSourceBehaviorRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DragSourceBehaviorRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DragSourceBehaviorRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,87 @@
+/*
+ * 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.html5.renderkit.behavior;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorContext;
+import javax.faces.render.ClientBehaviorRenderer;
+
+import org.apache.myfaces.html5.behavior.DragSourceBehavior;
+import org.apache.myfaces.html5.renderkit.util.BehaviorScriptUtils;
+import org.apache.myfaces.html5.renderkit.util.ClientBehaviorEvents;
+import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
+
+/**
+ * Renderer of {@link DragSourceBehavior} behaviors. <br/>
+ * This class only handles the script of "dragstart" event.
+ * 
+ * @author Ali Ok
+ * 
+ */
+public class DragSourceBehaviorRenderer extends ClientBehaviorRenderer
+{
+    private static final Logger log = Logger.getLogger(DragSourceBehaviorRenderer.class.getName());
+
+    @Override
+    public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior)
+    {
+        if (!(behavior instanceof DragSourceBehavior))
+        {
+            throw new FacesException("Behavior is not a DragSourceBehavior.");
+        }
+
+        String eventName = behaviorContext.getEventName();
+        if (ClientBehaviorEvents.DRAGSTART_EVENT.equals(eventName))
+        {
+            return _getDragStartScript((DragSourceBehavior) behavior);
+        }
+        else
+        {
+            if (log.isLoggable(Level.WARNING))
+                log.warning("Event " + eventName
+                        + " applied to DragSourceBehavior is not 'dragstart'. Ignoring the script.");
+
+            return null;
+        }
+    }
+
+    private String _getDragStartScript(DragSourceBehavior behavior)
+    {
+        String[] dropTargetTypes = Html5RendererUtils.resolveStrings(behavior.getDropTargetTypes());
+
+        String jsDropTargetTypes = BehaviorScriptUtils.convertToSafeJavascriptLiteralArray(dropTargetTypes);
+        String jsParam = BehaviorScriptUtils.convertToSafeJavascriptLiteral(behavior.getParam());
+        String jsAction = BehaviorScriptUtils.convertToSafeJavascriptLiteral(behavior.getAction());
+
+        //sample : return myfaces.html5.dragStart(event, 'move', {'A','B'), 'LAL');
+        String format = "return myfaces.html5.dragStart(event, %s, %s, %s);";
+        String script = String.format(format, jsAction,
+                jsDropTargetTypes, jsParam);
+
+        return script;
+    }
+
+
+    
+
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DropTargetBehaviorRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DropTargetBehaviorRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DropTargetBehaviorRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/behavior/DropTargetBehaviorRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,235 @@
+/*
+ * 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.html5.renderkit.behavior;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+import javax.faces.render.ClientBehaviorRenderer;
+
+import org.apache.myfaces.html5.behavior.DropTargetBehavior;
+import org.apache.myfaces.html5.event.DropEvent;
+import org.apache.myfaces.html5.renderkit.util.BehaviorScriptUtils;
+import org.apache.myfaces.html5.renderkit.util.ClientBehaviorEvents;
+import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
+
+/**
+ * Renderer of the fx:dropTarget behavior.
+ * 
+ * @author Ali Ok
+ * 
+ */
+public class DropTargetBehaviorRenderer extends ClientBehaviorRenderer
+{
+
+    private static final Logger log = Logger.getLogger(DropTargetBehaviorRenderer.class.getName());
+
+    /**
+     * Mime type to define the source of the drag. If Javascript transfer data has a data set with this key, than we can
+     * assume the source of the drag is a MyFaces Html5 component.
+     */
+    public static final String DEFAULT_MYFACES_MIME_TYPE = "text/x-myfaces-html5-dnd-source";
+
+    /**
+     * On a succesful drop, types of the data sent to server will be post to server with this key.
+     */
+    private static final String MYFACES_DND_FOUND_MIME_TYPES_KEY = "org.apache.myfaces.dnd.foundMimeTypes";
+
+    /**
+     * Mime type of the param sent to server. Param defined in fx:dragSource is passed to drag&drop events with this key
+     * and sent to server with this key.
+     */
+    private static final String MYFACES_HTML5_DND_PARAM_MIME_TYPE = "text/x-myfaces-html5-dnd-param";
+
+    private static Set<String> ALLOWED_ACTIONS = new HashSet<String>(Arrays.asList("copy", "move", "link", "copyLink",
+            "copyMove", "linkMove", "all", "none"));
+
+    @Override
+    public void decode(FacesContext context, UIComponent component, ClientBehavior behavior)
+    {
+
+        if (!(behavior instanceof DropTargetBehavior))
+        {
+            throw new FacesException("The behavior must be an instance of DropTargetBehavior");
+        }
+
+        super.decode(context, component, behavior);
+
+        DropTargetBehavior dropTargetBehavior = (DropTargetBehavior) behavior;
+        // XXX: do we need a disabled attr on dropTargetBehavior?
+        // if (dropTargetBehavior.isDisabled() || !component.isRendered()) {
+        if (!component.isRendered())
+        {
+            return;
+        }
+
+        dispatchBehaviorEvent(context, component, dropTargetBehavior);
+    }
+
+    /**
+     * Dispatches the {@link DropEvent} with appropriate parameter and data information.
+     */
+    protected void dispatchBehaviorEvent(FacesContext context, UIComponent component,
+            DropTargetBehavior dropTargetBehavior)
+    {
+        Map<String, String> requestParameterMap = context.getExternalContext().getRequestParameterMap();
+
+        // get value of param set in fx:dragSource
+        String param = requestParameterMap.get(MYFACES_HTML5_DND_PARAM_MIME_TYPE);
+        if (param == null || param.isEmpty())
+            param = null;
+
+        // get other data values with accepted mime types
+        Map<String, String> dropDataMap = null;
+        String strReceivedDataMimeTypes = requestParameterMap.get(MYFACES_DND_FOUND_MIME_TYPES_KEY);
+        if (strReceivedDataMimeTypes != null && !strReceivedDataMimeTypes.isEmpty())
+        {
+            dropDataMap = new HashMap<String, String>();
+
+            String[] receivedDataMimeTypes = Html5RendererUtils.resolveStrings(strReceivedDataMimeTypes);
+            for (String mimeType : receivedDataMimeTypes)
+            {
+                if (mimeType.equals(MYFACES_HTML5_DND_PARAM_MIME_TYPE))
+                    // param is set already, pass
+                    continue;
+
+                String data = requestParameterMap.get(mimeType);
+                if (data != null && !data.isEmpty())
+                {
+                    dropDataMap.put(mimeType, data);
+                }
+            }
+        }
+
+        DropEvent event = new DropEvent(component, dropTargetBehavior, dropDataMap, param);
+
+        // XXX: do we need immediate stuff on drop event?
+        // PhaseId phaseId = dropTargetBehavior.isImmediate() || isComponentImmediate(component) ?
+        // PhaseId.APPLY_REQUEST_VALUES :
+        // PhaseId.INVOKE_APPLICATION;
+
+        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
+
+        component.queueEvent(event);
+    }
+
+    @Override
+    public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior)
+    {
+        if (!(behavior instanceof DropTargetBehavior))
+        {
+            throw new FacesException("Behavior is not a DropTargetBehavior");
+        }
+
+        String eventName = behaviorContext.getEventName();
+        if (eventName.equals(ClientBehaviorEvents.DRAGENTER_EVENT)
+                || eventName.equals(ClientBehaviorEvents.DRAGOVER_EVENT))
+        {
+            return _getDragEnterOrOverScript((DropTargetBehavior) behavior);
+        }
+        else if (eventName.equals(ClientBehaviorEvents.DROP_EVENT))
+        {
+            return _getDropScript(behaviorContext, (DropTargetBehavior) behavior);
+        }
+        else
+        {
+            if (log.isLoggable(Level.WARNING))
+                log.warning("Event "
+                        + eventName
+                        + " is not one of "
+                        + Arrays.toString(new String[]
+                        {
+                                ClientBehaviorEvents.DRAGENTER_EVENT, ClientBehaviorEvents.DRAGOVER_EVENT,
+                                ClientBehaviorEvents.DROP_EVENT
+                        }) + ". Ignoring the script.");
+
+            return null;
+        }
+    }
+
+    private String _getDragEnterOrOverScript(DropTargetBehavior behavior)
+    {
+        String action = behavior.getAction() != null ? behavior.getAction().toString() : null;
+        String[] types = Html5RendererUtils.resolveStrings(behavior.getTypes());
+        String[] acceptMimeTypes = Html5RendererUtils.resolveStrings(behavior.getAcceptMimeTypes(), new String[]
+        {
+            DEFAULT_MYFACES_MIME_TYPE
+        });
+
+        // it is better to check the action is one of allowed, isn't it? So, if user types 'cpy' instead of 'copy',
+        // he/she will easily understand what is wrong. Other way, he/she has to watch the browser's javascript console.
+        _checkAction(action);
+
+        String jsAction = BehaviorScriptUtils.convertToSafeJavascriptLiteral(action);
+        String jsTypes = BehaviorScriptUtils.convertToSafeJavascriptLiteralArray(types);
+        String jsAcceptMimeTypes = BehaviorScriptUtils.convertToSafeJavascriptLiteralArray(acceptMimeTypes);
+
+        // sample:: return dragEnterOrOver(event,'move',['firstdropTargetType'], ['text/x-myfaces-html5-dnd-source']);
+        String format = "return myfaces.html5.dragEnterOrOver(event, %s, %s, %s);";
+        String script = String.format(format, jsAction, jsTypes, jsAcceptMimeTypes);
+
+        return script;
+    }
+
+    private void _checkAction(String action)
+    {
+        if (action == null || action.isEmpty())
+            return;
+
+        if (ALLOWED_ACTIONS.contains(action))
+            return;
+        else
+            throw new FacesException("Action of dropTarget is not one of allowed values "
+                    + Arrays.toString(ALLOWED_ACTIONS.toArray(new String[0])) + " but " + action);
+    }
+
+    private String _getDropScript(ClientBehaviorContext behaviorContext, DropTargetBehavior behavior)
+    {
+
+        String sourceId = behaviorContext.getSourceId();
+        String[] rerender = Html5RendererUtils.resolveStrings(behavior.getRerender());
+        String[] acceptMimeTypes = Html5RendererUtils.resolveStrings(behavior.getAcceptMimeTypes(), new String[]
+        {
+            DEFAULT_MYFACES_MIME_TYPE
+        });
+
+        String jsSourceId = (sourceId == null) ? "this" : BehaviorScriptUtils.convertToSafeJavascriptLiteral(sourceId);
+        String jsAcceptMimeTypes = BehaviorScriptUtils.convertToSafeJavascriptLiteralArray(acceptMimeTypes);
+        String jsRerender = BehaviorScriptUtils.convertToSpaceSeperatedJSLiteral(rerender);
+
+        // sample:: return myfaces.html5.drop(event, 'drop_zone', '@this someId',
+        // ['text/x-myfaces-html5-dnd-source','text/plain']);
+        String format = "return myfaces.html5.drop(event, %s, %s, %s);";
+        String script = String.format(format, jsSourceId, jsRerender, jsAcceptMimeTypes);
+
+        return script;
+    }
+
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,161 @@
+/*
+ * 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.html5.renderkit.input;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.html5.component.input.Html5BaseInputText;
+import org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.JsfProperties;
+import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.shared_html5.renderkit.html.HtmlTextRendererBase;
+import org.apache.myfaces.shared_html5.renderkit.html.util.ResourceUtils;
+
+/**
+ * An extensible base of the Html5 input renderers.
+ * 
+ * @author Ali Ok
+ * 
+ */
+public abstract class Html5BaseInputTextRenderer extends HtmlTextRendererBase
+{
+
+    private static final Logger log = Logger.getLogger(Html5BaseInputTextRenderer.class.getName());
+
+    @Override
+    public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
+    {
+        RendererUtils.checkParamValidity(facesContext, uiComponent, getComponentClass());
+
+        Html5BaseInputText component = (Html5BaseInputText) uiComponent;
+
+        // first, check whether we have behaviors, and render jsf.js if necessary
+        Map<String, List<ClientBehavior>> behaviors = null;
+        behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
+        if (!behaviors.isEmpty())
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("component " + RendererUtils.getPathToComponent(uiComponent) + " has behaviors, rendering jsf.js");
+
+            ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
+        }
+
+        // check suggestions
+        SuggestionRendererHelper suggestionRendererHelper = getSuggestionRendererHelper(component);
+        if (suggestionRendererHelper != null)
+            suggestionRendererHelper.checkSuggestions(component);
+
+        // are suggestions available?
+        boolean shouldGenerateDatalist = false;
+
+        if (suggestionRendererHelper != null)
+        {
+            shouldGenerateDatalist = suggestionRendererHelper.shouldGenerateDatalist(component);
+            if (shouldGenerateDatalist)
+            {
+                String datalistId = facesContext.getViewRoot().createUniqueId();
+                if (log.isLoggable(Level.FINE))
+                    log.fine("datalist will be created with id '" + datalistId + "'");
+                component.getAttributes().put(JsfProperties.DATALIST_PROP, datalistId);
+            }
+        }
+
+        // render the input
+        if (log.isLoggable(Level.FINE))
+            log.fine("will render input");
+        renderInput(facesContext, component);
+
+        // render suggestions
+        if (suggestionRendererHelper != null && shouldGenerateDatalist)
+        {
+            if (log.isLoggable(Level.FINE))
+                log.fine("will render generated datalist");
+            suggestionRendererHelper.renderDataList(facesContext, component);
+        }
+    }
+
+    @Override
+    protected void renderInputBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
+    {
+        RendererUtils.checkParamValidity(facesContext, uiComponent, getComponentClass());
+
+        // let parent render standard attributes
+        super.renderInputBegin(facesContext, uiComponent);
+
+        if (log.isLoggable(Level.FINE))
+            log.fine("parent rendered standart stuff. rendering additional pass thru attrs");
+        
+        renderPassThruAttrsAndEvents(facesContext, uiComponent);
+    }
+
+    //to make this extendible
+    protected void renderPassThruAttrsAndEvents(FacesContext facesContext, UIComponent uiComponent)
+            throws IOException
+    {
+        Map<String, List<ClientBehavior>> clientBehaviors = ((ClientBehaviorHolder)uiComponent).getClientBehaviors();
+        
+        Html5RendererUtils.renderPassThroughClientBehaviorEventHandlers(facesContext, uiComponent, PassThroughClientBehaviorEvents.BASE_INPUT, clientBehaviors);
+        
+        Html5RendererUtils.renderPassThroughAttributes(facesContext.getResponseWriter(), uiComponent, getExtraPassThroughAttributes());
+    }
+
+    @Override
+    protected void renderInputEnd(FacesContext facesContext, UIComponent component) throws IOException
+    {
+        // do nothing special. override for improving readability.
+        super.renderInputEnd(facesContext, component);
+    }
+
+    /**
+     * Returns pass through attributes that are not present in {@link javax.faces.component.html.HtmlInputText} Child
+     * component classes can override this method to modify pass through attributes, which are rendered at
+     * {@link Html5BaseInputTextRenderer#renderInputBegin(FacesContext, UIComponent)}
+     * 
+     */
+    protected abstract Map<String, String> getExtraPassThroughAttributes();
+
+    /**
+     * Component class to check the type of rendered component.
+     * 
+     */
+    protected abstract Class<? extends javax.faces.component.html.HtmlInputText> getComponentClass();
+
+    /**
+     * Returns the {@link SuggestionRendererHelper} instance, to render suggestion related markup.
+     * 
+     */
+    public abstract SuggestionRendererHelper getSuggestionRendererHelper(Html5BaseInputText component);
+
+    @Override
+    public boolean getRendersChildren()
+    {
+        return true;
+    }
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlDataListRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlDataListRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlDataListRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlDataListRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,53 @@
+/*
+ * 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.html5.renderkit.input;
+
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
+import org.apache.myfaces.html5.renderkit.input.delegate.HtmlDataListSuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper;
+
+//TODO: docme
+@JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Output", type = "org.apache.myfaces.html5.DataList")
+public class HtmlDataListRenderer extends Renderer
+{
+    private SuggestionRendererHelper _suggestionRendererHelper;
+
+    @Override
+    public boolean getRendersChildren()
+    {
+        return true;
+    }
+    
+    @Override
+    public void encodeEnd(FacesContext context, UIComponent component) throws IOException
+    {
+        super.encodeEnd(context, component);
+        
+        if (this._suggestionRendererHelper == null)
+            _suggestionRendererHelper = new HtmlDataListSuggestionRendererHelper();
+
+        _suggestionRendererHelper.renderDataList(context, component);
+    }
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,168 @@
+/*
+ * 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.html5.renderkit.input;
+
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.faces.FacesException;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
+import org.apache.myfaces.html5.component.input.Html5BaseInputText;
+import org.apache.myfaces.html5.component.input.HtmlInputColor;
+import org.apache.myfaces.html5.renderkit.input.delegate.HtmlTextInputSuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.util.HTML5;
+import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+
+/**
+ * Renderer for < hx:inputColor > component.
+ * 
+ * @author Ali Ok
+ * 
+ */
+@JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Input", type = "org.apache.myfaces.html5.Color")
+public class HtmlInputColorRenderer extends Html5BaseInputTextRenderer
+{
+
+    private HtmlTextInputSuggestionRendererHelper _suggestionRendererHelper;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.myfaces.shared_html5.renderkit.html.HtmlTextRendererBase#getConvertedValue(javax.faces.context.
+     * FacesContext, javax.faces.component.UIComponent, java.lang.Object)
+     * 
+     * This is overridden in order to validate the input without attaching a validator (or converter).
+     */
+    @Override
+    public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue)
+            throws ConverterException
+    {
+        if (submittedValue != null && !(submittedValue instanceof String))
+        {
+            throw new IllegalArgumentException("Submitted value of type String for component : "
+                    + RendererUtils.getPathToComponent(uiComponent) + "expected");
+        }
+
+        RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputColor.class);
+        HtmlInputColor component = (HtmlInputColor) uiComponent;
+
+        Converter converter;
+        try
+        {
+            converter = RendererUtils.findUIOutputConverter(facesContext, component);
+        }
+        catch (FacesException e)
+        {
+            throw new ConverterException(e);
+        }
+
+        if (converter == null)
+            converter = new ColorConverter();
+
+        return converter.getAsObject(facesContext, component, (String) submittedValue);
+    }
+
+    @Override
+    protected Map<String, String> getExtraPassThroughAttributes()
+    {
+        return PassThroughAttributes.INPUT_COLOR;
+    }
+
+    @Override
+    protected String getInputHtmlType(UIComponent component)
+    {
+        return HTML5.INPUT_TYPE_COLOR;
+    }
+
+    @Override
+    protected Class<? extends javax.faces.component.html.HtmlInputText> getComponentClass()
+    {
+        return HtmlInputColor.class;
+    }
+
+    @Override
+    public SuggestionRendererHelper getSuggestionRendererHelper(Html5BaseInputText component)
+    {
+        if (_suggestionRendererHelper == null)
+            _suggestionRendererHelper = new HtmlTextInputSuggestionRendererHelper();
+
+        return _suggestionRendererHelper;
+    }
+
+}
+
+class ColorConverter implements Converter
+{
+
+    private static Pattern SIMPLE_VALID_COLOR_PATTERN = Pattern.compile("^#([0-9a-fA-F]){6}$");
+
+    public Object getAsObject(FacesContext context, UIComponent uiComponent, String value) throws ConverterException
+    {
+
+        if (value == null || value.toString().isEmpty())
+        {
+            return null;
+        }
+        else
+        {
+            HtmlInputColor component = (HtmlInputColor) uiComponent;
+            String strValue = value.toString();
+
+            if (SIMPLE_VALID_COLOR_PATTERN.matcher(strValue).matches())
+            {
+                return strValue;
+            }
+            else
+            {
+                String invalidColorMessage = component.getInvalidColorMessage();
+                if (invalidColorMessage != null && !invalidColorMessage.isEmpty())
+                {
+                    throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, invalidColorMessage,
+                            invalidColorMessage));
+                }
+                else
+                {
+                    // throw new ConverterException(_MessageUtils.getMessage(facesContext,
+                    // facesContext.getViewRoot().getLocale(),
+                    // FacesMessage.SEVERITY_ERROR, UIInput.REQUIRED_MESSAGE_ID,
+                    // new Object[] { _MessageUtils.getLabel(facesContext,
+                    // uiComponent) }));
+                    // XXX: externalize and localize the message later!
+                    throw new ConverterException(new FacesMessage("Provided value for component " + RendererUtils.getPathToComponent(uiComponent) + " is not a valid simple color: "
+                            + value));
+                }
+            }
+        }
+
+    }
+
+    public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException
+    {
+        throw new UnsupportedOperationException("This method should not be called since this converter is not for public usage.");
+    }
+
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,257 @@
+/*
+ * 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.html5.renderkit.input;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.html.HtmlInputText;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.validator.Validator;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
+import org.apache.myfaces.html5.component.input.Html5BaseInputText;
+import org.apache.myfaces.html5.component.input.HtmlInputDateTime;
+import org.apache.myfaces.html5.renderkit.input.delegate.HtmlTextInputSuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.input.util.Html5DateTimeConverter;
+import org.apache.myfaces.html5.renderkit.input.util.Html5DateTimeFormatUtils;
+import org.apache.myfaces.html5.renderkit.util.HTML5;
+import org.apache.myfaces.html5.renderkit.util.JsfProperties;
+import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
+import org.apache.myfaces.html5.validator.DateTimeRangeValidator;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+
+/**
+ * Renderer of hx:inputDateTime. <br/>
+ * Renders the properties and looks for attached fx:dateTimeRangeValidator instance to determine minimum and maximum
+ * dates selectable.
+ * 
+ * @author Ali Ok
+ * 
+ */
+@JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Input", type = "org.apache.myfaces.html5.DateTime")
+public class HtmlInputDateTimeRenderer extends Html5BaseInputTextRenderer
+{
+    // see
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#attr-input-step
+    private static final String DEFAULT_STEP_HTML_VALUE = "any";
+
+    private static final Logger log = Logger.getLogger(HtmlInputDateTimeRenderer.class.getName());
+
+    private HtmlTextInputSuggestionRendererHelper _suggestionRendererHelper;
+
+    private static String[] ALLOWED_INPUT_TYPES = new String[]
+    {
+            JsfProperties.INPUTDATETIME_TYPE_DATETIME, JsfProperties.INPUTDATETIME_TYPE_DATE,
+            JsfProperties.INPUTDATETIME_TYPE_TIME, JsfProperties.INPUTDATETIME_TYPE_MONTH,
+            JsfProperties.INPUTDATETIME_TYPE_WEEK, JsfProperties.INPUTDATETIME_TYPE_DATETIME_LOCAL
+    };
+
+    @Override
+    public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue)
+            throws ConverterException
+    {
+        // override this method to convert the input to java.util.Date
+
+        if (submittedValue != null && !(submittedValue instanceof String))
+        {
+            throw new IllegalArgumentException("Submitted value of type String for component : "
+                    + RendererUtils.getPathToComponent(uiComponent) + " expected");
+        }
+
+        RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputDateTime.class);
+
+        _checkInputHtmlType(uiComponent);
+
+        HtmlInputDateTime component = (HtmlInputDateTime) uiComponent;
+
+        Converter converter = RendererUtils.findUIOutputConverter(facesContext, component);
+        if (converter == null)
+        {
+            // min and max validation is done at DateTimeRangeValidator, not in converter.
+            converter = new Html5DateTimeConverter();
+            component.setConverter(converter);
+        }
+
+        return converter.getAsObject(facesContext, component, (String) submittedValue);
+
+    }
+
+    @Override
+    protected void renderInputBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
+    {
+        RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputDateTime.class);
+        HtmlInputDateTime component = (HtmlInputDateTime) uiComponent;
+
+        if (RendererUtils.findUIOutputConverter(facesContext, component) == null)
+        {
+            component.setConverter(new Html5DateTimeConverter());
+        }
+
+        _checkInputHtmlType(uiComponent);
+        super.renderInputBegin(facesContext, uiComponent);
+
+        ResponseWriter writer = facesContext.getResponseWriter();
+
+        // XXX: support the symbols of java.text.SimpleDateFormat later. it is kind of confusing.
+        double step = component.getStep();
+        if (step == Double.MIN_VALUE) // means not specified
+        {
+            writer.writeAttribute(HTML5.STEP_ATTR, DEFAULT_STEP_HTML_VALUE, JsfProperties.STEP_PROP);
+        }
+        else if (step < 0)
+        {
+            throw new FacesException("'step' cannot be negative for component "
+                    + RendererUtils.getPathToComponent(uiComponent) + ". Provided " + step);
+        }
+        else
+        {
+            writer.writeAttribute(HTML5.STEP_ATTR, step, JsfProperties.STEP_PROP);
+        }
+
+        String strMinimum = _getMinimumStr(component);
+        if (strMinimum != null)
+            writer.writeAttribute(HTML5.MIN_ATTR, strMinimum, null);
+
+        String strMaximum = _getMaximumStr(component);
+        if (strMaximum != null)
+            writer.writeAttribute(HTML5.MAX_ATTR, strMaximum, null);
+    }
+
+    /**
+     * Extract minimum date selectable from attached fx:validateDateTimeRange
+     */
+    private String _getMinimumStr(HtmlInputDateTime component)
+    {
+        Validator[] validators = component.getValidators();
+        for (Validator validator : validators)
+        {
+            if (validator instanceof DateTimeRangeValidator)
+            {
+                DateTimeRangeValidator dateTimeRangeValidator = (DateTimeRangeValidator) validator;
+                Date minimum;
+                try
+                {
+                    minimum = dateTimeRangeValidator.getResolvedMinimum(component.getType());
+                }
+                catch (ParseException e)
+                {
+                    throw new FacesException("Unable to resolve minimum value of component " + RendererUtils.getPathToComponent(component) + ".", e);
+                }
+                if (minimum != null)
+                    return Html5DateTimeFormatUtils.formatDateTime(minimum, component.getType());
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Extract maximum date selectable from attached fx:validateDateTimeRange
+     */
+    private String _getMaximumStr(HtmlInputDateTime component)
+    {
+        Validator[] validators = component.getValidators();
+        for (Validator validator : validators)
+        {
+            if (validator instanceof DateTimeRangeValidator)
+            {
+                DateTimeRangeValidator dateTimeRangeValidator = (DateTimeRangeValidator) validator;
+                Date maximum;
+                try
+                {
+                    maximum = dateTimeRangeValidator.getResolvedMaximum(component.getType());
+                }
+                catch (ParseException e)
+                {
+                    throw new FacesException("Unable to resolve maximum value of component "
+                            + RendererUtils.getPathToComponent(component) + ".", e);
+                }
+                if (maximum != null)
+                    return Html5DateTimeFormatUtils.formatDateTime(maximum, component.getType());
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    protected Map<String, String> getExtraPassThroughAttributes()
+    {
+        return PassThroughAttributes.INPUT_DATE_TIME;
+    }
+
+    @Override
+    public SuggestionRendererHelper getSuggestionRendererHelper(Html5BaseInputText component)
+    {
+        if (_suggestionRendererHelper == null)
+            _suggestionRendererHelper = new HtmlTextInputSuggestionRendererHelper();
+
+        return _suggestionRendererHelper;
+    }
+
+    @Override
+    protected Class<? extends HtmlInputText> getComponentClass()
+    {
+        return HtmlInputDateTime.class;
+    }
+
+    /**
+     * This method checks whether html input type value is one of the allowed values.
+     */
+    private void _checkInputHtmlType(UIComponent uiComponent)
+    {
+        HtmlInputDateTime component = (HtmlInputDateTime) uiComponent;
+        String type = component.getType();
+        if (log.isLoggable(Level.FINE))
+            log.fine("initial type is: " + type);
+        if (type == null || type.isEmpty())
+        { // if not set, set default value.
+            if (log.isLoggable(Level.FINE))
+                log.fine("setting default type " + JsfProperties.INPUTDATETIME_TYPE_DATETIME);
+
+            component.setType(JsfProperties.INPUTDATETIME_TYPE_DATETIME);
+        }
+        else
+        {
+            if (!(Arrays.asList(ALLOWED_INPUT_TYPES).contains(type)))
+                throw new FacesException("\"type\" attribute of component "
+                        + RendererUtils.getPathToComponent(uiComponent) + " can be one of "
+                        + Arrays.toString(ALLOWED_INPUT_TYPES) + " . Provided: \"" + type + "\"");
+        }
+    }
+
+    @Override
+    protected String getInputHtmlType(UIComponent component)
+    {
+        // obj type check for component is done in #encodeEnd, no need to check it again
+        return ((HtmlInputDateTime) component).getType();
+    }
+}

Added: myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java?rev=980988&view=auto
==============================================================================
--- myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java (added)
+++ myfaces/gsoc/html5-comp-lib/trunk/html5-comp-lib-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java Fri Jul 30 22:37:29 2010
@@ -0,0 +1,123 @@
+/*
+ * 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.html5.renderkit.input;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
+import org.apache.myfaces.html5.component.HtmlInputEmail;
+import org.apache.myfaces.html5.component.input.Html5BaseInputText;
+import org.apache.myfaces.html5.renderkit.input.delegate.HtmlTextInputSuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.input.util.Html5EmailConverter;
+import org.apache.myfaces.html5.renderkit.input.util.InputPatternRendererUtil;
+import org.apache.myfaces.html5.renderkit.util.HTML5;
+import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
+import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+
+/**
+ * Renderer for < hx:inputEmail > component.
+ * 
+ * @author Ali Ok
+ * 
+ */
+@JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Input", type = "org.apache.myfaces.html5.Email")
+public class HtmlInputEmailRenderer extends Html5BaseInputTextRenderer
+{
+
+    private SuggestionRendererHelper _suggestionRendererHelper;
+
+    @Override
+    // overridden to validate the input against being an email and do a conversion if multiple=true
+    public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue)
+            throws ConverterException
+    {
+        if (submittedValue != null && !(submittedValue instanceof String))
+        {
+            throw new IllegalArgumentException("Submitted value of type String for component : "
+                    + RendererUtils.getPathToComponent(uiComponent) + " expected");
+        }
+
+        RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputEmail.class);
+
+        HtmlInputEmail component = (HtmlInputEmail) uiComponent;
+        Converter converter = RendererUtils.findUIOutputConverter(facesContext, component);
+        if (converter == null)
+        {
+            // min and max validation is done at DateTimeRangeValidator, not in converter.
+            converter = new Html5EmailConverter();
+            component.setConverter(converter);
+        }
+
+        return converter.getAsObject(facesContext, component, (String) submittedValue);
+    }
+
+    @Override
+    protected void renderInputBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
+    {
+        RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputEmail.class);
+
+        HtmlInputEmail component = (HtmlInputEmail) uiComponent;
+
+        if (RendererUtils.findUIOutputConverter(facesContext, component) == null)
+        {
+            component.setConverter(new Html5EmailConverter());
+        }
+
+        // let super renders inherited stuff
+        super.renderInputBegin(facesContext, uiComponent);
+
+        // render pattern here
+        InputPatternRendererUtil.renderPattern(facesContext, component);
+    }
+
+    @Override
+    protected Map<String, String> getExtraPassThroughAttributes()
+    {
+        return PassThroughAttributes.INPUT_EMAIL;
+    }
+
+    @Override
+    protected String getInputHtmlType(UIComponent component)
+    {
+        return HTML5.INPUT_TYPE_EMAIL;
+    }
+
+    @Override
+    protected Class<? extends javax.faces.component.html.HtmlInputText> getComponentClass()
+    {
+        return HtmlInputEmail.class;
+    }
+
+    @Override
+    public SuggestionRendererHelper getSuggestionRendererHelper(Html5BaseInputText component)
+    {
+        if (_suggestionRendererHelper == null)
+            _suggestionRendererHelper = new HtmlTextInputSuggestionRendererHelper();
+
+        return _suggestionRendererHelper;
+    }
+
+}