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  
24  import javax.faces.component.UIComponent;
25  import javax.faces.context.FacesContext;
26  import javax.faces.context.ResponseWriter;
27  
28  import org.apache.myfaces.renderkit.html.util.AddResource;
29  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
30  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
31  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
32  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
33  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
34  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
35  
36  /**
37   * @JSFRenderer
38   *   renderKitId = "HTML_BASIC" 
39   *   family = "javax.faces.Panel"
40   *   type = "org.apache.myfaces.Popup"
41   * @since 1.1.7
42   * @author Martin Marinschek (latest modification by $Author: lu4242 $)
43   * @version $Revision: 1097467 $ $Date: 2011-04-28 09:11:52 -0500 (Thu, 28 Apr 2011) $
44   */
45  public class HtmlPopupRenderer
46      extends HtmlRenderer
47  {
48      public static final String RENDERER_TYPE = "org.apache.myfaces.Popup";
49      //private static final Log log = LogFactory.getLog(HtmlListRenderer.class);
50      
51      private static final String LAYOUT_BLOCK = "block";
52      private static final String LAYOUT_DIV = "div";
53      private static final String LAYOUT_SPAN = "span";
54      private static final String LAYOUT_NONE = "none";
55  
56      public boolean getRendersChildren()
57      {
58          return true;
59      }
60  
61      public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
62      {
63      }
64  
65      public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException
66      {
67  
68      }
69  
70  
71      public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
72      {
73          RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlPopup.class);
74  
75          HtmlPopup popup = (HtmlPopup) uiComponent;
76  
77          UIComponent popupFacet = popup.getPopup();
78  
79          String popupId = writePopupScript(
80                  facesContext, popup.getClientId(facesContext),
81                  popup.getDisplayAtDistanceX(),popup.getDisplayAtDistanceY(), uiComponent);
82  
83          //writeMouseOverAndOutAttribs(popupId, popupFacet.getChildren());
84  
85          ResponseWriter writer = facesContext.getResponseWriter();
86          
87          String layout = popup.getLayout();
88          
89          if (LAYOUT_BLOCK.equals(layout) || LAYOUT_DIV.equals(layout))
90          {
91              writer.startElement(HTML.DIV_ELEM, popup);
92              writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, popupId + ".display(event);", null);
93              writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, popupId + ".hide(event);", null);
94          }
95          else if (LAYOUT_NONE.equals(layout))
96          {
97              writeMouseOverAttribs(popupId, uiComponent.getChildren(),
98                      popup.getClosePopupOnExitingElement()==null ||
99                              popup.getClosePopupOnExitingElement().booleanValue());
100         }
101         else
102         {
103             writer.startElement(HTML.SPAN_ELEM, popup);
104             writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, popupId + ".display(event);", null);
105             writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, popupId + ".hide(event);", null);
106         }
107         
108         RendererUtils.renderChildren(facesContext, uiComponent);
109         
110         if (LAYOUT_BLOCK.equals(layout) || LAYOUT_DIV.equals(layout))
111         {
112             writer.endElement(HTML.DIV_ELEM);
113         }
114         else if (LAYOUT_NONE.equals(layout))
115         {
116         }
117         else
118         {
119             writer.endElement(HTML.SPAN_ELEM);
120         }
121 
122         writer.startElement(HTML.DIV_ELEM, popup);
123         writer.writeAttribute(HTML.STYLE_ATTR,(popup.getStyle()!=null?(popup.getStyle()+
124                 (popup.getStyle().trim().endsWith(";")?"":";")):"")+
125                 "position:absolute;display:none;",null);
126         if(popup.getStyleClass()!=null)
127         {
128             writer.writeAttribute(HTML.CLASS_ATTR,popup.getStyleClass(),null);
129         }
130         writer.writeAttribute(HTML.ID_ATTR, popup.getClientId(facesContext),null);
131         writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, new String(popupId+".redisplay();"),null);
132 
133         Boolean closeExitPopup = popup.getClosePopupOnExitingPopup();
134 
135         if(closeExitPopup==null || closeExitPopup.booleanValue())
136             writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, popupId + ".hide();",null);
137         
138         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONCLICK_ATTR, HTML.ONCLICK_ATTR, popup.getOnclick());
139         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONDBLCLICK_ATTR, HTML.ONDBLCLICK_ATTR, popup.getOndblclick());
140         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONMOUSEDOWN_ATTR, HTML.ONMOUSEDOWN_ATTR, popup.getOnmousedown());
141         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONMOUSEUP_ATTR, HTML.ONMOUSEUP_ATTR, popup.getOnmouseup());
142         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONMOUSEMOVE_ATTR, HTML.ONMOUSEMOVE_ATTR, popup.getOnmousemove());
143         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONKEYPRESS_ATTR, HTML.ONKEYPRESS_ATTR, popup.getOnkeypress());
144         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONKEYDOWN_ATTR, HTML.ONKEYDOWN_ATTR, popup.getOnkeydown());
145         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONKEYUP_ATTR, HTML.ONKEYUP_ATTR, popup.getOnkeyup());
146 
147         RendererUtils.renderChild(facesContext, popupFacet);
148         writer.endElement(HTML.DIV_ELEM);
149     }
150 
151     private void writeMouseOverAttribs(String popupId, List children, boolean renderMouseOut)
152     {
153         for (int i = 0; i < children.size(); i++)
154         {
155             UIComponent uiComponent = (UIComponent) children.get(i);
156 
157             callMethod(uiComponent,"onmouseover", popupId + ".display(event);");
158 
159             if(renderMouseOut)
160                 callMethod(uiComponent,"onmouseout", popupId + ".hide(event);");
161 
162             writeMouseOverAttribs(popupId, uiComponent.getChildren(),renderMouseOut);
163         }
164     }
165 
166     private String writePopupScript(FacesContext context, String clientId,
167                                     Integer displayAtDistanceX, Integer displayAtDistanceY, UIComponent uiComponent)
168         throws IOException
169     {
170         AddResourceFactory.getInstance(context).addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlPopupRenderer.class, "JSPopup.js");
171 
172         String popupId = JavascriptUtils.getValidJavascriptName(clientId+"Popup",false);
173 
174         ResponseWriter writer = context.getResponseWriter();
175         writer.startElement(HTML.SCRIPT_ELEM, uiComponent);
176         writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);
177         writer.writeText("var "+popupId+"=new orgApacheMyfacesPopup('"+clientId+"',"+
178                 (displayAtDistanceX==null?-5:displayAtDistanceX.intValue())+","+
179                 (displayAtDistanceY==null?-5:displayAtDistanceY.intValue())+");",null);
180         writer.endElement(HTML.SCRIPT_ELEM);
181 
182         return popupId;
183     }
184 
185 
186     private void callMethod(UIComponent uiComponent, String propName, String value)
187     {
188         Object oldValue = uiComponent.getAttributes().get(propName);
189 
190         String oldValueStr = "";
191 
192         String genCommentary = "/* generated code */";
193 
194         if(oldValue != null)
195         {
196             oldValueStr = oldValue.toString().trim();
197 
198             int genCommentaryIndex;
199 
200             //check if generated code has already been added...
201             if((genCommentaryIndex=oldValueStr.indexOf(genCommentary))!=-1)
202             {
203                 oldValueStr = oldValueStr.substring(0,genCommentaryIndex);
204             }
205 
206             if(oldValueStr.length()>0 && !oldValueStr.endsWith(";"))
207                 oldValueStr +=";";
208         }
209 
210         value = oldValueStr+genCommentary+value;
211 
212         uiComponent.getAttributes().put(propName, value);
213     }
214 }