View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.custom.popup;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.Map;
24  
25  import javax.faces.application.ResourceDependency;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.behavior.ClientBehavior;
28  import javax.faces.component.behavior.ClientBehaviorHolder;
29  import javax.faces.context.FacesContext;
30  import javax.faces.context.ResponseWriter;
31  
32  import org.apache.myfaces.shared_tomahawk.renderkit.ClientBehaviorEvents;
33  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
34  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
35  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
36  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
37  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
38  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;
39  
40  /**
41   * @JSFRenderer
42   *   renderKitId = "HTML_BASIC" 
43   *   family = "javax.faces.Panel"
44   *   type = "org.apache.myfaces.Popup"
45   * @since 1.1.7
46   * @author Martin Marinschek (latest modification by $Author: lu4242 $)
47   * @version $Revision: 691856 $ $Date: 2008-09-03 21:40:30 -0500 (miƩ, 03 sep 2008) $
48   */
49  @ResourceDependency(library="oam.custom.popup",name="JSPopup.js")
50  public class HtmlPopupRenderer
51      extends HtmlRenderer
52  {
53      public static final String RENDERER_TYPE = "org.apache.myfaces.Popup";
54      //private static final Log log = LogFactory.getLog(HtmlListRenderer.class);
55      
56      private static final String LAYOUT_BLOCK = "block";
57      private static final String LAYOUT_DIV = "div";
58      private static final String LAYOUT_SPAN = "span";
59      private static final String LAYOUT_NONE = "none";
60  
61      public boolean getRendersChildren()
62      {
63          return true;
64      }
65  
66      @Override
67      public void decode(FacesContext context, UIComponent component)
68      {
69          super.decode(context, component);
70          
71          HtmlRendererUtils.decodeClientBehaviors(context, component);
72      }
73  
74      public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
75      {
76      }
77  
78      public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException
79      {
80  
81      }
82  
83  
84      public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
85      {
86          RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlPopup.class);
87  
88          HtmlPopup popup = (HtmlPopup) uiComponent;
89  
90          Map<String, List<ClientBehavior>> behaviors = null;
91          if (uiComponent instanceof ClientBehaviorHolder)
92          {
93              behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
94              if (!behaviors.isEmpty())
95              {
96                  ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
97              }
98          }
99          
100         UIComponent popupFacet = popup.getPopup();
101 
102         String popupId = writePopupScript(
103                 facesContext, popup.getClientId(facesContext),
104                 popup.getDisplayAtDistanceX(),popup.getDisplayAtDistanceY(), uiComponent);
105 
106         //writeMouseOverAndOutAttribs(popupId, popupFacet.getChildren());
107 
108         ResponseWriter writer = facesContext.getResponseWriter();
109         
110         String layout = popup.getLayout();
111         
112         if (LAYOUT_BLOCK.equals(layout) || LAYOUT_DIV.equals(layout))
113         {
114             writer.startElement(HTML.DIV_ELEM, popup);
115             writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, popupId + ".display(event);", null);
116             writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, popupId + ".hide(event);", null);
117         }
118         else if (LAYOUT_NONE.equals(layout))
119         {
120             writeMouseOverAttribs(popupId, uiComponent.getChildren(),
121                     popup.getClosePopupOnExitingElement()==null ||
122                             popup.getClosePopupOnExitingElement().booleanValue());
123         }
124         else
125         {
126             writer.startElement(HTML.SPAN_ELEM, popup);
127             writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, popupId + ".display(event);", null);
128             writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, popupId + ".hide(event);", null);
129         }
130         
131         RendererUtils.renderChildren(facesContext, uiComponent);
132         
133         if (LAYOUT_BLOCK.equals(layout) || LAYOUT_DIV.equals(layout))
134         {
135             writer.endElement(HTML.DIV_ELEM);
136         }
137         else if (LAYOUT_NONE.equals(layout))
138         {
139         }
140         else
141         {
142             writer.endElement(HTML.SPAN_ELEM);
143         }
144 
145         writer.startElement(HTML.DIV_ELEM, popup);
146         writer.writeAttribute(HTML.STYLE_ATTR,(popup.getStyle()!=null?(popup.getStyle()+
147                 (popup.getStyle().trim().endsWith(";")?"":";")):"")+
148                 "position:absolute;display:none;",null);
149         if(popup.getStyleClass()!=null)
150         {
151             writer.writeAttribute(HTML.CLASS_ATTR,popup.getStyleClass(),null);
152         }
153         writer.writeAttribute(HTML.ID_ATTR, popup.getClientId(facesContext),null);
154         if (behaviors != null && !behaviors.isEmpty())
155         {
156             HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer,
157                     HTML.ONMOUSEOVER_ATTR, popup, ClientBehaviorEvents.MOUSEOVER, null, behaviors,
158                     HTML.ONMOUSEOVER_ATTR, popup.getOnmouseover(), new String(popupId+".redisplay();"));
159             
160             Boolean closeExitPopup = popup.getClosePopupOnExitingPopup();
161 
162             if(closeExitPopup==null || closeExitPopup.booleanValue())
163             {
164                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer,
165                         HTML.ONMOUSEOUT_ATTR, popup, ClientBehaviorEvents.MOUSEOUT, null, behaviors,
166                         HTML.ONMOUSEOUT_ATTR, popup.getOnmouseover(), popupId + ".hide();");
167             }
168             else
169             {
170                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer,
171                         HTML.ONMOUSEOUT_ATTR, popup, ClientBehaviorEvents.MOUSEOUT, null, behaviors,
172                         HTML.ONMOUSEOUT_ATTR, popup.getOnmouseover(), null);
173             }
174             
175             HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnmouseoverAndOnmouseout(facesContext, writer, uiComponent, behaviors);
176         }
177         else
178         {
179             writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, new String(popupId+".redisplay();"),null);
180 
181             Boolean closeExitPopup = popup.getClosePopupOnExitingPopup();
182 
183             if(closeExitPopup==null || closeExitPopup.booleanValue())
184                 writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, popupId + ".hide();",null);
185             
186             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONCLICK_ATTR, HTML.ONCLICK_ATTR, popup.getOnclick());
187             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONDBLCLICK_ATTR, HTML.ONDBLCLICK_ATTR, popup.getOndblclick());
188             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONMOUSEDOWN_ATTR, HTML.ONMOUSEDOWN_ATTR, popup.getOnmousedown());
189             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONMOUSEUP_ATTR, HTML.ONMOUSEUP_ATTR, popup.getOnmouseup());
190             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONMOUSEMOVE_ATTR, HTML.ONMOUSEMOVE_ATTR, popup.getOnmousemove());
191             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONKEYPRESS_ATTR, HTML.ONKEYPRESS_ATTR, popup.getOnkeypress());
192             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONKEYDOWN_ATTR, HTML.ONKEYDOWN_ATTR, popup.getOnkeydown());
193             HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONKEYUP_ATTR, HTML.ONKEYUP_ATTR, popup.getOnkeyup());
194         }
195         
196         RendererUtils.renderChild(facesContext, popupFacet);
197         writer.endElement(HTML.DIV_ELEM);
198     }
199 
200     private void writeMouseOverAttribs(String popupId, List children, boolean renderMouseOut)
201     {
202         for (int i = 0; i < children.size(); i++)
203         {
204             UIComponent uiComponent = (UIComponent) children.get(i);
205 
206             callMethod(uiComponent,"onmouseover", popupId + ".display(event);");
207 
208             if(renderMouseOut)
209                 callMethod(uiComponent,"onmouseout", popupId + ".hide(event);");
210 
211             writeMouseOverAttribs(popupId, uiComponent.getChildren(),renderMouseOut);
212         }
213     }
214 
215     private String writePopupScript(FacesContext context, String clientId,
216                                     Integer displayAtDistanceX, Integer displayAtDistanceY, UIComponent uiComponent)
217         throws IOException
218     {
219         //AddResourceFactory.getInstance(context).addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlPopupRenderer.class, "JSPopup.js");
220 
221         String popupId = JavascriptUtils.getValidJavascriptName(clientId+"Popup",false);
222 
223         ResponseWriter writer = context.getResponseWriter();
224         writer.startElement(HTML.SCRIPT_ELEM, uiComponent);
225         writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);
226         writer.writeText("var "+popupId+"=new orgApacheMyfacesPopup('"+clientId+"',"+
227                 (displayAtDistanceX==null?-5:displayAtDistanceX.intValue())+","+
228                 (displayAtDistanceY==null?-5:displayAtDistanceY.intValue())+");",null);
229         writer.endElement(HTML.SCRIPT_ELEM);
230 
231         return popupId;
232     }
233 
234 
235     private void callMethod(UIComponent uiComponent, String propName, String value)
236     {
237         Object oldValue = uiComponent.getAttributes().get(propName);
238 
239         String oldValueStr = "";
240 
241         String genCommentary = "/* generated code */";
242 
243         if(oldValue != null)
244         {
245             oldValueStr = oldValue.toString().trim();
246 
247             int genCommentaryIndex;
248 
249             //check if generated code has already been added...
250             if((genCommentaryIndex=oldValueStr.indexOf(genCommentary))!=-1)
251             {
252                 oldValueStr = oldValueStr.substring(0,genCommentaryIndex);
253             }
254 
255             if(oldValueStr.length()>0 && !oldValueStr.endsWith(";"))
256                 oldValueStr +=";";
257         }
258 
259         value = oldValueStr+genCommentary+value;
260 
261         uiComponent.getAttributes().put(propName, value);
262     }
263 }