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;
+ }
+
+}