MFHTML5-1 - Get rid of myfaces-shared-html5 dependency
git-svn-id: https://svn.apache.org/repos/asf/myfaces/html5/trunk@1103558 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/myfaces-html5-core/pom.xml b/myfaces-html5-core/pom.xml
index f578419..56317ac 100644
--- a/myfaces-html5-core/pom.xml
+++ b/myfaces-html5-core/pom.xml
@@ -33,9 +33,14 @@
<dependencies>
<dependency>
- <groupId>org.apache.myfaces.shared</groupId>
- <artifactId>myfaces-shared-html5</artifactId>
- <version>${myfaces-shared-html5-version}</version>
+ <groupId>org.apache.myfaces.commons</groupId>
+ <artifactId>myfaces-commons-utils20</artifactId>
+ <version>${myfaces-commons20-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.myfaces.commons</groupId>
+ <artifactId>myfaces-components20</artifactId>
+ <version>${myfaces-commons20-version}</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.buildtools</groupId>
@@ -378,6 +383,7 @@
</profiles>
<properties>
+ <myfaces-commons20-version>1.0.1</myfaces-commons20-version>
<myfaces-builder-plugin-version>1.0.8</myfaces-builder-plugin-version>
<myfaces-builder-annotations-version>1.0.5</myfaces-builder-annotations-version>
</properties>
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/input/AbstractHtmlInputText.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/input/AbstractHtmlInputText.java
index 2e05c38..f380441 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/input/AbstractHtmlInputText.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/input/AbstractHtmlInputText.java
@@ -47,7 +47,7 @@
/**
* HTML type of the input.
* <br/>
- * Possible values are "text"(default), "search", "url", "tel", "textarea" and "password".
+ * Possible values are "text"(default), "search", "url", "tel" and "textarea".
* If this is set to "textarea", pattern is ignored.
* @see AbstractHtmlInputText#getSuggestions()
* @see AbstractHtmlInputText#getList()
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/util/ComponentUtils.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/util/ComponentUtils.java
index 5d517c8..47abc82 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/util/ComponentUtils.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/component/util/ComponentUtils.java
@@ -21,6 +21,7 @@
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
public class ComponentUtils {
@@ -52,4 +53,51 @@
return null;
}
+ //copied from org.apache.myfaces.commons.exporter.util.ComponentUtils
+ public static String getPathToComponent(UIComponent component) {
+ StringBuffer buf = new StringBuffer();
+
+ if (component == null)
+ {
+ buf.append("{Component-Path : ");
+ buf.append("[null]}");
+ return buf.toString();
+ }
+
+ getPathToComponent(component, buf);
+
+ buf.insert(0, "{Component-Path : ");
+ buf.append("}");
+
+ return buf.toString();
+ }
+
+ //copied from org.apache.myfaces.commons.exporter.util.ComponentUtils
+ private static void getPathToComponent(UIComponent component,
+ StringBuffer buf) {
+
+ if (component == null)
+ return;
+
+ StringBuffer intBuf = new StringBuffer();
+
+ intBuf.append("[Class: ");
+ intBuf.append(component.getClass().getName());
+ if (component instanceof UIViewRoot)
+ {
+ intBuf.append(",ViewId: ");
+ intBuf.append(((UIViewRoot) component).getViewId());
+ }
+ else
+ {
+ intBuf.append(",Id: ");
+ intBuf.append(component.getId());
+ }
+ intBuf.append("]");
+
+ buf.insert(0, intBuf.toString());
+
+ getPathToComponent(component.getParent(), buf);
+ }
+
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DragSourceBehaviorHandler.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DragSourceBehaviorHandler.java
index 8ff9408..e956efe 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DragSourceBehaviorHandler.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DragSourceBehaviorHandler.java
@@ -38,9 +38,9 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
import org.apache.myfaces.html5.behavior.DragSourceBehavior;
import org.apache.myfaces.html5.component.api.Draggable;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
import org.apache.myfaces.html5.event.DropEvent;
import org.apache.myfaces.html5.renderkit.util.ClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
/**
* Tag handler for {@link DragSourceBehavior}. Sets the "draggable" attribute of the parent and attaches the behavior to
@@ -102,7 +102,7 @@
if (!ComponentHandler.isNew(parent))
{
if (log.isLoggable(Level.FINE))
- log.fine("Component " + RendererUtils.getPathToComponent(parent)
+ log.fine("Component " + ComponentUtils.getPathToComponent(parent)
+ " is not new, thus return without any operation.");
return;
@@ -133,7 +133,7 @@
else
{
if (log.isLoggable(Level.WARNING))
- log.warning("Parent " + RendererUtils.getPathToComponent(parent)
+ log.warning("Parent " + ComponentUtils.getPathToComponent(parent)
+ " does not implement Draggable interface, thus unable to set the draggable attribute. "
+ "Renderer of the parent must handle the decision of being draggable manually.");
}
@@ -202,7 +202,7 @@
{
throw new TagException(getTag(),
"DragSourceBehavior must be attached to a ClientBehaviorHolder parent. Component "
- + RendererUtils.getPathToComponent(parent) + "is not a ClientBehaviorHolder.");
+ + ComponentUtils.getPathToComponent(parent) + "is not a ClientBehaviorHolder.");
}
ClientBehaviorHolder holder = (ClientBehaviorHolder) parent;
@@ -224,7 +224,7 @@
message.append("ClientBehaviorHolders that support the '");
message.append(eventName);
message.append("' event. The parent ClientBehaviorHolder "
- + RendererUtils.getPathToComponent((UIComponent) holder) + " only ");
+ + ComponentUtils.getPathToComponent((UIComponent) holder) + " only ");
message.append("supports the following events: ");
for (String supportedEventName : eventNames)
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java
index 44f5518..ecba7e6 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/DropTargetBehaviorHandler.java
@@ -38,11 +38,11 @@
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.component.util.ComponentUtils;
import org.apache.myfaces.html5.event.DropEvent;
import org.apache.myfaces.html5.event.DropListener;
import org.apache.myfaces.html5.renderkit.behavior.DropTargetBehaviorRenderer;
import org.apache.myfaces.html5.renderkit.util.ClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
/*
* Facelets tag handler for DropTargetBehavior.
@@ -164,7 +164,7 @@
if (!ComponentHandler.isNew(parent))
{
if (log.isLoggable(Level.FINE))
- log.fine("Component" + RendererUtils.getPathToComponent(parent)
+ log.fine("Component" + ComponentUtils.getPathToComponent(parent)
+ " is not new, thus return without any operation.");
return;
}
@@ -273,7 +273,7 @@
{
throw new TagException(getTag(),
"DropTargetBehavior must be attached to a ClientBehaviorHolder parent. Component "
- + RendererUtils.getPathToComponent(parent) + "is not a ClientBehaviorHolder");
+ + ComponentUtils.getPathToComponent(parent) + "is not a ClientBehaviorHolder");
}
ClientBehaviorHolder holder = (ClientBehaviorHolder) parent;
@@ -297,7 +297,7 @@
message.append("ClientBehaviorHolders that support the '");
message.append(eventName);
message.append("' event. The parent ClientBehaviorHolder "
- + RendererUtils.getPathToComponent((UIComponent) holder) + " only ");
+ + ComponentUtils.getPathToComponent((UIComponent) holder) + " only ");
message.append("supports the following events: ");
for (String supportedEventName : eventNames)
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java
index a260e7d..456788f 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourceHandler.java
@@ -30,9 +30,9 @@
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.component.util.ComponentUtils;
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}
@@ -100,7 +100,7 @@
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.");
+ log.warning("parent component " + ComponentUtils.getPathToComponent(parent) + " is not a MediaSourceHolder. handler will not apply anything.");
return;
}
else
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java
index 7a9fcca..b0593aa 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/handler/MediaSourcesHandler.java
@@ -32,9 +32,9 @@
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.component.util.ComponentUtils;
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}
@@ -95,7 +95,7 @@
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.");
+ log.warning("parent component " + ComponentUtils.getPathToComponent(parent) + " is not a MediaSourceHolder. handler will not apply anything.");
return;
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationPulseRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationPulseRenderer.java
index b036cba..b0e8b06 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationPulseRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationPulseRenderer.java
@@ -22,7 +22,7 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.animation.AbstractAnimationPulse;
import org.apache.myfaces.html5.component.animation.AbstractBaseAnimation;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.context.FacesContext;
import java.text.NumberFormat;
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationRenderer.java
index ba78d9f..4801e11 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationRenderer.java
@@ -25,15 +25,14 @@
import org.apache.myfaces.html5.renderkit.util.CSS;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HTML;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import org.apache.myfaces.view.facelets.PostBuildComponentTreeOnRestoreViewEvent;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.*;
+import javax.faces.render.Renderer;
import java.io.IOException;
@ListenersFor({
@@ -41,7 +40,7 @@
@ListenerFor(systemEventClass = PostBuildComponentTreeOnRestoreViewEvent.class)
})
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.Animation", type = "org.apache.myfaces.html5.Animation")
-public class AnimationRenderer extends HtmlRenderer implements ComponentSystemEventListener {
+public class AnimationRenderer extends Renderer implements ComponentSystemEventListener {
@Override
public boolean getRendersChildren() {
@@ -58,7 +57,7 @@
ResponseWriter writer = facesContext.getResponseWriter();
- writer.startElement(HTML.STYLE_ELEM, component);
+ writer.startElement(HTML5.STYLE_ELEM, component);
RendererUtils.checkParamValidity(facesContext, uiComponent, AbstractAnimation.class);
@@ -78,7 +77,7 @@
ResponseWriter writer = facesContext.getResponseWriter();
- writer.endElement(HTML.STYLE_ELEM);
+ writer.endElement(HTML5.STYLE_ELEM);
}
protected String getAnimationDefinition(FacesContext facesContext, AbstractAnimation component){
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationScaleRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationScaleRenderer.java
index 8fc9b5c..45dda52 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationScaleRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationScaleRenderer.java
@@ -22,7 +22,7 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.animation.AbstractAnimationScale;
import org.apache.myfaces.html5.component.animation.AbstractBaseAnimation;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.context.FacesContext;
import java.text.NumberFormat;
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationShakeRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationShakeRenderer.java
index 81e0a9e..0c763a3 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationShakeRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationShakeRenderer.java
@@ -22,7 +22,7 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.animation.AbstractAnimationShake;
import org.apache.myfaces.html5.component.animation.AbstractBaseAnimation;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.context.FacesContext;
import java.text.NumberFormat;
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationsRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationsRenderer.java
index cb23ba9..3bbea84 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationsRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/AnimationsRenderer.java
@@ -25,15 +25,14 @@
import org.apache.myfaces.html5.renderkit.util.CSS;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HTML;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import org.apache.myfaces.view.facelets.PostBuildComponentTreeOnRestoreViewEvent;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.*;
+import javax.faces.render.Renderer;
import java.io.IOException;
@ListenersFor({
@@ -41,7 +40,7 @@
@ListenerFor(systemEventClass = PostBuildComponentTreeOnRestoreViewEvent.class)
})
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.Animations", type = "org.apache.myfaces.html5.Animations")
-public class AnimationsRenderer extends HtmlRenderer implements ComponentSystemEventListener {
+public class AnimationsRenderer extends Renderer implements ComponentSystemEventListener {
@Override
public boolean getRendersChildren() {
@@ -58,7 +57,7 @@
ResponseWriter writer = facesContext.getResponseWriter();
- writer.startElement(HTML.STYLE_ELEM, component);
+ writer.startElement(HTML5.STYLE_ELEM, component);
}
@Override
@@ -92,7 +91,7 @@
ResponseWriter writer = facesContext.getResponseWriter();
- writer.endElement(HTML.STYLE_ELEM);
+ writer.endElement(HTML5.STYLE_ELEM);
}
protected String getAnimationDefinition(FacesContext facesContext, AbstractAnimations component){
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/BaseAnimationRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/BaseAnimationRenderer.java
index a90cfb5..93453b7 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/BaseAnimationRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/animation/BaseAnimationRenderer.java
@@ -20,15 +20,15 @@
package org.apache.myfaces.html5.renderkit.animation;
import org.apache.myfaces.html5.component.animation.AbstractBaseAnimation;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import java.io.IOException;
-public abstract class BaseAnimationRenderer extends HtmlRenderer {
+public abstract class BaseAnimationRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/BaseEffectRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/BaseEffectRenderer.java
index 0908a3a..7da3567 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/BaseEffectRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/BaseEffectRenderer.java
@@ -20,15 +20,15 @@
package org.apache.myfaces.html5.renderkit.effect;
import org.apache.myfaces.html5.component.effect.AbstractBaseEffect;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import java.io.IOException;
-public abstract class BaseEffectRenderer extends HtmlRenderer {
+public abstract class BaseEffectRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectOutputRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectOutputRenderer.java
index 410c136..208df82 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectOutputRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectOutputRenderer.java
@@ -26,15 +26,14 @@
import org.apache.myfaces.html5.renderkit.util.CSS;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HTML;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import org.apache.myfaces.view.facelets.PostBuildComponentTreeOnRestoreViewEvent;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.*;
+import javax.faces.render.Renderer;
import java.io.IOException;
@ListenersFor({
@@ -42,7 +41,7 @@
@ListenerFor(systemEventClass = PostBuildComponentTreeOnRestoreViewEvent.class)
})
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.EffectOutput", type = "org.apache.myfaces.html5.EffectOutput")
-public class EffectOutputRenderer extends HtmlRenderer implements ComponentSystemEventListener {
+public class EffectOutputRenderer extends Renderer implements ComponentSystemEventListener {
@Override
public boolean getRendersChildren() {
@@ -59,7 +58,7 @@
ResponseWriter writer = facesContext.getResponseWriter();
- writer.startElement(HTML.STYLE_ELEM, component);
+ writer.startElement(HTML5.STYLE_ELEM, component);
}
@Override
@@ -90,7 +89,7 @@
ResponseWriter writer = facesContext.getResponseWriter();
- writer.endElement(HTML.STYLE_ELEM);
+ writer.endElement(HTML5.STYLE_ELEM);
}
public void processEvent(ComponentSystemEvent event) {
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectRenderer.java
index b7c31dd..670ef67 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectRenderer.java
@@ -22,7 +22,7 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.effect.AbstractBaseEffect;
import org.apache.myfaces.html5.component.effect.AbstractEffect;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.context.FacesContext;
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectTransformRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectTransformRenderer.java
index 73057c5..7dce946 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectTransformRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectTransformRenderer.java
@@ -24,7 +24,7 @@
import org.apache.myfaces.html5.component.effect.AbstractBaseEffect;
import org.apache.myfaces.html5.component.effect.AbstractEffectTransform;
import org.apache.myfaces.html5.renderkit.util.CSS;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import javax.faces.context.FacesContext;
import java.text.NumberFormat;
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectsRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectsRenderer.java
index 6d74009..3e83a5c 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectsRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/effect/EffectsRenderer.java
@@ -23,15 +23,11 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.effect.AbstractEffects;
import org.apache.myfaces.html5.renderkit.util.CSS;
-import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HTML;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
import org.apache.myfaces.view.facelets.PostBuildComponentTreeOnRestoreViewEvent;
import javax.faces.component.UIComponent;
-import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.*;
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java
index 7cabd57..0559d68 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/Html5BaseInputTextRenderer.java
@@ -18,25 +18,21 @@
*/
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 org.apache.myfaces.html5.component.input.Html5BaseInputText;
+import org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper;
+import org.apache.myfaces.html5.renderkit.util.*;
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;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* An extensible base of the Html5 input renderers.
@@ -44,7 +40,7 @@
* @author Ali Ok
*
*/
-public abstract class Html5BaseInputTextRenderer extends HtmlTextRendererBase
+public abstract class Html5BaseInputTextRenderer extends Renderer
{
private static final Logger log = Logger.getLogger(Html5BaseInputTextRenderer.class.getName());
@@ -57,13 +53,9 @@
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();
+ Map<String, List<ClientBehavior>> behaviors = 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());
}
@@ -99,19 +91,47 @@
log.fine("will render generated datalist");
suggestionRendererHelper.renderDataList(facesContext, component);
}
+
}
- @Override
+ protected void renderInput(FacesContext facesContext, UIComponent component)
+ throws IOException
+ {
+ //allow subclasses to render custom attributes by separating rendering begin and end
+ renderInputBegin(facesContext, component);
+ renderInputEnd(facesContext, component);
+ }
+
protected void renderInputBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
{
RendererUtils.checkParamValidity(facesContext, uiComponent, getComponentClass());
- // let parent render standard attributes
- super.renderInputBegin(facesContext, uiComponent);
+ ResponseWriter writer = facesContext.getResponseWriter();
- if (log.isLoggable(Level.FINE))
- log.fine("parent rendered standart stuff. rendering additional pass thru attrs");
-
+ Html5BaseInputText component = (Html5BaseInputText) uiComponent;
+
+ String clientId = component.getClientId(facesContext);
+ String value = RendererUtils.getStringValue(facesContext, component);
+
+ writer.startElement(HTML5.INPUT_ELEM, component);
+ writer.writeAttribute(HTML5.ID_ATTR, clientId, null);
+ writer.writeAttribute(HTML5.NAME_ATTR, clientId, null);
+
+ //allow extending classes to modify html input element's type
+ String inputHtmlType = getInputHtmlType(component);
+ writer.writeAttribute(HTML5.TYPE_ATTR, inputHtmlType, null);
+
+ if (value != null)
+ {
+ writer.writeAttribute(HTML5.VALUE_ATTR, value, JsfProperties.VALUE_PROP);
+ }
+
+ Map<String, List<ClientBehavior>> behaviors = component.getClientBehaviors();
+
+ Html5RendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
+ Html5RendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
+ Html5RendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, component, behaviors);
+
renderPassThruAttrsAndEvents(facesContext, uiComponent);
}
@@ -120,20 +140,26 @@
throws IOException
{
Map<String, List<ClientBehavior>> clientBehaviors = ((ClientBehaviorHolder)uiComponent).getClientBehaviors();
-
+
+ Html5RendererUtils.renderPassThroughAttributes(facesContext.getResponseWriter(), uiComponent, PassThroughAttributes.BASE_INPUT);
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);
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ writer.endElement(HTML5.INPUT_ELEM);
}
/**
+ * Returns the HTML type attribute of HTML input element, which is being rendered.
+ */
+ protected abstract String getInputHtmlType(Html5BaseInputText 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)}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java
index 6a4a458..9ea6a99 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputColorRenderer.java
@@ -31,11 +31,12 @@
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.component.util.ComponentUtils;
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;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Renderer for < hx:inputColor > component.
@@ -64,7 +65,7 @@
if (submittedValue != null && !(submittedValue instanceof String))
{
throw new IllegalArgumentException("Submitted value of type String for component : "
- + RendererUtils.getPathToComponent(uiComponent) + "expected");
+ + ComponentUtils.getPathToComponent(uiComponent) + "expected");
}
RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputColor.class);
@@ -93,7 +94,7 @@
}
@Override
- protected String getInputHtmlType(UIComponent component)
+ protected String getInputHtmlType(Html5BaseInputText component)
{
return HTML5.INPUT_TYPE_COLOR;
}
@@ -152,7 +153,7 @@
// 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: "
+ throw new ConverterException(new FacesMessage("Provided value for component " + ComponentUtils.getPathToComponent(uiComponent) + " is not a valid simple color: "
+ value));
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java
index 07bd56d..74ba40f 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputDateTimeRenderer.java
@@ -38,6 +38,7 @@
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.component.util.ComponentUtils;
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;
@@ -45,8 +46,8 @@
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.renderkit.util.RendererUtils;
import org.apache.myfaces.html5.validator.DateTimeRangeValidator;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
/**
* Renderer of hx:inputDateTime. <br/>
@@ -83,7 +84,7 @@
if (submittedValue != null && !(submittedValue instanceof String))
{
throw new IllegalArgumentException("Submitted value of type String for component : "
- + RendererUtils.getPathToComponent(uiComponent) + " expected");
+ + ComponentUtils.getPathToComponent(uiComponent) + " expected");
}
RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputDateTime.class);
@@ -129,7 +130,7 @@
else if (step < 0)
{
throw new FacesException("'step' cannot be negative for component "
- + RendererUtils.getPathToComponent(uiComponent) + ". Provided " + step);
+ + ComponentUtils.getPathToComponent(uiComponent) + ". Provided " + step);
}
else
{
@@ -163,7 +164,7 @@
}
catch (ParseException e)
{
- throw new FacesException("Unable to resolve minimum value of component " + RendererUtils.getPathToComponent(component) + ".", e);
+ throw new FacesException("Unable to resolve minimum value of component " + ComponentUtils.getPathToComponent(component) + ".", e);
}
if (minimum != null)
return Html5DateTimeFormatUtils.formatDateTime(minimum, component.getType());
@@ -192,7 +193,7 @@
catch (ParseException e)
{
throw new FacesException("Unable to resolve maximum value of component "
- + RendererUtils.getPathToComponent(component) + ".", e);
+ + ComponentUtils.getPathToComponent(component) + ".", e);
}
if (maximum != null)
return Html5DateTimeFormatUtils.formatDateTime(maximum, component.getType());
@@ -243,13 +244,13 @@
{
if (!(Arrays.asList(ALLOWED_INPUT_TYPES).contains(type)))
throw new FacesException("\"type\" attribute of component "
- + RendererUtils.getPathToComponent(uiComponent) + " can be one of "
+ + ComponentUtils.getPathToComponent(uiComponent) + " can be one of "
+ Arrays.toString(ALLOWED_INPUT_TYPES) + " . Provided: \"" + type + "\"");
}
}
@Override
- protected String getInputHtmlType(UIComponent component)
+ protected String getInputHtmlType(Html5BaseInputText component)
{
// obj type check for component is done in #encodeEnd, no need to check it again
return ((HtmlInputDateTime) component).getType();
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java
index bdae833..b00a3cb 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputEmailRenderer.java
@@ -29,13 +29,14 @@
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.component.util.ComponentUtils;
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;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Renderer for < hx:inputEmail > component.
@@ -57,7 +58,7 @@
if (submittedValue != null && !(submittedValue instanceof String))
{
throw new IllegalArgumentException("Submitted value of type String for component : "
- + RendererUtils.getPathToComponent(uiComponent) + " expected");
+ + ComponentUtils.getPathToComponent(uiComponent) + " expected");
}
RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputEmail.class);
@@ -100,7 +101,7 @@
}
@Override
- protected String getInputHtmlType(UIComponent component)
+ protected String getInputHtmlType(Html5BaseInputText component)
{
return HTML5.INPUT_TYPE_EMAIL;
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSliderRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSliderRenderer.java
index 9f6c4f4..fc3c164 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSliderRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSliderRenderer.java
@@ -32,11 +32,11 @@
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.HtmlInputNumberSlider;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
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:inputNumberSlider.
@@ -89,7 +89,7 @@
if (max <= min)
{
- throw new FacesException("Maximum must be larger than minimum for component " + RendererUtils.getPathToComponent(uiComponent) + ". "
+ throw new FacesException("Maximum must be larger than minimum for component " + ComponentUtils.getPathToComponent(uiComponent) + ". "
+ "These values are calculated from the first attached DoubleRangeValidator or LongRangeValidator");
}
@@ -116,14 +116,14 @@
if (step != Double.MIN_VALUE && segmentCount != Integer.MIN_VALUE)
{ // if both are set
throw new FacesException(
- "Only one of 'step' or 'segmentCount' properties must be defined for component " + RendererUtils.getPathToComponent(component) + ". Undefined one will be calculated.");
+ "Only one of 'step' or 'segmentCount' properties must be defined for component " + ComponentUtils.getPathToComponent(component) + ". Undefined one will be calculated.");
}
if (step != Double.MIN_VALUE)
{ // if only step is set
if (step <= 0)
{ // if it is set but it is negative
- throw new FacesException("'step' property of component " + RendererUtils.getPathToComponent(component) + " must be positive");
+ throw new FacesException("'step' property of component " + ComponentUtils.getPathToComponent(component) + " must be positive");
}
calculatedStep = step;
}
@@ -131,7 +131,7 @@
{ // if only segmentCount is set
if (segmentCount <= 0)
{ // if it is set but it is negative
- throw new FacesException("'segmentCount' property of component " + RendererUtils.getPathToComponent(
+ throw new FacesException("'segmentCount' property of component " + ComponentUtils.getPathToComponent(
component) + " must be positive");
}
calculatedStep = (max - min) / segmentCount;
@@ -167,7 +167,7 @@
}
@Override
- protected String getInputHtmlType(UIComponent component)
+ protected String getInputHtmlType(Html5BaseInputText component)
{
return HTML5.INPUT_TYPE_RANGE;
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSpinnerRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSpinnerRenderer.java
index 64e09ae..1b76d1f 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSpinnerRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputNumberSpinnerRenderer.java
@@ -26,6 +26,7 @@
import javax.faces.context.FacesContext;
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.HtmlInputNumberSpinner;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
@@ -60,7 +61,7 @@
}
@Override
- protected String getInputHtmlType(UIComponent component)
+ protected String getInputHtmlType(Html5BaseInputText component)
{
return HTML5.INPUT_TYPE_NUMBER;
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputTextRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputTextRenderer.java
index f297f70..de057cf 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputTextRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/HtmlInputTextRenderer.java
@@ -31,11 +31,10 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.input.HtmlInputText;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
import org.apache.myfaces.html5.renderkit.input.delegate.HtmlInputTextRendererDelegate;
-import org.apache.myfaces.html5.renderkit.input.delegate.HtmlSecretRendererDelegate;
import org.apache.myfaces.html5.renderkit.input.delegate.HtmlTextAreaRendererDelegate;
import org.apache.myfaces.html5.renderkit.util.JsfProperties;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
/**
* Renderer for < hx:inputText > component.
@@ -58,16 +57,14 @@
private static final Logger log = Logger.getLogger(HtmlInputTextRendererDelegate.class.getName());
protected Renderer _textTypeRendererDelegate = null;
- protected Renderer _passwordTypeRendererDelegate = null;
protected Renderer _textareaTypeRendererDelegate = null;
public HtmlInputTextRenderer()
{
super();
- // let's create all three delegates since renderers are created once in application lifecycle
+ // let's create the delegates since renderers are created once in application lifecycle
_textTypeRendererDelegate = new HtmlInputTextRendererDelegate();
- _passwordTypeRendererDelegate = new HtmlSecretRendererDelegate();
_textareaTypeRendererDelegate = new HtmlTextAreaRendererDelegate();
}
@@ -108,17 +105,13 @@
{
return _textTypeRendererDelegate;
}
- else if (type.equals(JsfProperties.INPUTTEXT_TYPE_PASSWORD))
- {
- return _passwordTypeRendererDelegate;
- }
else if (type.equals(JsfProperties.INPUTTEXT_TYPE_TEXTAREA))
{
return _textareaTypeRendererDelegate;
}
else
{
- throw new IllegalStateException("Input type of component " + RendererUtils.getPathToComponent(component) + " is not one of the expected types: \""
+ throw new IllegalStateException("Input type of component " + ComponentUtils.getPathToComponent(component) + " is not one of the expected types: \""
+ JsfProperties.INPUTTEXT_TYPE_TEXT + "\", \"" + JsfProperties.INPUTTEXT_TYPE_SEARCH + "\", \""
+ JsfProperties.INPUTTEXT_TYPE_URL + "\" ,\"" + JsfProperties.INPUTTEXT_TYPE_TEL + "\". Provided: \""
+ type + "\".");
@@ -191,7 +184,7 @@
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)
+ throw new FacesException("\"type\" attribute of component " + ComponentUtils.getPathToComponent(uiComponent) + " can be one of " + Arrays.toString(ALLOWED_INPUT_TYPES)
+ ". You provided: \"" + type + "\"");
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlDataListSuggestionRendererHelper.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlDataListSuggestionRendererHelper.java
index a18ec73..45f2a4a 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlDataListSuggestionRendererHelper.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlDataListSuggestionRendererHelper.java
@@ -28,9 +28,10 @@
import javax.faces.model.SelectItem;
import org.apache.myfaces.html5.component.input.HtmlDataList;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.JsfProperties;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Implementation of {@link SuggestionRendererHelper} for usage in {@link org.apache.myfaces.html5.component.input.HtmlDataList}s.
@@ -54,7 +55,11 @@
@Override
public void renderDataList(FacesContext facesContext, UIComponent component) throws IOException
{
- super.renderDataList(facesContext, component);
+ renderDataListBegin(facesContext, component);
+
+ renderDataListOptions(facesContext, component, null);
+
+ renderDataListEnd(facesContext, component);
}
protected void renderDataListBegin(FacesContext facesContext, UIComponent component) throws IOException
@@ -89,7 +94,7 @@
else
{
throw new IllegalArgumentException(
- "Component " + RendererUtils.getPathToComponent(uiComponent) + " is not instance of HtmlDataList. HtmlDataListSuggestionRendererHelper is unable to render options of suggestions attr.");
+ "Component " + ComponentUtils.getPathToComponent(uiComponent) + " is not instance of HtmlDataList. HtmlDataListSuggestionRendererHelper is unable to render options of suggestions attr.");
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlInputTextRendererDelegate.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlInputTextRendererDelegate.java
index f390033..5958e8f 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlInputTextRendererDelegate.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlInputTextRendererDelegate.java
@@ -34,7 +34,7 @@
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;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Delegate renderer that is used when the type of < hx:input > is one of "text", "search", "url" or "tel".
@@ -111,7 +111,7 @@
}
@Override
- protected String getInputHtmlType(UIComponent component)
+ protected String getInputHtmlType(Html5BaseInputText component)
{
// obj type check for component is done in #encodeEnd, no need to check it again
return ((HtmlInputText) component).getType();
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlSecretRendererDelegate.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlSecretRendererDelegate.java
deleted file mode 100644
index 5a89a20..0000000
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlSecretRendererDelegate.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.delegate;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-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.HtmlInputText;
-import org.apache.myfaces.html5.renderkit.input.util.InputPatternRendererUtil;
-import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
-import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlSecretRendererBase;
-
-/**
- * Delegate renderer that is used when the type of < hx:input > is one of "password".
- *
- * @author Ali Ok
- *
- */
-public class HtmlSecretRendererDelegate extends HtmlSecretRendererBase
-{
-
- @Override
- protected void renderInputBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
- {
- RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputText.class);
-
- HtmlInputText component = (HtmlInputText) uiComponent;
-
- // pass cols -> size to make super render size correctly!
- component.setSize(component.getCols());
-
- super.renderInputBegin(facesContext, uiComponent);
-
- // render pattern here
- InputPatternRendererUtil.renderPattern(facesContext, component);
-
- 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,
- PassThroughAttributes.INPUT_SECRET);
- }
-
-}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextAreaRendererDelegate.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextAreaRendererDelegate.java
index 3edb142..48d4237 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextAreaRendererDelegate.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextAreaRendererDelegate.java
@@ -18,56 +18,110 @@
*/
package org.apache.myfaces.html5.renderkit.input.delegate;
+import org.apache.commons.collections.MapUtils;
+import org.apache.myfaces.html5.component.input.Html5BaseInputText;
+import org.apache.myfaces.html5.renderkit.util.*;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIOutput;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
import java.io.IOException;
import java.util.List;
import java.util.Map;
-import javax.faces.component.UIComponent;
-import javax.faces.component.behavior.ClientBehavior;
-import javax.faces.component.behavior.ClientBehaviorHolder;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-
-import org.apache.myfaces.html5.component.input.HtmlInputText;
-import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
-import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.html.HTML;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.util.JavascriptUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlTextareaRendererBase;
-
/**
* Delegate renderer that is used when the type of < hx:input > is one of "textarea".
*
* @author Ali Ok
*
*/
-public class HtmlTextAreaRendererDelegate extends HtmlTextareaRendererBase
+public class HtmlTextAreaRendererDelegate extends Renderer
{
- @Override
- protected void renderTextAreaBegin(FacesContext facesContext,
- UIComponent uiComponent) throws IOException
+
+ public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
+ throws IOException
{
- renderPassThruAttrsAndEvents(facesContext, uiComponent);
+ RendererUtils.checkParamValidity(facesContext, uiComponent, UIInput.class);
+
+ Html5BaseInputText component = (Html5BaseInputText) uiComponent;
+
+ Map<String, List<ClientBehavior>> behaviors = component.getClientBehaviors();
+ if (MapUtils.isNotEmpty(behaviors))
+ {
+ ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
+ }
+
+ encodeTextArea(facesContext, component);
+
}
- // to make this extendible
- protected void renderPassThruAttrsAndEvents(FacesContext facesContext, UIComponent uiComponent) throws IOException
+ protected void encodeTextArea(FacesContext facesContext, Html5BaseInputText component) throws IOException {
+ //allow subclasses to render custom attributes by separating rendering begin and end
+ renderTextAreaBegin(facesContext, component);
+ renderTextAreaValue(facesContext, component);
+ renderTextAreaEnd(facesContext, component);
+
+ }
+
+ //Subclasses can set the value of an attribute before, or can render a custom attribute after calling this method
+ protected void renderTextAreaBegin(FacesContext facesContext, Html5BaseInputText component) throws IOException
{
- Map<String, List<ClientBehavior>> clientBehaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+ ResponseWriter writer = facesContext.getResponseWriter();
+ writer.startElement(HTML5.TEXTAREA_ELEM, component);
- Html5RendererUtils.renderPassThroughClientBehaviorEventHandlers(facesContext, uiComponent,
- PassThroughClientBehaviorEvents.BASE_INPUT, clientBehaviors);
+ writer.writeAttribute(HTML5.ID_ATTR, component.getClientId(facesContext), null);
+ writer.writeAttribute(HTML5.NAME_ATTR, component.getClientId(facesContext), null);
- Html5RendererUtils.renderPassThroughAttributes(facesContext.getResponseWriter(), uiComponent,
+ Map<String, List<ClientBehavior>> behaviors = component.getClientBehaviors();
+ Html5RendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
+ Html5RendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
+ Html5RendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, component, behaviors);
+
+ Html5RendererUtils.renderPassThroughClientBehaviorEventHandlers(facesContext, component,
+ PassThroughClientBehaviorEvents.BASE_INPUT, behaviors);
+
+ Html5RendererUtils.renderPassThroughAttributes(facesContext.getResponseWriter(), component,
+ PassThroughAttributes.BASE_INPUT);
+
+ Html5RendererUtils.renderPassThroughAttributes(facesContext.getResponseWriter(), component,
PassThroughAttributes.INPUT_TEXTAREA);
}
- @Override
- protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
+ //Subclasses can override the writing of the "text" value of the textarea
+ protected void renderTextAreaValue(FacesContext facesContext, UIComponent uiComponent) throws IOException
{
- return ((HtmlInputText) uiComponent).isDisabled();
+ ResponseWriter writer = facesContext.getResponseWriter();
+ String strValue = RendererUtils.getStringValue(facesContext, uiComponent);
+ writer.writeText(strValue, JsfProperties.VALUE_PROP);
+ }
+
+ protected void renderTextAreaEnd(FacesContext facesContext,
+ Html5BaseInputText component) throws IOException
+ {
+ facesContext.getResponseWriter().endElement(HTML5.TEXTAREA_ELEM);
+ }
+
+ public void decode(FacesContext facesContext, UIComponent component)
+ {
+ RendererUtils.checkParamValidity(facesContext, component, Html5BaseInputText.class);
+ Html5RendererUtils.decodeUIInput(facesContext, component);
+ if (!((Html5BaseInputText)component).isDisabled())
+ {
+ Html5RendererUtils.decodeClientBehaviors(facesContext, component);
+ }
+ }
+
+ public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException
+ {
+ RendererUtils.checkParamValidity(facesContext, uiComponent, UIOutput.class);
+ return RendererUtils.getConvertedUIOutputValue(facesContext,
+ (UIOutput)uiComponent,
+ submittedValue);
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextInputSuggestionRendererHelper.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextInputSuggestionRendererHelper.java
index c260ed5..48e1380 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextInputSuggestionRendererHelper.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/delegate/HtmlTextInputSuggestionRendererHelper.java
@@ -36,12 +36,11 @@
import org.apache.myfaces.html5.component.input.Html5BaseInputText;
import org.apache.myfaces.html5.component.input.HtmlInputText;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
import org.apache.myfaces.html5.renderkit.util.HTML5;
-import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
import org.apache.myfaces.html5.renderkit.util.JsfProperties;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HTML;
-import org.apache.myfaces.shared_html5.util.SelectItemsIterator;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.SelectItemsIterator;
/**
* Implementation of {@link SuggestionRendererHelper} for usage in {@link HtmlInputText}s.
@@ -77,13 +76,13 @@
{
// WIKI: put a wiki page about this error
throw new FacesException(
- "Either \"list\" attribute or \"suggestions\" attribute and children with type SelectItem mechanism can be used for suggestions. Component " + RendererUtils.getPathToComponent(uiComponent) + "has both!");
+ "Either \"list\" attribute or \"suggestions\" attribute and children with type SelectItem mechanism can be used for suggestions. Component " + ComponentUtils.getPathToComponent(uiComponent) + "has both!");
}
}
else
{
throw new IllegalArgumentException(
- "Component " + RendererUtils.getPathToComponent(uiComponent) + " is not instance of Html5BaseInputText. HtmlTextInputSuggestionRendererHelper is unable to check suggestions.");
+ "Component " + ComponentUtils.getPathToComponent(uiComponent) + " is not instance of Html5BaseInputText. HtmlTextInputSuggestionRendererHelper is unable to check suggestions.");
}
}
@@ -119,23 +118,21 @@
else
{
throw new IllegalArgumentException(
- "Component " + RendererUtils.getPathToComponent(uiComponent) + " is not instance of Html5BaseInputText. HtmlTextInputSuggestionRendererHelper is unable to determine whether datalist will be generated or not.");
+ "Component " + ComponentUtils.getPathToComponent(uiComponent) + " is not instance of Html5BaseInputText. HtmlTextInputSuggestionRendererHelper is unable to determine whether datalist will be generated or not.");
}
}
/*
* (non-Javadoc)
*
- * @see
- * org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper#renderDataList(javax.faces.context
- * .FacesContext, org.apache.myfaces.html5.component.input.Html5BaseInputText)
+ * @see org.apache.myfaces.html5.renderkit.input.delegate.SuggestionRendererHelper#renderDataList(javax.faces.context.FacesContext, org.apache.myfaces.html5.component.input.Html5BaseInputText)
*/
public void renderDataList(FacesContext facesContext, UIComponent component) throws IOException
{
renderDataListBegin(facesContext, component);
// create converter and pass it to methods here to prevent duplicate creation of the converter
- Converter converter = Html5RendererUtils.findUIOutputConverterFailSafe(facesContext, component);
+ Converter converter = RendererUtils.findUIOutputConverterFailSafe(facesContext, component);
renderDataListOptions(facesContext, component, converter);
@@ -180,7 +177,7 @@
else
{
throw new IllegalArgumentException(
- "Component " + RendererUtils.getPathToComponent(uiComponent) + " is not instance of Html5BaseInputText. HtmlTextInputSuggestionRendererHelper is unable to render options of suggestions attr.");
+ "Component " + ComponentUtils.getPathToComponent(uiComponent) + " is not instance of Html5BaseInputText. HtmlTextInputSuggestionRendererHelper is unable to render options of suggestions attr.");
}
}
@@ -246,7 +243,7 @@
writer.write(TABULATOR);
- writer.startElement(HTML.OPTION_ELEM, null);
+ writer.startElement(HTML5.OPTION_ELEM, null);
/*
* we're writing an attribute, not text here: using <option value="value" label="Label" /> notation, not
@@ -254,14 +251,14 @@
*/
String itemLabel = selectItem.getLabel();
// writeAttribute method escapes the label anyway. so ignore SelectItem#isEscape()...
- writer.writeAttribute(HTML.LABEL_ATTR, itemLabel, null);
+ writer.writeAttribute(HTML5.LABEL_ATTR, itemLabel, null);
- String itemStrValue = RendererUtils.getConvertedStringValue(facesContext, component, converter, selectItem);
+ String itemStrValue = RendererUtils.getConvertedStringValue(facesContext, component, converter, selectItem.getValue());
writer.writeAttribute(HTML5.VALUE_ATTR, itemStrValue, null);
- writer.writeAttribute(HTML.DISABLED_ATTR, selectItem.isDisabled(), null);
+ writer.writeAttribute(HTML5.DISABLED_ATTR, selectItem.isDisabled(), null);
- writer.endElement(HTML.OPTION_ELEM);
+ writer.endElement(HTML5.OPTION_ELEM);
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5DateTimeConverter.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5DateTimeConverter.java
index 3cce84e..a88c4c1 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5DateTimeConverter.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5DateTimeConverter.java
@@ -29,7 +29,7 @@
import javax.faces.convert.ConverterException;
import org.apache.myfaces.html5.component.input.HtmlInputDateTime;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
/**
* Converter for use in hx:inputDateTime.
@@ -53,12 +53,12 @@
}
catch (ParseException e)
{
- throw new ConverterException(new FacesMessage("Unable to parse input " + value + " for " + RendererUtils.getPathToComponent(uiComponent) + " with type " + type), e);
+ throw new ConverterException(new FacesMessage("Unable to parse input " + value + " for " + ComponentUtils.getPathToComponent(uiComponent) + " with type " + type), e);
}
}
else
{
- throw new FacesException("Component " + RendererUtils.getPathToComponent(uiComponent) + " is not a HtmlInputDateTime");
+ throw new FacesException("Component " + ComponentUtils.getPathToComponent(uiComponent) + " is not a HtmlInputDateTime");
}
}
@@ -69,7 +69,7 @@
return null;
if (!(objValue instanceof Date))
- throw new FacesException("Value is not a java.util.Date for component " + RendererUtils.getPathToComponent(uiComponent) + ".");
+ throw new FacesException("Value is not a java.util.Date for component " + ComponentUtils.getPathToComponent(uiComponent) + ".");
if (uiComponent instanceof HtmlInputDateTime)
{
@@ -82,7 +82,7 @@
}
else
{
- throw new FacesException("Component " + RendererUtils.getPathToComponent(uiComponent) + " is not a HtmlInputDateTime");
+ throw new FacesException("Component " + ComponentUtils.getPathToComponent(uiComponent) + " is not a HtmlInputDateTime");
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5EmailConverter.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5EmailConverter.java
index 4c3b8c2..364cf1d 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5EmailConverter.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/input/util/Html5EmailConverter.java
@@ -25,7 +25,7 @@
import javax.faces.convert.ConverterException;
import org.apache.commons.validator.EmailValidator;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
/**
* Converter for use in hx:inputEmail.
@@ -54,7 +54,7 @@
if (!EmailValidator.getInstance().isValid(email))
{
throw new ConverterException(new FacesMessage("Provided value for component "
- + RendererUtils.getPathToComponent(component) + " is not a valid email: " + email));
+ + ComponentUtils.getPathToComponent(component) + " is not a valid email: " + email));
}
}
@@ -93,7 +93,7 @@
else
{
throw new ConverterException(new FacesMessage("Provided value for component "
- + RendererUtils.getPathToComponent(component) + " is not String or String[]: " + value.toString()));
+ + ComponentUtils.getPathToComponent(component) + " is not String or String[]: " + value.toString()));
}
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AbstractMediaRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AbstractMediaRenderer.java
index 0206c64..baf0791 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AbstractMediaRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AbstractMediaRenderer.java
@@ -31,14 +31,14 @@
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import org.apache.myfaces.html5.component.media.AbstractMedia;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
import org.apache.myfaces.html5.model.MediaInfo;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.JSFAttr;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Abstract base for media renderers.
@@ -46,7 +46,7 @@
* @author Ali Ok
*
*/
-public abstract class AbstractMediaRenderer extends HtmlRenderer
+public abstract class AbstractMediaRenderer extends Renderer
{
private static final Logger log = Logger.getLogger(AbstractMediaRenderer.class.getName());
@@ -72,11 +72,11 @@
writer.writeAttribute(HTML5.ID_ATTR, component.getClientId(facesContext), null);
// get the value and render the src attr
- String src = org.apache.myfaces.shared_html5.renderkit.RendererUtils.getStringValue(facesContext, component);
+ String src = RendererUtils.getStringValue(facesContext, component);
if (log.isLoggable(Level.FINE))
log.fine("writing src '" + src + "'");
if (src != null && !src.isEmpty())
- writer.writeAttribute(HTML5.SRC_ATTR, src, JSFAttr.VALUE_ATTR);
+ writer.writeAttribute(HTML5.SRC_ATTR, src, "value");
// no need to check the value of preload, it is bypassed anyway.
// _checkPreload(component);
@@ -162,7 +162,7 @@
// src is reqired to be present and not empty!
if (mediaInfo.getSrc() == null || mediaInfo.getSrc().isEmpty())
// WIKI: add a wiki page
- throw new FacesException("'src' field of MediaInfo has to be defined and nonempty for component " + RendererUtils.getPathToComponent(uiComponent) + ".");
+ throw new FacesException("'src' field of MediaInfo has to be defined and nonempty for component " + ComponentUtils.getPathToComponent(uiComponent) + ".");
writer.writeAttribute(HTML5.SRC_ATTR, mediaInfo.getSrc(), null);
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AudioRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AudioRenderer.java
index 9383e9b..5bb7363 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AudioRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/AudioRenderer.java
@@ -29,7 +29,7 @@
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Renderer for < hx:audio > component.
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/VideoRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/VideoRenderer.java
index c826164..7223a78 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/VideoRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/media/VideoRenderer.java
@@ -29,7 +29,7 @@
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
+import org.apache.myfaces.html5.renderkit.util.RendererUtils;
/**
* Renderer for < hx:video > component.
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/MeterRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/MeterRenderer.java
index 03bb65c..af561e7 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/MeterRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/MeterRenderer.java
@@ -22,12 +22,7 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.output.AbstractMeter;
import org.apache.myfaces.html5.renderkit.panel.DivRenderer;
-import org.apache.myfaces.html5.renderkit.util.HTML5;
-import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
-import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.*;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
@@ -35,6 +30,7 @@
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -42,7 +38,7 @@
import java.util.logging.Logger;
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.Meter", type = "org.apache.myfaces.html5.Meter")
-public class MeterRenderer extends HtmlRenderer
+public class MeterRenderer extends Renderer
{
private static final Logger log = Logger.getLogger(DivRenderer.class.getName());
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/ProgressRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/ProgressRenderer.java
index 27d5e74..48e4330 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/ProgressRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/ProgressRenderer.java
@@ -3,12 +3,7 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.output.AbstractProgress;
import org.apache.myfaces.html5.renderkit.panel.DivRenderer;
-import org.apache.myfaces.html5.renderkit.util.HTML5;
-import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
-import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.html5.renderkit.util.*;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
@@ -16,6 +11,7 @@
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -29,7 +25,7 @@
*
*/
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.Progress", type = "org.apache.myfaces.html5.Progress")
-public class ProgressRenderer extends HtmlRenderer
+public class ProgressRenderer extends Renderer
{
private static final Logger log = Logger.getLogger(DivRenderer.class.getName());
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideRenderer.java
index a21cfbb..893afac 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideRenderer.java
@@ -22,10 +22,7 @@
import org.apache.commons.lang.StringUtils;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.output.AbstractSlide;
-import org.apache.myfaces.html5.component.output.AbstractSlideView;
import org.apache.myfaces.html5.renderkit.util.*;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
@@ -34,6 +31,7 @@
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -47,7 +45,7 @@
@ResourceDependency(name = "html5.css", library = "org.apache.myfaces.html5", target = "head")
})
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.Slide", type = "org.apache.myfaces.html5.Slide")
-public class SlideRenderer extends HtmlRenderer
+public class SlideRenderer extends Renderer
{
@Override
public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideViewRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideViewRenderer.java
index fe15dd6..51cd344 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideViewRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/output/SlideViewRenderer.java
@@ -23,8 +23,6 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.output.AbstractSlideView;
import org.apache.myfaces.html5.renderkit.util.*;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
@@ -33,6 +31,7 @@
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
@@ -49,7 +48,7 @@
@ResourceDependency(name = "html5.css", library = "org.apache.myfaces.html5", target = "head")
})
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.SlideView", type = "org.apache.myfaces.html5.SlideView")
-public class SlideViewRenderer extends HtmlRenderer
+public class SlideViewRenderer extends Renderer
{
@Override
public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/panel/DivRenderer.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/panel/DivRenderer.java
index c2c2721..769e53f 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/panel/DivRenderer.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/panel/DivRenderer.java
@@ -29,16 +29,11 @@
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
import org.apache.myfaces.html5.component.panel.AbstractDiv;
-import org.apache.myfaces.html5.renderkit.util.HTML5;
-import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
-import org.apache.myfaces.html5.renderkit.util.PassThroughAttributes;
-import org.apache.myfaces.html5.renderkit.util.PassThroughClientBehaviorEvents;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRenderer;
-import org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.html5.renderkit.util.*;
/**
* Div renderer.
@@ -47,7 +42,7 @@
*
*/
@JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.Div", type = "org.apache.myfaces.html5.Div")
-public class DivRenderer extends HtmlRenderer
+public class DivRenderer extends Renderer
{
private static final Logger log = Logger.getLogger(DivRenderer.class.getName());
@@ -112,7 +107,7 @@
// Check for npe
super.decode(context, component);
- HtmlRendererUtils.decodeClientBehaviors(context, component);
+ Html5RendererUtils.decodeClientBehaviors(context, component);
}
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ClientBehaviorEvents.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ClientBehaviorEvents.java
index d77d593..780e888 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ClientBehaviorEvents.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ClientBehaviorEvents.java
@@ -73,6 +73,9 @@
String MOUSEOUT_EVENT = "mouseout";
String MOUSEOVER_EVENT = "mouseover";
String MOUSEUP_EVENT = "mouseup";
+ String CHANGE_EVENT = "change";
+ String SELECT_EVENT = "select";
+ String VALUECHANGE_EVENT= "valueChange";
//Effect events
String ANIMATIONEND_EVENT = "webkitAnimationEnd";
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/HTML5.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/HTML5.java
index e81386f..45c0510 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/HTML5.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/HTML5.java
@@ -19,15 +19,13 @@
package org.apache.myfaces.html5.renderkit.util;
/**
- * Html constants for using in renderers. Does not extend {@link org.apache.myfaces.shared_html5.renderkit.html.HTML} on
- * purpose, since there are ugly constants like
- * "COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK" in there. <br/>
- * Note that, this interface does not contain all of the element names and attribute names specified in Html5 spec. It
+ * Html constants for using in renderers. <br/>
+ * Note that, this interface does not contain all of the element names and attribute names specified in Html spec. It
* only contains used ones in MyFaces Html5 components, and may not contain the attributes which have the same name with
* the Jsf component property.
*
* @author Ali Ok
- * @see org.apache.myfaces.shared_html5.renderkit.html.HTML
+ * @see org.apache.myfaces.commons.util.renderkit.HTML
*/
public interface HTML5
{
@@ -39,10 +37,12 @@
String DATALIST_ELEM = "datalist";
// html elements
+ String INPUT_ELEM = "input";
String TEXTAREA_ELEM = "textarea";
String DIV_ELEM = "div";
String STYLE_ELEM = "style";
String SCRIPT_ELEM = "script";
+ String OPTION_ELEM = "option";
// general attrs
String ID_ATTR = "id";
@@ -51,7 +51,13 @@
String SRC_ATTR = "src";
String TYPE_ATTR = "type";
String CLASS_ATTR = "class";
+ String STYLE_ATTR = "style";
String VALUE_ATTR = "value";
+ String DISABLED_ATTR = "disabled";
+ String LABEL_ATTR = "label";
+ String SCRIPT_TYPE_ATTR = "type";
+ String SCRIPT_TYPE_TEXT_JAVASCRIPT = "text/javascript";
+ String NAME_ATTR = "name";
// media attrs
String CONTROLS_ATTR = "controls"; // not pass thru
@@ -86,6 +92,7 @@
String MIN_ATTR = "min";
String MAX_ATTR = "max";
String STEP_ATTR = "step";
+ String AUTOCOMPLETE_ATTR = "autocomplete";
// new Html5 attributes which is boolean but not Html5 boolean
// @see Html5RendererUtils#renderHTMLAttribute(javax.faces.context.ResponseWriter, String, String, Object)
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/Html5RendererUtils.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/Html5RendererUtils.java
index a5927ca..80e9c0a 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/Html5RendererUtils.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/Html5RendererUtils.java
@@ -18,35 +18,25 @@
*/
package org.apache.myfaces.html5.renderkit.util;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
+import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
-import javax.faces.component.UIOutput;
import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorContext;
+import javax.faces.component.behavior.ClientBehaviorHint;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
-import javax.faces.convert.Converter;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.myfaces.html5.component.input.Html5BaseInputText;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
-import org.apache.myfaces.shared_html5.renderkit.html.HtmlRendererUtils;
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Logger;
/**
- * Renderer utils for common stuff.
- * <p>
- * Does not extend org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils on purpose, since this class should not
- * expose methods like
- * {@link org.apache.myfaces.shared_html5.renderkit.html.HtmlRendererUtils#renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIComponent, java.util.Map)}
- *
* @author Ali Ok
- *
*/
public class Html5RendererUtils
{
@@ -58,6 +48,18 @@
private static final String DEFAULT_WIDGET_PREFIX = "widget_";
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\r\n");
+ private static final char TABULATOR = '\t';
+
+ public static final String NON_SUBMITTED_VALUE_WARNING
+ = "There should always be a submitted value for an input if it is rendered,"
+ + " its form is submitted, and it was not originally rendered disabled or read-only."
+ + " You cannot submit a form after disabling an input element via javascript."
+ + " Consider setting read-only to true instead"
+ + " or resetting the disabled value back to false prior to form submission.";
+
+ private static final Logger log = Logger.getLogger(Html5RendererUtils.class.getName());
+
/**
* Renders the pass through attributes of the component. Value of the JSF properties will be written with the
* matching Html attribute name.
@@ -149,12 +151,80 @@
String eventName = passThroughClientBehaviors.get(property);
String htmlAttrName = HTML_EVENT_ATTR_PREFIX + eventName;
- org.apache.myfaces.shared_html5.renderkit.html.HtmlRendererUtils.renderBehaviorizedAttribute(facesContext,
+ renderBehaviorizedAttribute(facesContext,
facesContext.getResponseWriter(), property, uiComponent, eventName, clientBehaviors, htmlAttrName);
}
}
+ public static boolean renderBehaviorizedOnchangeEventHandler(
+ FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+ Map<String, List<ClientBehavior>> clientBehaviors) throws IOException {
+ boolean hasChange = Html5RendererUtils.hasClientBehavior(ClientBehaviorEvents.CHANGE_EVENT, clientBehaviors, facesContext);
+ boolean hasValueChange = Html5RendererUtils.hasClientBehavior(ClientBehaviorEvents.VALUECHANGE_EVENT, clientBehaviors, facesContext);
+
+ if (hasChange && hasValueChange) {
+ String chain = Html5RendererUtils.buildBehaviorChain(facesContext,
+ uiComponent, ClientBehaviorEvents.CHANGE_EVENT, null, ClientBehaviorEvents.VALUECHANGE_EVENT, null, clientBehaviors,
+ (String) uiComponent.getAttributes().get(JsfProperties.ONCHANGE_PROP), null);
+
+ return Html5RendererUtils.renderHTMLAttribute(writer, JsfProperties.ONCHANGE_PROP, JsfProperties.ONCHANGE_PROP, chain);
+ } else if (hasChange) {
+ return Html5RendererUtils.renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONCHANGE_PROP, uiComponent,
+ ClientBehaviorEvents.CHANGE_EVENT, clientBehaviors, JsfProperties.ONCHANGE_PROP);
+ } else if (hasValueChange) {
+ return Html5RendererUtils.renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONCHANGE_PROP, uiComponent,
+ ClientBehaviorEvents.VALUECHANGE_EVENT, clientBehaviors, JsfProperties.ONCHANGE_PROP);
+ } else {
+ return Html5RendererUtils.renderHTMLAttribute(writer, JsfProperties.ONCHANGE_PROP, JsfProperties.ONCHANGE_PROP, uiComponent.getAttributes().get(JsfProperties.ONCHANGE_PROP));
+ }
+ }
+
+ public static void renderBehaviorizedEventHandlers(
+ FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+ Map<String, List<ClientBehavior>> clientBehaviors) throws IOException {
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONCLICK_PROP, uiComponent,
+ ClientBehaviorEvents.CLICK_EVENT, clientBehaviors, JsfProperties.ONCLICK_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONDBLCLICK_PROP, uiComponent,
+ ClientBehaviorEvents.DBLCLICK_EVENT, clientBehaviors, JsfProperties.ONDBLCLICK_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONMOUSEDOWN_PROP, uiComponent,
+ ClientBehaviorEvents.MOUSEDOWN_EVENT, clientBehaviors, JsfProperties.ONMOUSEDOWN_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONMOUSEUP_PROP, uiComponent,
+ ClientBehaviorEvents.MOUSEUP_EVENT, clientBehaviors, JsfProperties.ONMOUSEUP_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONMOUSEOVER_PROP, uiComponent,
+ ClientBehaviorEvents.MOUSEOVER_EVENT, clientBehaviors, JsfProperties.ONMOUSEOVER_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONMOUSEMOVE_PROP, uiComponent,
+ ClientBehaviorEvents.MOUSEMOVE_EVENT, clientBehaviors, JsfProperties.ONMOUSEMOVE_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONMOUSEOUT_PROP, uiComponent,
+ ClientBehaviorEvents.MOUSEOUT_EVENT, clientBehaviors, JsfProperties.ONMOUSEOUT_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONKEYPRESS_PROP, uiComponent,
+ ClientBehaviorEvents.KEYPRESS_EVENT, clientBehaviors, JsfProperties.ONKEYPRESS_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONKEYDOWN_PROP, uiComponent,
+ ClientBehaviorEvents.KEYDOWN_EVENT, clientBehaviors, JsfProperties.ONKEYDOWN_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONKEYUP_PROP, uiComponent,
+ ClientBehaviorEvents.KEYUP_EVENT, clientBehaviors, JsfProperties.ONKEYUP_PROP);
+ }
+
+ public static void renderBehaviorizedFieldEventHandlersWithoutOnchange(
+ FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent,
+ Map<String, List<ClientBehavior>> clientBehaviors) throws IOException {
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONFOCUS_PROP, uiComponent,
+ ClientBehaviorEvents.FOCUS_EVENT, clientBehaviors, JsfProperties.ONFOCUS_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONBLUR_PROP, uiComponent,
+ ClientBehaviorEvents.BLUR_EVENT, clientBehaviors, JsfProperties.ONBLUR_PROP);
+ renderBehaviorizedAttribute(facesContext, writer, JsfProperties.ONSELECT_PROP, uiComponent,
+ ClientBehaviorEvents.SELECT_EVENT, clientBehaviors, JsfProperties.ONSELECT_PROP);
+ }
+
+ public static boolean hasClientBehavior(String eventName,
+ Map<String, List<ClientBehavior>> behaviors,
+ FacesContext facesContext) {
+ if (behaviors == null) {
+ return false;
+ }
+ return (behaviors.get(eventName) != null);
+ }
+
/**
* Resolves string values from comma separated strings, string arrays or string collections.
*
@@ -239,19 +309,6 @@
}
/**
- * Finds the converter of the component in a safe way.
- *
- * @return null if no converter found or an exception occured inside
- */
- public static Converter findUIOutputConverterFailSafe(FacesContext facesContext, UIComponent component)
- {
- if(!(component instanceof UIOutput))
- return null;
-
- return HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, component);
- }
-
- /**
* Escapes the given string for use as a CSS selector.
* @return Escaped selector
*/
@@ -281,4 +338,532 @@
return str.replace(":", "_");
}
+
+ /**
+ * @since 4.0.0
+ * @param facesContext
+ * @param component
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static void decodeClientBehaviors(FacesContext facesContext,
+ UIComponent component)
+ {
+ if (component instanceof ClientBehaviorHolder)
+ {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+
+ Map<String,List<ClientBehavior>> clientBehaviors =
+ clientBehaviorHolder.getClientBehaviors();
+
+ if (clientBehaviors != null && !clientBehaviors.isEmpty())
+ {
+ Map<String,String> paramMap = facesContext.getExternalContext().
+ getRequestParameterMap();
+
+ String behaviorEventName = paramMap.get("javax.faces.behavior.event");
+
+ if (behaviorEventName != null)
+ {
+ List<ClientBehavior> clientBehaviorList = clientBehaviors.get(behaviorEventName);
+
+ if (clientBehaviorList != null && !clientBehaviorList.isEmpty())
+ {
+ String clientId = paramMap.get("javax.faces.source");
+
+ if (component.getClientId().equals(clientId))
+ {
+ for (ClientBehavior clientBehavior : clientBehaviorList)
+ {
+ clientBehavior.decode(facesContext, component);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Render an attribute taking into account the passed event and
+ * the component property. The event will be rendered on the selected
+ * htmlAttrName
+ *
+ * @param facesContext
+ * @param writer
+ * @param component
+ * @param clientBehaviors
+ * @param eventName
+ * @param componentProperty
+ * @param htmlAttrName
+ * @return
+ * @throws IOException
+ * @since 4.0.1
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static boolean renderBehaviorizedAttribute(
+ FacesContext facesContext, ResponseWriter writer,
+ String componentProperty, UIComponent component,
+ String eventName, Map<String, List<ClientBehavior>> clientBehaviors,
+ String htmlAttrName) throws IOException {
+ return renderBehaviorizedAttribute(facesContext, writer,
+ componentProperty, component,
+ eventName, null, clientBehaviors,
+ htmlAttrName, (String) component.getAttributes().get(componentProperty));
+ }
+
+ /**
+ * Render an attribute taking into account the passed event,
+ * the component property and the passed attribute value for the component
+ * property. The event will be rendered on the selected htmlAttrName.
+ *
+ * @param facesContext
+ * @param writer
+ * @param componentProperty
+ * @param component
+ * @param eventName
+ * @param clientBehaviors
+ * @param htmlAttrName
+ * @param attributeValue
+ * @return
+ * @throws IOException
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static boolean renderBehaviorizedAttribute(
+ FacesContext facesContext, ResponseWriter writer,
+ String componentProperty, UIComponent component,
+ String eventName, Collection<ClientBehaviorContext.Parameter> eventParameters, Map<String, List<ClientBehavior>> clientBehaviors,
+ String htmlAttrName, String attributeValue) throws IOException {
+ List<ClientBehavior> cbl = (clientBehaviors != null) ? clientBehaviors.get(eventName) : null;
+
+ if (cbl == null || cbl.size() == 0) {
+ return renderHTMLAttribute(writer, componentProperty, htmlAttrName, attributeValue);
+ }
+
+ if (cbl.size() > 1 || (cbl.size() == 1 && attributeValue != null)) {
+ return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
+ buildBehaviorChain(facesContext,
+ component, eventName, eventParameters, clientBehaviors,
+ attributeValue, StringUtils.EMPTY));
+ } else {
+ //Only 1 behavior and attrValue == null, so just render it directly
+ return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
+ cbl.get(0).getScript(
+ ClientBehaviorContext
+ .createClientBehaviorContext(facesContext, component,
+ eventName, component.getClientId(facesContext),
+ eventParameters)));
+ }
+ }
+
+ /**
+ * @param facesContext
+ * @param uiComponent
+ * @param clientBehaviors
+ * @param eventName
+ * @param userEventCode
+ * @param serverEventCode
+ * @param params
+ * @return
+ * @since 4.0.0
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ //modified
+ public static String buildBehaviorChain(FacesContext facesContext,
+ UIComponent uiComponent,
+ String eventName, Collection<ClientBehaviorContext.Parameter> params,
+ Map<String, List<ClientBehavior>> clientBehaviors,
+ String userEventCode, String serverEventCode) {
+ ExternalContext externalContext = facesContext.getExternalContext();
+ List<String> finalParams = new ArrayList<String>(3);
+ if(StringUtils.isNotBlank(userEventCode)){
+ // escape every ' in the user event code since it will
+ // be a string attribute of jsf.util.chain
+ finalParams.add('\'' + escapeJavaScriptForChain(userEventCode) + '\'');
+ }
+
+ ScriptContext behaviorCode = new ScriptContext();
+ ScriptContext retVal = new ScriptContext();
+
+ getClientBehaviorScript(facesContext, uiComponent, eventName, clientBehaviors,
+ behaviorCode, params);
+ if (behaviorCode!=null && StringUtils.isNotBlank(behaviorCode.toString())) {
+ finalParams.add(behaviorCode.toString());
+ }
+ if (StringUtils.isNotBlank(serverEventCode)) {
+ finalParams.add('\'' + escapeJavaScriptForChain(serverEventCode) + '\'');
+ }
+ Iterator<String> it = finalParams.iterator();
+
+ // It's possible that there are no behaviors to render. For example, if we have
+ // <f:ajax disabled="true" /> as the only behavior.
+
+ if (it.hasNext()) {
+ //according to the spec jsf.util.chain has to be used to build up the behavior and scripts
+ retVal.append("jsf.util.chain(document.getElementById('"
+ + uiComponent.getClientId(facesContext) + "'), event,");
+ while (it.hasNext()) {
+ retVal.append(it.next());
+ if (it.hasNext()) {
+ retVal.append(", ");
+ }
+ }
+ retVal.append(");");
+ }
+
+ return retVal.toString();
+ }
+
+ public static String buildBehaviorChain(FacesContext facesContext,
+ UIComponent uiComponent,
+ String eventName1, Collection<ClientBehaviorContext.Parameter> params,
+ String eventName2, Collection<ClientBehaviorContext.Parameter> params2,
+ Map<String, List<ClientBehavior>> clientBehaviors,
+ String userEventCode,
+ String serverEventCode) {
+
+ List<String> finalParams = new ArrayList<String>(3);
+ if (StringUtils.isNotBlank(userEventCode)) {
+ finalParams.add('\'' + escapeJavaScriptForChain(userEventCode) + '\'');
+ }
+
+ ScriptContext behaviorCode = new ScriptContext();
+ ScriptContext retVal = new ScriptContext();
+
+ boolean submitting1 = getClientBehaviorScript(facesContext, uiComponent, eventName1, clientBehaviors,
+ behaviorCode, params);
+ boolean submitting2 = getClientBehaviorScript(facesContext, uiComponent, eventName2, clientBehaviors,
+ behaviorCode, params2);
+
+ // ClientBehaviors for both events have to be checked for the Submitting hint
+ boolean submitting = submitting1 || submitting2;
+
+ if (StringUtils.isNotBlank(behaviorCode.toString())) {
+ finalParams.add(behaviorCode.toString());
+ }
+ if (StringUtils.isNotBlank(serverEventCode)) {
+ finalParams.add('\'' + escapeJavaScriptForChain(serverEventCode) + '\'');
+ }
+ Iterator<String> it = finalParams.iterator();
+
+ // It's possible that there are no behaviors to render. For example, if we have
+ // <f:ajax disabled="true" /> as the only behavior.
+
+ if (it.hasNext()) {
+ if (!submitting) {
+ retVal.append("return ");
+ }
+ //according to the spec jsf.util.chain has to be used to build up the behavior and scripts
+ retVal.append("jsf.util.chain(document.getElementById('"
+ + uiComponent.getClientId(facesContext) + "'), event,");
+ while (it.hasNext()) {
+ retVal.append(it.next());
+ if (it.hasNext()) {
+ retVal.append(", ");
+ }
+ }
+ retVal.append(");");
+ if (submitting) {
+ retVal.append(" return false;");
+ }
+ }
+
+ return retVal.toString();
+
+ }
+
+ /**
+ * builds the chained behavior script which then can be reused
+ * in following order by the other script building parts
+ * <p/>
+ * user defined event handling script
+ * behavior script
+ * renderer default script
+ *
+ * @param eventName event name ("onclick" etc...)
+ * @param uiComponent the component which has the attachement (or should have)
+ * @param facesContext the facesContext
+ * @param params params map of params which have to be dragged into the request
+ * @return a string representation of the javascripts for the attached event behavior, an empty string if none is present
+ * @since 4.0.0
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ //modified
+ private static boolean getClientBehaviorScript(FacesContext facesContext,
+ UIComponent uiComponent, String eventName,
+ Map<String, List<ClientBehavior>> clientBehaviors,
+ ScriptContext target, Collection<ClientBehaviorContext.Parameter> params) {
+ if (!(uiComponent instanceof ClientBehaviorHolder)) {
+ target.append(StringUtils.EMPTY);
+ return false;
+ }
+
+ ExternalContext externalContext = facesContext.getExternalContext();
+
+ boolean renderClientBehavior = MapUtils.isNotEmpty(clientBehaviors);
+ if (!renderClientBehavior) {
+ target.append(StringUtils.EMPTY);
+ return false;
+ }
+
+ List<ClientBehavior> attachedEventBehaviors = clientBehaviors
+ .get(eventName);
+ if (attachedEventBehaviors == null
+ || attachedEventBehaviors.size() == 0) {
+ target.append(StringUtils.EMPTY);
+ return false;
+ }
+
+ ClientBehaviorContext context = ClientBehaviorContext
+ .createClientBehaviorContext(facesContext, uiComponent,
+ eventName, uiComponent.getClientId(facesContext),
+ params);
+
+
+ boolean submitting = false;
+ Iterator<ClientBehavior> clientIterator = attachedEventBehaviors
+ .iterator();
+ while (clientIterator.hasNext()) {
+ ClientBehavior clientBehavior = clientIterator.next();
+ String script = clientBehavior.getScript(context);
+
+ // The script _can_ be null, and in fact is for <f:ajax disabled="true" />
+
+ if (script != null) {
+ //either strings or functions, but I assume string is more appropriate since it allows access to the
+ //origin as this!
+ target.append("'" + escapeJavaScriptForChain(script) + "'");
+ if (clientIterator.hasNext()) {
+ target.append(", ");
+ }
+ }
+ if (!submitting) {
+ submitting = clientBehavior.getHints().contains(ClientBehaviorHint.SUBMITTING);
+ }
+ }
+ return submitting;
+ }
+
+ /**
+ * This function correctly escapes the given JavaScript code
+ * for the use in the jsf.util.chain() JavaScript function.
+ * It also handles double-escaping correclty.
+ *
+ * @param javaScript
+ * @return
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static String escapeJavaScriptForChain(String javaScript)
+ {
+ // first replace \' with \\'
+ //String escaped = StringUtils.replace(javaScript, "\\'", "\\\\'");
+
+ // then replace ' with \'
+ // (this will replace every \' in the original to \\\')
+ //escaped = StringUtils.replace(escaped, '\'', "\\'");
+
+ //return escaped;
+
+ StringBuffer out = null;
+ for (int pos = 0; pos < javaScript.length(); pos++)
+ {
+ char c = javaScript.charAt(pos);
+
+ if (c == '\\' || c == '\'')
+ {
+ if (out == null)
+ {
+ out = new StringBuffer(javaScript.length() + 8);
+ if (pos > 0)
+ {
+ out.append(javaScript, 0, pos);
+ }
+ }
+ out.append('\\');
+ }
+ if (out != null)
+ {
+ out.append(c);
+ }
+ }
+
+ if (out == null)
+ {
+ return javaScript;
+ }
+ else
+ {
+ return out.toString();
+ }
+ }
+
+ /**
+ * Utility to set the submitted value of the provided component from the
+ * data in the current request object.
+ * <p/>
+ * Param component is required to be an EditableValueHolder. On return
+ * from this method, the component's submittedValue property will be
+ * set if the submitted form contained that component.
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static void decodeUIInput(FacesContext facesContext,
+ UIComponent component) {
+ if (!(component instanceof EditableValueHolder)) {
+ throw new IllegalArgumentException("Component "
+ + component.getClientId(facesContext)
+ + " is not an EditableValueHolder");
+ }
+ Map paramMap = facesContext.getExternalContext()
+ .getRequestParameterMap();
+ String clientId = component.getClientId(facesContext);
+
+ if (isDisabledOrReadOnly(component))
+ return;
+
+ if (paramMap.containsKey(clientId)) {
+ ((EditableValueHolder) component).setSubmittedValue(paramMap
+ .get(clientId));
+ } else {
+ log.warning(NON_SUBMITTED_VALUE_WARNING +
+ " Component : " +
+ ComponentUtils.getPathToComponent(component));
+ }
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static boolean isDisabled(UIComponent component) {
+ return isTrue(component.getAttributes().get("disabled"));
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static boolean isReadOnly(UIComponent component) {
+ return isTrue(component.getAttributes().get("readonly"));
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ private static boolean isTrue(Object obj) {
+ if (obj instanceof String) {
+ return new Boolean((String) obj);
+ }
+
+ if (!(obj instanceof Boolean))
+ return false;
+
+ return ((Boolean) obj).booleanValue();
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ //modified
+ public static boolean isDisabledOrReadOnly(UIComponent component) {
+ return isDisabled(component) ||
+ isReadOnly(component);
+ }
+
+ /**
+ * The ScriptContext offers methods and fields
+ * to help with rendering out a script and keeping a
+ * proper formatting.
+ */
+ //copied from org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
+ public static class ScriptContext {
+ private long currentIndentationLevel;
+ private StringBuffer buffer = new StringBuffer();
+ private boolean prettyPrint = false;
+ /**
+ * automatic formatting will render
+ * new-lines and indents if blocks are opened
+ * and closed - attention: you need to append
+ * opening and closing brackets of blocks separately in this case!
+ */
+ private boolean automaticFormatting = true;
+
+ public ScriptContext() {
+
+ }
+
+ public ScriptContext(boolean prettyPrint) {
+ this.prettyPrint = prettyPrint;
+ }
+
+ public ScriptContext(StringBuffer buf, boolean prettyPrint) {
+ this.prettyPrint = prettyPrint;
+ this.buffer = buf;
+ }
+
+ public void increaseIndent() {
+ currentIndentationLevel++;
+ }
+
+ public void decreaseIndent() {
+ currentIndentationLevel--;
+
+ if (currentIndentationLevel < 0)
+ currentIndentationLevel = 0;
+ }
+
+ public void prettyLine() {
+ if (prettyPrint) {
+ append(LINE_SEPARATOR);
+
+ for (int i = 0; i < getCurrentIndentationLevel(); i++)
+ append(TABULATOR);
+ }
+ }
+
+ public void prettyLineIncreaseIndent() {
+ increaseIndent();
+ prettyLine();
+ }
+
+ public void prettyLineDecreaseIndent() {
+ decreaseIndent();
+ prettyLine();
+ }
+
+ public long getCurrentIndentationLevel() {
+ return currentIndentationLevel;
+ }
+
+ public void setCurrentIndentationLevel(long currentIndentationLevel) {
+ this.currentIndentationLevel = currentIndentationLevel;
+ }
+
+ public ScriptContext append(String str) {
+
+ if (automaticFormatting && str.length() == 1) {
+ boolean openBlock = str.equals("{");
+ boolean closeBlock = str.equals("}");
+
+ if (openBlock) {
+ prettyLine();
+ } else if (closeBlock) {
+ prettyLineDecreaseIndent();
+ }
+
+ buffer.append(str);
+
+ if (openBlock) {
+ prettyLineIncreaseIndent();
+ } else if (closeBlock) {
+ prettyLine();
+ }
+ } else {
+ buffer.append(str);
+ }
+ return this;
+ }
+
+ public ScriptContext append(char c) {
+ buffer.append(c);
+ return this;
+ }
+
+ public ScriptContext append(int i) {
+ buffer.append(i);
+ return this;
+ }
+
+ public String toString() {
+ return buffer.toString();
+ }
+ }
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/JsfProperties.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/JsfProperties.java
index 40194b8..ab26e87 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/JsfProperties.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/JsfProperties.java
@@ -40,8 +40,12 @@
String SRC_PROP = "src";
String WIDTH_PROP = "width";
String HEIGHT_PROP = "height";
+ String ALIGN_PROP = "align";
+ String ALT_PROP = "alt";
+ String SIZE_PROP = "size";
String VALUE_PROP = "value";
+ String VAR_PROP = "var";
// new Html5 common props
String HIDDEN_PROP = "hidden";
@@ -111,10 +115,20 @@
String MAXLENGTH_PROP = "maxlength";
String READONLY_PROP = "readonly";
String STEP_PROP = "step";
+ String ONCHANGE_PROP = "onchange";
+ String ONSELECT_PROP = "onselect";
// input email props
String MULTIPLE_PROP = "multiple";
+ //textarea props
+ String COLS_PROP = "cols";
+ String ROWS_PROP = "rows";
+ String WRAP_PROP = "wrap";
+
+ // Input_Secret Attributes
+ String REDISPLAY_PROP = "redisplay";
+
// possible types for hx:inputText
String INPUTTEXT_TYPE_PASSWORD = "password";
String INPUTTEXT_TYPE_TEXTAREA = "textarea";
@@ -139,4 +153,14 @@
String HIGH_PROP = "high";
String ONANIMATIONEND_PROP = "onanimationEnd";
+
+
+ // UISelectItem(s) attributes
+ String ITEM_DISABLED_PROP = "itemDisabled";
+ String ITEM_DESCRIPTION_PROP = "itemDescription";
+ String ITEM_LABEL_PROP = "itemLabel";
+ String ITEM_VALUE_PROP = "itemValue";
+ String ITEM_LABEL_ESCAPED_PROP = "itemLabelEscaped";
+ String NO_SELECTION_VALUE_PROP = "noSelectionValue";
+
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributeGroups.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributeGroups.java
index f1e4b0d..364e0bc 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributeGroups.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributeGroups.java
@@ -42,11 +42,27 @@
.attr(ACCESSKEY_PROP)
.attr(TABINDEX_PROP)
.unmodifiable();
-
+
Map<String, String> DND_PROPS = map(1)
.attr(DRAGGABLE_PROP)
.unmodifiable();
-
+
+ Map<String, String> COMMON_INPUT_PROPS = map(13)
+ .attr(ALIGN_PROP)
+ .attr(ALT_PROP)
+ .attr(MAXLENGTH_PROP)
+ .attr(READONLY_PROP)
+ .attr(SIZE_PROP)
+ .attr(STYLE_PROP, STYLE_ATTR)
+ .attr(STYLECLASS_PROP, CLASS_ATTR)
+ .attr(DIR_PROP)
+ .attr(LANG_PROP)
+ .attr(TITLE_PROP)
+ .attr(ACCESSKEY_PROP)
+ .attr(TABINDEX_PROP)
+ .attr(DISABLED_ATTR)
+ .unmodifiable();
+
Map<String, String> HTML5_INPUT_PROPS = map(2)
.attr(DATALIST_PROP, LIST_ATTR)
.attr(AUTOFOCUS_PROP)
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributes.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributes.java
index 3eab5c5..a859531 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributes.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/PassThroughAttributes.java
@@ -21,7 +21,6 @@
import static org.apache.myfaces.html5.renderkit.util.AttributeMap.map;
import static org.apache.myfaces.html5.renderkit.util.HTML5.*;
import static org.apache.myfaces.html5.renderkit.util.JsfProperties.*;
-import org.apache.myfaces.html5.renderkit.util.PassThroughAttributeGroups;
import java.util.Map;
@@ -49,6 +48,10 @@
.attr(HEIGHT_PROP)
.unmodifiable();
+ Map<String, String> BASE_INPUT = map(13)
+ .attrs(PassThroughAttributeGroups.COMMON_INPUT_PROPS)
+ .unmodifiable();
+
Map<String, String> INPUT_COLOR = map(4)
.attrs(PassThroughAttributeGroups.HTML5_GLOBAL_PROPS)
.attrs(PassThroughAttributeGroups.HTML5_INPUT_PROPS)
@@ -72,7 +75,9 @@
.attrs(PassThroughAttributeGroups.HTML5_GLOBAL_PROPS)
.attr(AUTOFOCUS_PROP)
.attr(REQUIRED_PROP)
- .attr(MAXLENGTH_PROP)
+ .attr(COLS_PROP)
+ .attr(ROWS_PROP)
+ .attr(WRAP_PROP)
.unmodifiable();
Map<String, String> INPUT_EMAIL = map(7)
@@ -134,5 +139,5 @@
.attrs(PassThroughAttributeGroups.HTML5_GLOBAL_PROPS)
.attrs(PassThroughAttributeGroups.HTML_GLOBAL_PROPS)
.unmodifiable();
-
+
}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/RendererUtils.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/RendererUtils.java
new file mode 100644
index 0000000..a96fc48
--- /dev/null
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/RendererUtils.java
@@ -0,0 +1,308 @@
+/*
+ * 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.util;
+
+import org.apache.myfaces.html5.component.util.ComponentUtils;
+
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIOutput;
+import javax.faces.component.ValueHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.el.PropertyNotFoundException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Ali Ok
+ */
+public class RendererUtils {
+
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static void checkParamValidity(FacesContext facesContext, UIComponent uiComponent, Class compClass)
+ {
+ if(facesContext == null)
+ throw new NullPointerException("facesContext may not be null");
+ if(uiComponent == null)
+ throw new NullPointerException("uiComponent may not be null");
+
+ //if (compClass != null && !(compClass.isAssignableFrom(uiComponent.getClass())))
+ // why isAssignableFrom with additional getClass method call if isInstance does the same?
+ if (compClass != null && !(compClass.isInstance(uiComponent)))
+ {
+ throw new IllegalArgumentException("uiComponent : " + ComponentUtils.getPathToComponent(uiComponent)+
+ " is not instance of "+compClass.getName()+" as it should be");
+ }
+ }
+
+ /**
+ * Convenient utility method that returns the currently given value as String,
+ * using the given converter.
+ * Especially usefull for dealing with primitive types.
+ */
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static String getConvertedStringValue(FacesContext context,
+ UIComponent component, Converter converter, Object value) {
+ if (converter == null) {
+ if (value == null) {
+ return "";
+ } else if (value instanceof String) {
+ return (String) value;
+ } else {
+ return value.toString();
+ }
+ }
+
+ return converter.getAsString(context, component, value);
+ }
+
+ /**
+ * Find the proper Converter for the given UIOutput component.
+ * @return the Converter or null if no Converter specified or needed
+ * @throws javax.faces.FacesException if the Converter could not be created
+ */
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static Converter findUIOutputConverter(FacesContext facesContext,
+ UIOutput component)
+ throws FacesException
+ {
+ // Attention!
+ // This code is duplicated in jsfapi component package.
+ // If you change something here please do the same in the other class!
+
+ Converter converter = component.getConverter();
+ if (converter != null)
+ return converter;
+
+ //Try to find out by value expression
+ ValueExpression expression = component.getValueExpression("value");
+ if (expression == null)
+ return null;
+
+ Class valueType = expression.getType(facesContext.getELContext());
+ if (valueType == null)
+ return null;
+
+ if (Object.class.equals(valueType))
+ return null; //There is no converter for Object class
+
+ try
+ {
+ return facesContext.getApplication().createConverter(valueType);
+ }
+ catch (FacesException e)
+ {
+ log(facesContext, "No Converter for type " + valueType.getName()
+ + " found", e);
+ return null;
+ }
+ }
+
+ /**
+ * Finds the converter of the component in a safe way.
+ *
+ * @return null if no converter found or an exception occured inside
+ */
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static Converter findUIOutputConverterFailSafe(FacesContext facesContext, UIComponent uiComponent) {
+ Converter converter;
+ try {
+ converter = RendererUtils.findUIOutputConverter(facesContext,
+ (UIOutput) uiComponent);
+ } catch (FacesException e) {
+ log.log(Level.SEVERE, "Error finding Converter for component with id "
+ + uiComponent.getClientId(facesContext), e);
+ converter = null;
+ }
+ return converter;
+ }
+
+ /**
+ * See JSF Spec. 8.5 Table 8-1
+ * @param value
+ * @return boolean
+ */
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static boolean isDefaultAttributeValue(Object value)
+ {
+ if (value == null)
+ {
+ return true;
+ }
+ else if (value instanceof Boolean)
+ {
+ return !((Boolean) value).booleanValue();
+ }
+ else if (value instanceof Number)
+ {
+ if (value instanceof Integer)
+ {
+ return ((Number)value).intValue() == Integer.MIN_VALUE;
+ }
+ else if (value instanceof Double)
+ {
+ return ((Number)value).doubleValue() == Double.MIN_VALUE;
+ }
+ else if (value instanceof Long)
+ {
+ return ((Number)value).longValue() == Long.MIN_VALUE;
+ }
+ else if (value instanceof Byte)
+ {
+ return ((Number)value).byteValue() == Byte.MIN_VALUE;
+ }
+ else if (value instanceof Float)
+ {
+ return ((Number)value).floatValue() == Float.MIN_VALUE;
+ }
+ else if (value instanceof Short)
+ {
+ return ((Number)value).shortValue() == Short.MIN_VALUE;
+ }
+ }
+ return false;
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit._SharedRendererUtils
+ private static final Logger log = Logger.getLogger(RendererUtils.class.getName());
+ private static void log(FacesContext context, String msg, Exception e)
+ {
+ log.log(Level.SEVERE, msg, e);
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static String getStringValue(FacesContext facesContext,
+ UIComponent component)
+ {
+ try
+ {
+ if (!(component instanceof ValueHolder))
+ {
+ throw new IllegalArgumentException("Component : " + ComponentUtils.getPathToComponent(component)+"is not a ValueHolder");
+ }
+
+ if (component instanceof EditableValueHolder)
+ {
+ Object submittedValue = ((EditableValueHolder)component).getSubmittedValue();
+ if (submittedValue != null)
+ {
+ if (log.isLoggable(Level.FINE)) log.fine("returning 1 '" + submittedValue + "'");
+ return submittedValue.toString();
+ }
+ }
+
+ Object value;
+
+ if(component instanceof EditableValueHolder) {
+
+ EditableValueHolder holder = (EditableValueHolder) component;
+
+ if(holder.isLocalValueSet()) {
+ value = holder.getLocalValue();
+ } else {
+ value = getValue(component);
+ }
+ }
+ else {
+ value = getValue(component);
+ }
+
+ Converter converter = ((ValueHolder)component).getConverter();
+ if (converter == null && value != null)
+ {
+
+ try
+ {
+ converter = facesContext.getApplication().createConverter(value.getClass());
+ if (log.isLoggable(Level.FINE)) log.fine("the created converter is " + converter);
+ }
+ catch (FacesException e)
+ {
+ log.log(Level.SEVERE, "No converter for class " + value.getClass().getName() + " found (component id=" + component.getId() + ").", e);
+ // converter stays null
+ }
+ }
+
+ if (converter == null)
+ {
+ if (value == null)
+ {
+ if (log.isLoggable(Level.FINE)) log.fine("returning an empty string");
+ return "";
+ }
+
+ if (log.isLoggable(Level.FINE)) log.fine("returning an .toString");
+ return value.toString();
+
+ }
+
+ if (log.isLoggable(Level.FINE)) log.fine("returning converter get as string " + converter);
+ return converter.getAsString(facesContext, component, value);
+
+ }
+ catch(PropertyNotFoundException ex)
+ {
+ log.log(Level.SEVERE, "Property not found - called by component : "+ComponentUtils.getPathToComponent(component),ex);
+
+ throw ex;
+ }
+ }
+
+ private static Object getValue(UIComponent component) {
+ Object value;
+ try
+ {
+ value = ((ValueHolder) component).getValue();
+ }
+ catch(Exception ex)
+ {
+ throw new FacesException("Could not retrieve value of component with path : "+
+ ComponentUtils.getPathToComponent(component),ex);
+ }
+ return value;
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.RendererUtils
+ public static Object getConvertedUIOutputValue(FacesContext facesContext, UIOutput output, Object submittedValue)
+ throws ConverterException
+ {
+ if (submittedValue != null && !(submittedValue instanceof String))
+ {
+ submittedValue = submittedValue.toString();
+ }
+
+ Converter converter;
+ try
+ {
+ converter = findUIOutputConverter(facesContext, output);
+ }
+ catch (FacesException e)
+ {
+ throw new ConverterException(e);
+ }
+
+ return converter == null ? submittedValue : converter
+ .getAsObject(facesContext, output, (String) submittedValue);
+ }
+}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ResourceUtils.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ResourceUtils.java
new file mode 100644
index 0000000..2fc817f
--- /dev/null
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/ResourceUtils.java
@@ -0,0 +1,106 @@
+/*
+ * 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.util;
+
+import javax.faces.application.Resource;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResourceUtils {
+
+ private final static String RENDERED_JSF_JS = "org.apache.myfaces.RENDERED_JSF_JS";
+
+ public final static String JAVAX_FACES_LIBRARY_NAME = "javax.faces";
+ public final static String JSF_JS_RESOURCE_NAME = "jsf.js";
+
+ private final static String RENDERED_SCRIPT_RESOURCES_SET = "org.apache.myfaces.RENDERED_SCRIPT_RESOURCES_SET";
+
+ //copied from org.apache.myfaces.shared.renderkit.html.util.ResourceUtils
+ //modified
+ public static void renderDefaultJsfJsInlineIfNecessary(FacesContext facesContext, ResponseWriter writer) throws IOException
+ {
+ if (facesContext.getAttributes().containsKey(RENDERED_JSF_JS))
+ {
+ return;
+ }
+
+ // Check first if we have lucky, we are using myfaces and the script has
+ // been previously rendered
+ if (isRenderedScript(facesContext, JAVAX_FACES_LIBRARY_NAME, JSF_JS_RESOURCE_NAME))
+ {
+ facesContext.getAttributes().put(RENDERED_JSF_JS, Boolean.TRUE);
+ return;
+ }
+
+ // Check if this is an ajax request. If so, we don't need to include it, because that was
+ // already done and in the worst case, jsf script was already loaded on the page.
+ if (facesContext.getPartialViewContext() != null && facesContext.getPartialViewContext().isAjaxRequest())
+ {
+ return;
+ }
+
+ //Fast shortcut, don't create component instance and do what HtmlScriptRenderer do.
+ Resource resource = facesContext.getApplication().getResourceHandler().createResource(JSF_JS_RESOURCE_NAME, JAVAX_FACES_LIBRARY_NAME);
+ markScriptAsRendered(facesContext, JAVAX_FACES_LIBRARY_NAME, JSF_JS_RESOURCE_NAME);
+ writer.startElement(HTML5.SCRIPT_ELEM, null);
+ writer.writeAttribute(HTML5.SCRIPT_TYPE_ATTR, HTML5.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+ writer.writeURIAttribute(HTML5.SRC_ATTR, resource.getRequestPath(), null);
+ writer.endElement(HTML5.SCRIPT_ELEM);
+
+ //mark as rendered
+ facesContext.getAttributes().put(RENDERED_JSF_JS, Boolean.TRUE);
+ return;
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.html.util.ResourceUtils
+ public static boolean isRenderedScript(FacesContext facesContext, String libraryName, String resourceName)
+ {
+ return getRenderedScriptResources(facesContext).containsKey(libraryName != null ? libraryName+'/'+resourceName : resourceName);
+ }
+
+ /**
+ * Return a set of already rendered resources by this renderer on the current
+ * request.
+ *
+ * @param facesContext
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ //copied from org.apache.myfaces.shared.renderkit.html.util.ResourceUtils
+ private static Map<String, Boolean> getRenderedScriptResources(FacesContext facesContext)
+ {
+ Map<String, Boolean> map = (Map<String, Boolean>) facesContext.getAttributes().get(RENDERED_SCRIPT_RESOURCES_SET);
+ if (map == null)
+ {
+ map = new HashMap<String, Boolean>();
+ facesContext.getAttributes().put(RENDERED_SCRIPT_RESOURCES_SET,map);
+ }
+ return map;
+ }
+
+ //copied from org.apache.myfaces.shared.renderkit.html.util.ResourceUtils
+ public static void markScriptAsRendered(FacesContext facesContext, String libraryName, String resourceName)
+ {
+ getRenderedScriptResources(facesContext).put(libraryName != null ? libraryName+'/'+resourceName : resourceName, Boolean.TRUE);
+ }
+}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/SelectItemsIterator.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/SelectItemsIterator.java
new file mode 100644
index 0000000..60d6655
--- /dev/null
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/renderkit/util/SelectItemsIterator.java
@@ -0,0 +1,323 @@
+/*
+ * 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.util;
+
+import org.apache.myfaces.html5.component.util.ComponentUtils;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.el.ValueExpression;
+import javax.faces.application.ProjectStage;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UISelectItem;
+import javax.faces.component.UISelectItems;
+import javax.faces.context.FacesContext;
+import javax.faces.model.SelectItem;
+
+// ATTENTION
+// This class is associated with javax.faces.component._SelectItemsIterator.
+// Changes here should also be applied to this class.
+
+/**
+ * @author Mathias Broekelmann (latest modification by $Author$)
+ * @author Jakob Korherr (jsf 2.0)
+ * @version $Revision$ $Date$
+ */
+public class SelectItemsIterator implements Iterator<SelectItem>
+{
+ private static final Logger log = Logger.getLogger(SelectItemsIterator.class.getName());
+
+ private static final String VAR_PROP = JsfProperties.VAR_PROP;
+ private static final String ITEM_VALUE_PROP = JsfProperties.ITEM_VALUE_PROP;
+ private static final String ITEM_LABEL_PROP = JsfProperties.ITEM_LABEL_PROP;
+ private static final String ITEM_DESCRIPTION_PROP = JsfProperties.ITEM_DESCRIPTION_PROP;
+ private static final String ITEM_DISABLED_PROP = JsfProperties.ITEM_DISABLED_PROP;
+ private static final String ITEM_LABEL_ESCAPED_PROP = JsfProperties.ITEM_LABEL_ESCAPED_PROP;
+ private static final String NO_SELECTION_VALUE_PROP = JsfProperties.NO_SELECTION_VALUE_PROP;
+
+ private final Iterator<UIComponent> _children;
+ private Iterator<? extends Object> _nestedItems;
+ private SelectItem _nextItem;
+ private UISelectItems _currentUISelectItems;
+ private FacesContext _facesContext;
+
+ public SelectItemsIterator(UIComponent selectItemsParent, FacesContext facesContext)
+ {
+ _children = selectItemsParent.getChildren().iterator();
+ _facesContext = facesContext;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean hasNext()
+ {
+ if (_nextItem != null)
+ {
+ return true;
+ }
+ if (_nestedItems != null)
+ {
+ if (_nestedItems.hasNext())
+ {
+ return true;
+ }
+ _nestedItems = null;
+ }
+ if (_children.hasNext())
+ {
+ UIComponent child = _children.next();
+ // When there is other components nested that does
+ // not extends from UISelectItem or UISelectItems
+ // the behavior for this iterator is just skip this
+ // element(s) until an element that extends from these
+ // classes are found. If there is no more elements
+ // that conform this condition, just return false.
+ while (!(child instanceof UISelectItem) && !(child instanceof UISelectItems))
+ {
+ // Try to skip it
+ if (_children.hasNext())
+ {
+ // Skip and do the same check
+ child = _children.next();
+ }
+ else
+ {
+ // End loop, so the final result is return false,
+ // since there are no more components to iterate.
+ return false;
+ }
+ }
+ if (child instanceof UISelectItem)
+ {
+ UISelectItem uiSelectItem = (UISelectItem) child;
+ Object item = uiSelectItem.getValue();
+ if (item == null)
+ {
+ // no value attribute --> create the SelectItem out of the other attributes
+ Object itemValue = uiSelectItem.getItemValue();
+ String label = uiSelectItem.getItemLabel();
+ String description = uiSelectItem.getItemDescription();
+ boolean disabled = uiSelectItem.isItemDisabled();
+ boolean escape = uiSelectItem.isItemEscaped();
+ boolean noSelectionOption = uiSelectItem.isNoSelectionOption();
+ if (label == null)
+ {
+ label = itemValue.toString();
+ }
+ item = new SelectItem(itemValue, label, description, disabled, escape, noSelectionOption);
+ }
+ else if (!(item instanceof SelectItem))
+ {
+ ValueExpression expression = uiSelectItem.getValueExpression("value");
+ throw new IllegalArgumentException("ValueExpression '"
+ + (expression == null ? null : expression.getExpressionString()) + "' of UISelectItem : "
+ + ComponentUtils.getPathToComponent(child) + " does not reference an Object of type SelectItem");
+ }
+ _nextItem = (SelectItem) item;
+ return true;
+ }
+ else if (child instanceof UISelectItems)
+ {
+ _currentUISelectItems = ((UISelectItems) child);
+ Object value = _currentUISelectItems.getValue();
+
+ if (value instanceof SelectItem)
+ {
+ _nextItem = (SelectItem) value;
+ return true;
+ }
+ else if (value != null && value.getClass().isArray())
+ {
+ // value is any kind of array (primitive or non-primitive)
+ // --> we have to use class Array to get the values
+ final int length = Array.getLength(value);
+ Collection<Object> items = new ArrayList<Object>(length);
+ for (int i = 0; i < length; i++)
+ {
+ items.add(Array.get(value, i));
+ }
+ _nestedItems = items.iterator();
+ return hasNext();
+ }
+ else if (value instanceof Iterable)
+ {
+ // value is Iterable --> Collection, DataModel,...
+ _nestedItems = ((Iterable<?>) value).iterator();
+ return hasNext();
+ }
+ else if (value instanceof Map)
+ {
+ Map<Object, Object> map = ((Map<Object, Object>) value);
+ Collection<SelectItem> items = new ArrayList<SelectItem>(map.size());
+ for (Map.Entry<Object, Object> entry : map.entrySet())
+ {
+ items.add(new SelectItem(entry.getValue(), entry.getKey().toString()));
+ }
+
+ _nestedItems = items.iterator();
+ return hasNext();
+ }
+ else
+ {
+ Level level = Level.FINE;
+ if (!_facesContext.isProjectStage(ProjectStage.Production))
+ {
+ level = Level.WARNING;
+ }
+
+ if (log.isLoggable(level))
+ {
+ ValueExpression expression = _currentUISelectItems.getValueExpression("value");
+ log.log(level, "ValueExpression {0} of UISelectItems with component-path {1}"
+ + " does not reference an Object of type SelectItem,"
+ + " array, Iterable or Map, but of type: {2}",
+ new Object[] {
+ (expression == null ? null : expression.getExpressionString()),
+ ComponentUtils.getPathToComponent(child),
+ (value == null ? null : value.getClass().getName())
+ });
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public SelectItem next()
+ {
+ if (!hasNext())
+ {
+ throw new NoSuchElementException();
+ }
+ if (_nextItem != null)
+ {
+ SelectItem value = _nextItem;
+ _nextItem = null;
+ return value;
+ }
+ if (_nestedItems != null)
+ {
+ Object item = _nestedItems.next();
+
+ if (!(item instanceof SelectItem))
+ {
+ // check new params of SelectItems (since 2.0): itemValue, itemLabel, itemDescription,...
+ // Note that according to the spec UISelectItems does not provide Getter and Setter
+ // methods for this values, so we have to use the attribute map
+ Map<String, Object> attributeMap = _currentUISelectItems.getAttributes();
+
+ // write the current item into the request map under the key listed in var, if available
+ boolean wroteRequestMapVarValue = false;
+ Object oldRequestMapVarValue = null;
+ final String var = (String) attributeMap.get(VAR_PROP);
+ if(var != null && !"".equals(var))
+ {
+ // save the current value of the key listed in var from the request map
+ oldRequestMapVarValue = _facesContext.getExternalContext().getRequestMap().put(var, item);
+ wroteRequestMapVarValue = true;
+ }
+
+ // check the itemValue attribute
+ Object itemValue = attributeMap.get(ITEM_VALUE_PROP);
+ if (itemValue == null)
+ {
+ // the itemValue attribute was not provided
+ // --> use the current item as the itemValue
+ itemValue = item;
+ }
+
+ // Spec: When iterating over the select items, toString()
+ // must be called on the string rendered attribute values
+ Object itemLabel = attributeMap.get(ITEM_LABEL_PROP);
+ if (itemLabel == null)
+ {
+ itemLabel = itemValue.toString();
+ }
+ else
+ {
+ itemLabel = itemLabel.toString();
+ }
+ Object itemDescription = attributeMap.get(ITEM_DESCRIPTION_PROP);
+ if (itemDescription != null)
+ {
+ itemDescription = itemDescription.toString();
+ }
+ Boolean itemDisabled = getBooleanAttribute(_currentUISelectItems, ITEM_DISABLED_PROP, false);
+ Boolean itemLabelEscaped = getBooleanAttribute(_currentUISelectItems, ITEM_LABEL_ESCAPED_PROP, true);
+ Object noSelectionValue = attributeMap.get(NO_SELECTION_VALUE_PROP);
+ item = new SelectItem(itemValue,
+ (String) itemLabel,
+ (String) itemDescription,
+ itemDisabled,
+ itemLabelEscaped,
+ itemValue.equals(noSelectionValue));
+
+ // remove the value with the key from var from the request map, if previously written
+ if(wroteRequestMapVarValue)
+ {
+ // If there was a previous value stored with the key from var in the request map, restore it
+ if (oldRequestMapVarValue != null)
+ {
+ _facesContext.getExternalContext()
+ .getRequestMap().put(var, oldRequestMapVarValue);
+ }
+ else
+ {
+ _facesContext.getExternalContext()
+ .getRequestMap().remove(var);
+ }
+ }
+ }
+ return (SelectItem) item;
+ }
+ throw new NoSuchElementException();
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ private boolean getBooleanAttribute(UIComponent component, String attrName, boolean defaultValue)
+ {
+ Object value = component.getAttributes().get(attrName);
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ else if (value instanceof Boolean)
+ {
+ return (Boolean) value;
+ }
+ else
+ {
+ // If the value is a String, parse the boolean.
+ // This makes the following code work: <tag attribute="true" />,
+ // otherwise you would have to write <tag attribute="#{true}" />.
+ return Boolean.valueOf(value.toString());
+ }
+ }
+
+}
diff --git a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/validator/DateTimeRangeValidator.java b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/validator/DateTimeRangeValidator.java
index 68406a9..788772f 100644
--- a/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/validator/DateTimeRangeValidator.java
+++ b/myfaces-html5-core/src/main/java/org/apache/myfaces/html5/validator/DateTimeRangeValidator.java
@@ -35,9 +35,9 @@
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFValidator;
import org.apache.myfaces.html5.component.input.HtmlInputDateTime;
+import org.apache.myfaces.html5.component.util.ComponentUtils;
import org.apache.myfaces.html5.renderkit.input.util.Html5DateTimeFormatUtils;
import org.apache.myfaces.html5.renderkit.util.HTML5;
-import org.apache.myfaces.shared_html5.renderkit.RendererUtils;
/**
* Validate that the date entered is within a given range. Rendered min/max attributes of hx:inputDateTime is driven by
@@ -89,7 +89,7 @@
catch (ParseException e)
{
throw new ValidatorException(new FacesMessage("Unable to resolve minimum for component "
- + RendererUtils.getPathToComponent(uiComponent) + "."), e);
+ + ComponentUtils.getPathToComponent(uiComponent) + "."), e);
}
Date resolvedMaximum = null;
@@ -100,7 +100,7 @@
catch (ParseException e)
{
throw new ValidatorException(new FacesMessage("Unable to resolve maximum for component "
- + RendererUtils.getPathToComponent(uiComponent) + "."), e);
+ + ComponentUtils.getPathToComponent(uiComponent) + "."), e);
}
if (resolvedMinimum != null && resolvedMaximum != null)
@@ -109,7 +109,7 @@
{
// not a ValidatorException since state is illegal
throw new FacesException("Minimum value is before than maximum for component "
- + RendererUtils.getPathToComponent(uiComponent) + ".");
+ + ComponentUtils.getPathToComponent(uiComponent) + ".");
}
else
{
@@ -120,7 +120,7 @@
else
throw new ValidatorException(
new FacesMessage("Submitted value is not in allowed range for component "
- + RendererUtils.getPathToComponent(uiComponent) + ". Range is "
+ + ComponentUtils.getPathToComponent(uiComponent) + ". Range is "
+ resolvedMinimum.toString() + " - " + resolvedMaximum.toString() + "."));
}
}
@@ -132,7 +132,7 @@
throw new ValidatorException(new FacesMessage(this.lessThanMinimumMessage));
else
throw new ValidatorException(new FacesMessage("Value is before minimum for component "
- + RendererUtils.getPathToComponent(uiComponent) + ". Minimum value is "
+ + ComponentUtils.getPathToComponent(uiComponent) + ". Minimum value is "
+ resolvedMinimum.toString() + "."));
}
@@ -142,7 +142,7 @@
throw new ValidatorException(new FacesMessage(this.exceedMaximumMessage));
else
throw new ValidatorException(new FacesMessage("Value is after maximum for component "
- + RendererUtils.getPathToComponent(uiComponent) + ". Maximum value is "
+ + ComponentUtils.getPathToComponent(uiComponent) + ". Maximum value is "
+ resolvedMaximum.toString() + "."));
}
}
diff --git a/pom.xml b/pom.xml
index 062e714..3d298a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -137,7 +137,6 @@
<properties>
<myfaces-core-version>2.0.1</myfaces-core-version>
- <myfaces-shared-html5-version>4.0.6-SNAPSHOT</myfaces-shared-html5-version>
</properties>
</project>
\ No newline at end of file